【发布时间】:2020-08-31 07:49:27
【问题描述】:
我正在尝试为 CDK 构造编写一些 tests,以验证定义为构造一部分的安全组规则。
构造体如下所示。
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 访问的规则,您需要 Logical ID 的作为 Construct 的一部分创建的安全组。
您可以在此处生成的 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确实为您提供了handful of identifiers。
- 唯一 ID 提供了非常接近的东西,但它与 CloudFormation 堆栈中使用的标识符不同。例如,
securityGroup.uniqueId返回TestStackTestConstructSecurityGroup10D493A7,而 CloudFormation 模板显示TestConstructSecurityGroup95EF3F0F。您可以注意到不同之处在于uniqueId将构造 ID 附加到逻辑标识符中,并且附加的哈希在每个中都不同。 - 构造 ID 只是您在实例化构造时提供的标识符。它也不是逻辑 ID,尽管它被用作逻辑 ID 的一部分。我还没有看到直接从构造中以编程方式检索此 ID 的方法。您当然可以在某处定义 ID 并重复使用它,但这仍然不能解决它与逻辑 ID 不完全匹配的问题。在这种情况下,
SecurityGroup作为构造 ID,TestConstructSecurityGroup95EF3F0F作为合成模板中的逻辑 ID。
有没有直接的方法获取 CDK 资源的逻辑 ID?
【问题讨论】:
标签: amazon-web-services amazon-cloudformation aws-cdk