CDK 部署结果显示“名为“x”的存储桶存在,但不在帐户 067685711111 中。帐户错误?”

hal*_*fer 4 typescript aws-lambda aws-cdk

我正在修改一个有效的 CDK 管道。我添加了一个 lambda,当进行此代码修改时,管道失败并出现错误。

\n
import * as cdk from \'@aws-cdk/core\';\nimport * as lambda from \'@aws-cdk/aws-lambda\';\nimport * as path from \'path\';\nimport { Rule, Schedule } from \'@aws-cdk/aws-events\';\nimport { LambdaFunction } from \'@aws-cdk/aws-events-targets\';\nimport { Secret } from \'@aws-cdk/aws-secretsmanager\';\nimport { Effect, Policy, PolicyStatement } from \'@aws-cdk/aws-iam\';\n\ninterface LambdaStackProps extends cdk.StackProps {\n    logzioToken: string;\n}\n\nexport class Lambda extends cdk.Stack {\n    constructor(scope: cdk.Construct, id: string, props: LambdaStackProps) {\n        super(scope, id, props);\n\n        const logzioSecret = Secret.fromSecretAttributes(this, \'sv-logzioToken\', {\n            secretPartialArn: props.logzioToken,\n        });\n\n        // Here is the func itself\n        const func = new lambda.Function(this, \'sv-http-cache-clear-lambda\', {\n            runtime: lambda.Runtime.NODEJS_14_X,\n            handler: \'index.handler\',\n            // The "build" folder requires `yarn build` to have been run in the lambda folder\n            code: lambda.Code.fromAsset(path.join(__dirname, \'../../lambdas/HttpCacheClear/build\')),\n            environment: {\n                LOGZIO_TOKEN: logzioSecret.secretValueFromJson(\'logzioToken\').toString(),\n            },\n        });\n\n        // Here are the Dynamo permissions I think we need\n        const policyStatement = new PolicyStatement({\n            actions: [\'dynamodb:GetItem\', \'dynamodb:Query\', \'dynamodb:Scan\', \'dynamodb:DeleteItem\'],\n            effect: Effect.ALLOW,\n            resources: [\'*\'],\n        });\n        const policy = new Policy(this, \'sv-http-cache-clear-policy\', {\n            statements: [policyStatement],\n        });\n        func.role?.attachInlinePolicy(policy);\n\n        new Rule(this, \'sv-http-cache-clear-schedule-rule\', {\n            description: \'Schedule a Lambda that regularly clears the cache\',\n            schedule: Schedule.cron({\n                year: \'*\',\n                month: \'*\',\n                day: \'*\',\n                hour: \'1\',\n                minute: \'0\',\n            }),\n            targets: [new LambdaFunction(func)],\n        });\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是在 CDK 中实例化的:

\n
#!/usr/bin/env node\nimport \'source-map-support/register\';\nimport * as cdk from \'@aws-cdk/core\';\nimport { AppStack } from \'../lib/app-stack\';\nimport { ECR } from \'../lib/ecr\';\nimport { Lambda } from \'../lib/lambda\';\nimport { getConfig } from \'../lib/config\';\n\nconst app = new cdk.App();\n\n// Stateful infra\nconst { repository } = new ECR(app, \'sv-ecr-stack\');\n\n// Get app config\nconst environment = process.env.ENVIRONMENT || \'\';\nconst { certificateArn, domainName, sIdProgramId, logzioToken, optimizelyUrl } = getConfig(environment);\n\nnew AppStack(app, \'sv-stack\', {\n    repository,\n    domainName,\n    certificateArn,\n    sIdProgramId,\n    logzioToken,\n    optimizelyUrl,\n    environment,\n});\n\nconst lambda = new Lambda(app, \'sv-http-scheduled-cache-clear\', {\n    logzioToken,\n});\n
Run Code Online (Sandbox Code Playgroud)\n

出于简洁的原因,我没有将其添加AppStack到这篇文章中。

\n

最后,我有一组相当简单的 NPM 依赖项:

