jre*_*ady 10 amazon-web-services aws-cloudformation aws-cdk
我正在尝试为 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));
}
}
Run Code Online (Sandbox Code Playgroud)
我想编写一个类似于以下内容的测试。
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
)
);
});
Run Code Online (Sandbox Code Playgroud)
这里的问题是测试是针对合成的 CloudFormation 模板进行验证的,因此如果您想验证此构造创建的安全组是否具有允许从 访问的规则srcSecurityGroup,您需要作为一部分创建的安全组的逻辑 ID的构造。
您可以在此处生成的 CloudFormation 模板中看到这一点。
{
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"IpProtocol": "tcp",
"FromPort": 22,
"GroupId": {
"Fn::GetAtt": [
"TestConstructSecurityGroup95EF3F0F", <-- This
"GroupId"
]
},
"SourceSecurityGroupId": "id-123",
"ToPort": 22
}
}
Run Code Online (Sandbox Code Playgroud)
这Fn::GetAtt就是这个问题的症结所在。由于这些测试实际上只是进行对象比较,因此您需要能够复制Fn::Get调用,这需要 CloudFormation 逻辑 ID。
请注意,CDK确实为您提供了一些标识符。
securityGroup.uniqueId返回TestStackTestConstructSecurityGroup10D493A7而 CloudFormation 模板显示TestConstructSecurityGroup95EF3F0F。您可以注意到不同之处在于uniqueId将构造 ID 附加到逻辑标识符,并且每个附加的散列都不同。SecurityGroup的构造 ID 和TestConstructSecurityGroup95EF3F0F逻辑 ID 不同。有没有一种直接的方法可以获取 CDK 资源的逻辑 ID?
jre*_*ady 14
在写完整篇文章并深入研究 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);
Run Code Online (Sandbox Code Playgroud)
请注意,您已经拥有一个 CloudFormation 资源(例如以 开头的资源Cfn),那么它会更容易一些。
// Pretend construct.securityGroup is of type CfnSecurityGroup
const logicalId = stack.getLogicalId(construct.securityGroup);
Run Code Online (Sandbox Code Playgroud)
从我的测试来看,似乎stack.getLogicalId总是返回原始的、CDK分配的逻辑Id,如果你调用它不会改变overrideLogicalId,所以它并不总是与合成的输出匹配。
即使设置了 LogicalId 覆盖,这对我也有用:
stack.resolve((construct.node.defaultChild as cdk.CfnElement).logicalId)
Run Code Online (Sandbox Code Playgroud)
stack.resolve是必要的,因为它.logicalId是一个令牌。
| 归档时间: |
|
| 查看次数: |
4819 次 |
| 最近记录: |