使用Pulumi+TypeScript创建S3 Bucket Policy遇Resource空值问题
问题:Pulumi + TypeScript创建S3存储桶及Bucket Policy时,测试阶段Resource字段出现null/undefined值
错误详情
expect(received).toEqual(expected) // deep equality - Expected - 2 + Received + 2 @@ -8,12 +8,12 @@ }, }, "Effect": "Deny", "Principal": "*", "Resource": Array [ - "app-testsupun-buyapp-bucket-arn", - "app-testsupun-buyapp-bucket-arn/*", + null, + "undefined/*", ], }, ], "Version": "2012-10-17", } 137 | Statement: [ 138 | { > 139 | Effect: 'Deny', | ^ 140 | Principal: '*', 141 | Action: 's3:*', 142 | Resource: ['app-testsupun-buyapp-bucket-arn', 'app-testsupun-buyapp-bucket-arn/*'], at infra/resource.unit.ts:139:32 at node_modules/@pulumi/output.ts:440:31 at node_modules/@pulumi/pulumi/output.js:21:71 at Object.<anonymous>.__awaiter (node_modules/@pulumi/pulumi/output.js:17:12) at applyHelperAsync (node_modules/@pulumi/pulumi/output.js:257:12) at node_modules/@pulumi/output.ts:352:13
相关代码
创建S3存储桶
const appS3 = new s3Bucket.S3Resource('app-testsupun-buyapp-bucket', { bucketArgOpts: { args: { bucket: 'app-testsupun-buyapp-bucket', tags: { application: 'app', }, }, }, });
创建Bucket Policy
const appS3Policy = new aws.s3.BucketPolicy( 'default-testsupun-policy', { bucket: appS3.bucket.bucket, policy: { Version: '2012-10-17', Statement: [ { Effect: 'Deny', Principal: '*', Action: 's3:*', Resource: [ /* pulumi.output(appS3.bucket.bucket).apply(() => `arn:aws:s3:::${bucketname}/*`), */ appS3.bucket.arn, pulumi.interpolate`${appS3.bucket.arn}/*`, ], Condition: { Bool: { 'aws:SecureTransport': 'false', }, }, }, ], }, }, { dependsOn: [appS3], }, );
解决方案
问题根源
appS3.bucket.arn是Pulumi的Output类型,直接将其放入普通JavaScript对象中时,Pulumi不会自动解析它的实际值。在测试阶段,这些Output还未完成解析,就会呈现为null或undefined。
代码修改
将Bucket Policy的policy字段改为用pulumi.output().apply()来构建,确保ARN值被正确解析:
const appS3Policy = new aws.s3.BucketPolicy( 'default-testsupun-policy', { bucket: appS3.bucket.bucket, // 用apply解析ARN后再构建Policy对象 policy: pulumi.output(appS3.bucket.arn).apply(arn => ({ Version: '2012-10-17', Statement: [ { Effect: 'Deny', Principal: '*', Action: 's3:*', Resource: [ arn, `${arn}/*` ], Condition: { Bool: { 'aws:SecureTransport': 'false', }, }, }, ], })), }, { dependsOn: [appS3], }, );
测试用例调整
测试时需要等待Output解析完成,用pulumi.output().promise()获取实际值后再断言:
// 示例测试代码 test('S3 Bucket Policy Resource字段正确', async () => { const expectedArn = 'arn:aws:s3:::app-testsupun-buyapp-bucket'; // 等待Policy值解析完成 const policy = await pulumi.output(appS3Policy.policy).promise(); expect(policy.Statement[0].Resource).toEqual([ expectedArn, `${expectedArn}/*` ]); });
内容的提问来源于stack exchange,提问作者Azmy
相关产品推荐
相关产品推荐