\n
{\n    "name": "cdk",\n    "version": "0.1.0",\n    "bin": {\n        "cdk": "bin/cdk.js"\n    },\n    "scripts": {\n        "build": "tsc",\n        "watch": "tsc -w",\n        "cdk": "cdk",\n        "synth": "cdk synth -q",\n        "deploy": "cdk deploy --all --progress=events --require-approval=never"\n    },\n    "devDependencies": {\n        "@aws-cdk/assert": "^1.100.0",\n        "@aws-cdk/aws-certificatemanager": "^1.100.0",\n        "@aws-cdk/aws-ec2": "^1.100.0",\n        "@aws-cdk/aws-ecr": "^1.100.0",\n        "@aws-cdk/aws-ecs": "^1.100.0",\n        "@aws-cdk/aws-ecs-patterns": "^1.100.0",\n        "@aws-cdk/aws-iam": "^1.100.0",\n        "@aws-cdk/aws-route53": "^1.100.0",\n        "@types/node": "10.17.27",\n        "aws-cdk": "^1.100.0",\n        "ts-node": "^9.0.0",\n        "typescript": "~3.9.7"\n    },\n    "dependencies": {\n        "@aws-cdk/core": "^1.100.0",\n        "source-map-support": "^0.5.16"\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如果我npm run synth在本地运行,那么它会运行合成命令,并成功。我的编辑器中没有 TypeScript 错误。

\n

这是cdk deploy错误:

\n
export AWS_ACCESS_KEY_ID=$DEV_ACCESS_KEY_ID\nexport AWS_SECRET_ACCESS_KEY=$DEV_SECRET_ACCESS_KEY\nexport ENVIRONMENT=dev\ncd cdk\nnpm install\nnpm run deploy\n\nnpm WARN read-shrinkwrap This version of npm is compatible with lockfileVersion@1, but package-lock.json was generated for lockfileVersion@2. I\'ll try to do my best with it!\nnpm WARN cdk@0.1.0 No repository field.\nnpm WARN cdk@0.1.0 No license field.\n\nadded 1363 packages from 232 contributors and audited 1366 packages in 19.228s\n\n18 packages are looking for funding\n  run `npm fund` for details\n\nfound 0 vulnerabilities\n\n\n> cdk@0.1.0 deploy /home/circleci/project/cdk\n> cdk deploy --all --progress=events --require-approval=never\n\nsv-ecr-stack\nsv-ecr-stack: deploying...\n\n \xe2\x9c\x85  sv-ecr-stack (no changes)\n\nOutputs:\nsv-ecr-stack.ExportsOutputFnGetAttsvrepositoryXXX = arn:aws:ecr:*********:067685711111:repository/student-validation-app\nsv-ecr-stack.ExportsOutputRefsvrepositoryXXX = student-validation-app\n\nStack ARN:\narn:aws:cloudformation:*********:067685711111:stack/sv-ecr-stack/aabbccddeeffgghhiijjkk\nsv-http-scheduled-cache-clear\nsv-http-scheduled-cache-clear: deploying...\n[0%] start: Publishing abcdefghijklmnop:current\n[100%] fail: Bucket named \'cdktoolkit-stagingbucket-7k57fjeur592\' exists, but not in account 067685711111. Wrong account?\n\n \xe2\x9d\x8c  sv-http-scheduled-cache-clear failed: Error: Failed to publish one or more assets. See the error messages above for more information.\n    at Object.publishAssets (/home/circleci/project/cdk/node_modules/aws-cdk/lib/util/asset-publishing.ts:25:11)\n    at Object.deployStack (/home/circleci/project/cdk/node_modules/aws-cdk/lib/api/deploy-stack.ts:235:3)\n    at CdkToolkit.deploy (/home/circleci/project/cdk/node_modules/aws-cdk/lib/cdk-toolkit.ts:180:24)\n    at initCommandLine (/home/circleci/project/cdk/node_modules/aws-cdk/bin/cdk.ts:208:9)\n***************************************************\n*** Newer version of CDK is available [1.110.0] ***\n*** Upgrade recommended                         ***\n***************************************************\nFailed to publish one or more assets. See the error messages above for more information.\nnpm ERR! code ELIFECYCLE\nnpm ERR! errno 1\nnpm ERR! cdk@0.1.0 deploy: `cdk deploy --all --progress=events --require-approval=never`\nnpm ERR! Exit status 1\nnpm ERR! \nnpm ERR! Failed at the cdk@0.1.0 deploy script.\nnpm ERR! This is probably not a problem with npm. There is likely additional logging output above.\n\nnpm ERR! A complete log of this run can be found in:\nnpm ERR!     /home/circleci/.npm/_logs/2021-06-25T13_34_37_706Z-debug.log\n\n\nExited with code exit status 1\n
Run Code Online (Sandbox Code Playgroud)\n

一些研究表明 CDK 使用 S3 创建“临时存储桶”,我认为这就是它的本质cdktoolkit-stagingbucket-*(它不是我明确创建的工件)。

\n

我需要远程/显式或本地/手动创建此存储桶吗?

\n

更新

\n

我发现这个错误报告表明错误消息很糟糕 - 它需要 S3 访问权限,但该消息并没有明确说明这一点。我已经为 CI/CD 用户找到了这个策略文件,我想知道是否需要确定向其中添加哪些策略以允许使用 S3。

\n
{\n    "Version": "2012-10-17",\n    "Statement": [\n        {\n            "Sid": "StmtXXXYYYZZZ4501",\n            "Action": [\n                "cloudformation:*",\n                "ec2:*",\n                "ecs:*",\n                "ecr:*",\n                "application-autoscaling:*",\n                "elasticloadbalancing:*",\n                "iam:CreateRole",\n                "iam:DeleteRole",\n                "iam:GetRole",\n                "iam:TagRole",\n                "iam:UpdateRole",\n                "iam:GetRolePolicy",\n                "iam:DeleteRolePolicy",\n                "iam:PutRolePolicy",\n                "iam:PassRole",\n                "logs:*",\n                "route53:*",\n                "secretsmanager:*",\n                "sts:*",\n                "dynamodb:*",\n            ],\n            "Effect": "Allow",\n            "Resource": "*"\n        }\n    ]\n}\n
Run Code Online (Sandbox Code Playgroud)\n

hal*_*fer 5

该错误消息相当具有误导性。如果您有权访问多个帐户,则 S3 存储桶很可能存在于另一个帐户中 - 这是因为它是 CDK 用于打包和部署 lambda 的自动生成的存储桶。我假设所有 AWS 账户中的名称都相同。

简单的解决方案是添加"s3:*"针对资源的允许操作"*"。然而,我决定添加一个新的策略,以便资源规范更加严格。就我而言,这意味着添加具有不同资源规范的新子句:

{
    "Action": [
        "s3:*"
    ],
    "Effect": "Allow",
    "Resource": "arn:aws:s3:::cdktoolkit-stagingbucket-*"
}
Run Code Online (Sandbox Code Playgroud)

看起来您不必显式创建此存储桶 - CDK 会为您完成。看来“Sid”也不是必填字段。

就我而言,添加此策略显示了我缺少多少其他权限,但至少这些错误消息更明智!