You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 22:24:55