CDK でリソースの論理 ID を取得するにはどうすればいいですか? 質問する

CDK でリソースの論理 ID を取得するにはどうすればいいですか? 質問する

私はいくつか書こうとしているテスト構造の一部として定義されたセキュリティ グループ ルールを検証する CDK 構造用。

構造は次のようになります。

export interface SampleConstructProps extends StackProps {
  srcSecurityGroupId: string;
}

export class SampleConstruct extends Construct {
  securityGroup: SecurityGroup;

  constructor(scope: Construct, id: string, props: SampleConstructProps) {
    super(scope, id, props);

    // const vpc = Vpc.fromLookup(...);
    this.securityGroup = new SecurityGroup(this, "SecurityGroup", {
      vpc: vpc,
      allowAllOutbound: true,
    });

    const srcSecurityGroupId = SecurityGroup.fromSecurityGroupId(stack, "SrcSecurityGroup", props.srcSecurityGroupId);

    this.securityGroup.addIngressRule(srcSecurityGroup, Port.tcp(22));
  }
}

そして、次のようなテストを書きたいと思います。

test("Security group config is correct", () => {
  const stack = new Stack();
  const srcSecurityGroupId = "id-123";
  const testConstruct = new SampleConstruct(stack, "TestConstruct", {
    srcSecurityGroupId: srcSecurityGroupId
  });

  expect(stack).to(
    haveResource(
      "AWS::EC2::SecurityGroupIngress",
      {
        IpProtocol: "tcp",
        FromPort: 22,
        ToPort: 22,
        SourceSecurityGroupId: srcSecurityGroupId,
        GroupId: {
          "Fn::GetAtt": [testConstruct.securityGroup.logicalId, "GroupId"], // Can't do this
        },
      },
      undefined,
      true
    )
  );
});

ここでの問題は、テストが合成されたCloudFormationテンプレートに対して検証されるため、この構成によって作成されたセキュリティグループにからのアクセスを許可するルールがあることを確認するにはsrcSecurityGroup論理IDConstruct の一部として作成されたセキュリティ グループの。

これは、ここで生成された CloudFormation テンプレートで確認できます。

{
  "Type": "AWS::EC2::SecurityGroupIngress",
  "Properties": {
    "IpProtocol": "tcp",
    "FromPort": 22,
    "GroupId": {
      "Fn::GetAtt": [
        "TestConstructSecurityGroup95EF3F0F", <-- This
        "GroupId"
      ]
    },
    "SourceSecurityGroupId": "id-123",
    "ToPort": 22
  }
}

これがFn::GetAttこの問題の核心です。これらのテストは実際にはオブジェクトの比較だけを行うため、呼び出しを複製できる必要がありFn::Get、そのためには CloudFormation 論理 ID が必要です。


CDKはするを提供するいくつかの識別子あなたのために。

  • 一意の ID は非常に近いものを提供しますが、CloudFormation スタックで使用される識別子とは異なります。たとえば、securityGroup.uniqueIdは を返しますTestStackTestConstructSecurityGroup10D493A7が、CloudFormation テンプレートは を表示しますTestConstructSecurityGroup95EF3F0F。違いは、 がuniqueId論理識別子の前に Construct ID を付加し、追加されたハッシュがそれぞれ異なることです。
  • コンストラクト ID は、コンストラクトをインスタンス化するときに指定する識別子です。論理 ID の一部に使用されますが、論理 ID ではありません。また、この ID をプログラムでコンストラクトから直接取得する方法も見たことがありません。もちろん、ID をどこかで定義して再利用することはできますが、それでも論理 ID と完全に一致しない問題は解決されません。この場合、コンストラクトSecurityGroupID と合成TestConstructSecurityGroup95EF3F0Fされたテンプレートの論理 ID が異なります。

CDK リソースの論理 ID を取得する簡単な方法はありますか?

ベストアンサー1

この投稿全体を書き上げ、CDK コードを詳しく調べた後、探していた答えに偶然出会いました。より高レベルの CDK 構造から論理 ID を取得するためのより良い方法をお持ちの方がいらっしゃいましたら、ぜひご協力ください。

CDK リソースの論理 ID を取得する必要がある場合は、次の操作を実行できます。

const stack = new Stack();
const construct = new SampleConstruct(stack, "SampleConstruct");
const logicalId = stack.getLogicalId(construct.securityGroup.node.defaultChild as CfnSecurityGroup);

すでに CloudFormation リソース ( で始まるものなど) がある場合はCfn、少し簡単になります。

// Pretend construct.securityGroup is of type CfnSecurityGroup
const logicalId = stack.getLogicalId(construct.securityGroup);

おすすめ記事