Rah*_*hul 5 unit-testing amazon-web-services aws-cdk
我正在尝试对我的 CDK 应用程序进行单元测试。我创建了一个角色,我想确保它已分配所有策略。由于角色和策略是不同的资源,因此 Cloud Formation 角色资源无法提供策略。角色仅具有对策略的引用:
"MyRole4CBCE4C9": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
...
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{
"Ref": "MyPolicyC18AB378"
}
]
},
Run Code Online (Sandbox Code Playgroud)
在测试中我有:
expectCDK(stack).to(haveResource("AWS::IAM::Role", {
AssumeRolePolicyDocument: {
Statement: [
...
],
Version: "2012-10-17",
},
}
));
Run Code Online (Sandbox Code Playgroud)
我如何验证这个确切的角色具有正确的策略?我脑子里的步骤如下:
然而,CDK 似乎没有提供通过元素的逻辑 id 获取元素以及从中获取资源haveResource作为对象的功能。
CDK 进行此类测试的方法是什么?
UPD:似乎我可以用 来接近它StackInspector,尽管我仍然想知道,真正的方法是什么。
Scenario 1: you're creating a role and a policy in the same stack, and the policy will not be reused in any other stack.
In this case use iam.Policy and attach it in-line:
export class CdkGetLogicalIdExampleStack extends cdk.Stack {
role: iam.IRole;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const policy = new iam.Policy(this, 'policy', {
policyName: 'policy',
statements: [
new iam.PolicyStatement({
actions: ["s3:*"],
resources: ['*'],
effect: iam.Effect.ALLOW
})
]
});
this.role = new iam.Role(this, 'my-role', {
roleName: 'my-role',
assumedBy: new iam.AccountPrincipal(this.account),
});
// Alternatively: this.role.attachInlinePolicy(policy);
policy.attachToRole(this.role);
}
}
Run Code Online (Sandbox Code Playgroud)
The role is kept as stack's attribute, so it's easy to refer to it in tests:
test('Empty Stack', () => {
const app = new cdk.App();
const stack = new CdkGetLogicalIdExample.CdkGetLogicalIdExampleStack(app, 'MyTestStack');
const roleId = stack.getLogicalId(stack.role.node.findChild('Resource') as cdk.CfnElement);
expectCDK(stack).to(haveResource("AWS::IAM::Policy", {
"PolicyDocument": {
"Statement": [
{
"Action": "s3:*",
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
},
"PolicyName": "policy",
"Roles": [
{
"Ref": roleId
}
]
}));
});
Run Code Online (Sandbox Code Playgroud)
Scenario 2: you're creating a policy that can be used in various stacks, so you want to make it a managed policy.
Testing this scenario is a little bit more complex because iam.ManagedPolicy implements the IManagedPolicy interface, which only provides the managedPolicyArn attribute (I am using CDK 1.124.0).
Nevertheless, the iam.ManagedPolicy extends the cdk.Resource, so we can trick the casting mechanism of TypeScript in the following way:
export class CdkGetLogicalIdExampleStack extends cdk.Stack {
// note the type here
managedPolicy: cdk.Resource | iam.IManagedPolicy;
role: iam.IRole;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
this.managedPolicy = new iam.ManagedPolicy(this, 'managed-policy', {
managedPolicyName: 'managed-policy',
document: new iam.PolicyDocument({
statements: [
new iam.PolicyStatement({
actions: ["dynamodb:*"],
resources: ["*"],
effect: iam.Effect.ALLOW
})
]
})
});
this.role = new iam.Role(this, 'my-role', {
roleName: 'my-role',
assumedBy: new iam.AccountPrincipal(this.account),
});
// here we need to cast to iam.IManagedPolicy
this.role.addManagedPolicy(this.managedPolicy as iam.IManagedPolicy);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,测试它是可能的,因为我们可以访问managedPolicy属性cdk.Resource:
const roleId = stack.getLogicalId(stack.role.node.findChild('Resource') as cdk.CfnElement);
// here we do the casting to cdk.Resource
const managedPolicyResource = stack.managedPolicy as cdk.Resource;
const managedPolicyId = stack.getLogicalId(managedPolicyResource.node.findChild('Resource') as cdk.CfnElement);
expectCDK(stack).to(haveResource("AWS::IAM::ManagedPolicy", {
"PolicyDocument": {
"Statement": [
{
"Action": "dynamodb:*",
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
},
"Description": "",
"ManagedPolicyName": "managed-policy",
"Path": "/"
}));
expectCDK(stack).to(haveResource("AWS::IAM::Role", {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::",
{
"Ref": "AWS::AccountId"
},
":root"
]
]
}
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{
"Ref": managedPolicyId
}
],
"RoleName": "my-role"
}));
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以测试您的策略是否具有所有必要的数据以及角色和策略之间的关系是否正确。
您可以在此处访问完整的工作示例。
| 归档时间: |
|
| 查看次数: |
2609 次 |
| 最近记录: |