如何自定义 AWS CDK 引导并部署 CFNToolkit CloudFormation 堆栈?

3 分钟阅读
0

我想自定义 AWS Cloud Development Kit (AWS CDK) 引导并部署 CFN AWS CloudFormation 堆栈。

简短描述

要使用 AWS CDK,您必须引导您的 AWS 账户。引导操作会在账户上创建 AWS CDK 所需的资源。您可以通过以下操作自定义引导模板以实施合规性和安全性要求:

  • 为资源添加标签。
  • 为 Amazon Simple Storage Service (Amazon S3) 存储桶添加加密。
  • 使用自定义 S3 存储桶名称。
  • 使用现有的 S3 存储桶或对引导模板生成的 AWS Identity and Access Management (IAM) 角色应用最低权限主体。

cdk bootstrap 命令将创建了名为 CDKToolkit 的 CloudFormation 堆栈。CDKToolkit CloudFormation 堆栈中部署的资源来自模板。

要显示您的引导模板,请运行以下命令:

cdk bootstrap --show-template > bootstrap-template.yml

前面的引导模板包含以下资源:

  • 诸如 S3 存储桶之类的资源
  • AWS Key Management Service (AWS KMS) 密钥
  • IAM 角色
  • 用于版本控制的 SSM 参数

有关详细信息,请参阅 GitHub 网站上用于自定义引导的 AWS CDK 引导模板

您可以为以下用例自定义引导模板:

  • 使用 AWS CDK 仅部署您使用的资源。
  • 更新或创建用于存储 AWS CDK 应用程序文件资产的 S3 存储桶的自定义限定符和名称。
  • 使用现有的 S3 存储桶来存放 AWS CDK 应用程序文件资产。

解决方法

要自定义您的引导模板,请使用以下方法之一:

使用 AWS CDK 仅部署您使用的资源

AWS CDK 引导会创建一个角色 CloudFormationExecutionRole,CloudFormation 会代入该角色来部署您的堆栈。然后,CloudFormation 使用该角色通过 cdk deploy 命令从本地计算机进行部署,或者通过 CI/CD 的 AWS CDK 管线进行部署。

为了允许使用 AWS CDK 创建资源,CloudFormationExecutionRole 具有 arn:aws:iam:aws:policy/AdministratorAccess 策略,该策略授予执行所有操作的完全访问权限。请注意,此策略违背了最低权限原则。要限制此策略,您必须创建新策略,然后使用新的自定义策略引导 AWS CDK。

**注意:**请务必查看所有命令并将 example 字符串的所有实例替换为所需的值。

  1. 在 IAM 中创建自定义策略:

    aws iam create-policy \
      --policy-name cdkCFExecutionPolicy \
      --policy-document file://example-custom-Execution-Policy-name.json
  2. 使用新创建的 IAM 策略来引导 AWS CDK:

    ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
    cdk bootstrap aws://$ACCOUNT_ID/example-Region \
      --cloudformation-execution-policies "arn:aws:iam::$ACCOUNT_ID:policy/example-custom-Execution-Policy-name"
  3. (可选)如果账户已经被引导,请使用新的自定义策略重新运行 cdk bootstrap 命令。

  4. (可选)按照 AWS CDK 应用程序的要求更新您的策略以创建新的策略版本。可以将新策略版本设置为默认策略。

**注意:**IAM 中只能保存五个策略版本。如果您更新政策,请根据需要删除较早的版本。

更新或创建用于存储 AWS CDK 应用程序文件资产的 S3 存储桶的自定义限定符和名称

  1. 为限定符和 bootstrap-bucket-name 传递额外的标志以引导账户。这些标志使用资源的新值创建或更新 CDKToolkit CloudFormation 堆栈。

    cdk bootstrap --template bootstrap-template.yml --qualifier <example-custom-qualifier-value> --bootstrap-bucket-name <example-custom-bucket-name> --profile <example-profile-name>
  2. 使用以下值更新 app.py 文件:

    import os
    import aws_cdk as cdk
    from myproject.myproject_stack import MyprojectStack
    app = cdk.App()
    MyprojectStack(app, "MyprojectStack", synthesizer=cdk.DefaultStackSynthesizer(qualifier="<example-custom-qualifier-value>", file_assets_bucket_name="<example-custom-bucket-name>"))
    app.synth()

**注意:**如果由于资源已经存在,CDKToolkit 堆栈无法部署,请先识别该资源,并在不需要时将其删除。然后,再次从 CloudFormation 堆栈执行引导。

使用现有的 S3 存储桶存放 AWS CDK 应用程序文件资产

AWS CDK 应用程序使用 CDKToolkit AWS CloudFormation Stack > Outputs(CDKToolkit AWS CloudFormation 堆栈 > 输出)部分中的 S3 存储桶名称和位置。要使用现有的 S3 存储桶,必须修改 bootstrap-template.yml

  1. 使用现有的 S3 存储桶详细信息修改 BucketNameBucketDomainNameOutputs(输出)值:

    Outputs:
        BucketName:
            Description: The name of S3 bucket owned by the CDK toolkit stack
            Value: <example-existing-bucket-name>
        BucketDomainName:
            Description: The domain name of the S3 bucket owned by the CDK toolkit stack
            Value: <example-existing-bucket-name>.s3.<example-Region>.amazonaws.com
  2. bootstrap-template.ymlDeploymentActionRoleFilePublishingRoleDefaultPolicy 资源中添加现有 S3 存储桶的 ARN

    Resources:
        DeploymentActionRole:
            Type: AWS::IAM::Role
            Properties:
              AssumeRolePolicyDocument:
                Statement:
                  - Action: sts:AssumeRole
                    Effect: Allow
                    Principal:
                      AWS:
                        Ref: AWS::AccountId
                  - Fn::If:
                      - HasTrustedAccounts
                      - Action: sts:AssumeRole
                        Effect: Allow
                        Principal:
                          AWS:
                            Ref: TrustedAccounts
                      - Ref: AWS::NoValue
              Policies:
                - PolicyDocument:
                    Statement:
                      - Sid: CliStagingBucket
                        Effect: Allow
                        Action:
                          - s3:GetObject*
                          - s3:GetBucket*
                          - s3:List*
                        Resource:
                          - Fn::Sub: ${StagingBucket.Arn}
                          - Fn::Sub: ${StagingBucket.Arn}/*
                          - arn:aws:s3:::<example-existing-bucket-name>
                          - arn:aws:s3:::<example-existing-bucket-name>/
                    Version: "example-version"
                  PolicyName: default
              RoleName:
                Fn::Sub: cdk-${Qualifier}-deploy-role-${AWS::AccountId}-${AWS::Region}
              Tags:
                - Key: aws-cdk:bootstrap-role
                  Value: deploy
        FilePublishingRoleDefaultPolicy:
            Type: AWS::IAM::Policy
            Properties:
              PolicyDocument:
                Statement:
                  - Action:
                      - s3:GetObject*
                      - s3:GetBucket*
                      - s3:GetEncryptionConfiguration
                      - s3:List*
                      - s3:DeleteObject*
                      - s3:PutObject*
                      - s3:Abort*
                    Resource:
                      - Fn::Sub: ${StagingBucket.Arn}
                      - Fn::Sub: ${StagingBucket.Arn}/*
                      - arn:aws:s3:::<example-existing-bucket-name>/
                      - arn:aws:s3:::<example-existing-bucket-name>
                    Effect: Allow
                  - Action:
                      - kms:Decrypt
                      - kms:DescribeKey
                      - kms:Encrypt
                      - kms:ReEncrypt*
                      - kms:GenerateDataKey*
                    Effect: Allow
                    Resource:
                      Fn::If:
                        - CreateNewKey
                        - Fn::Sub: ${FileAssetsBucketEncryptionKey.Arn}
                        - Fn::Sub: arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/${FileAssetsBucketKmsKeyId}
                Version: "example-version"
              Roles:
                - Ref: FilePublishingRole
              PolicyName:
                Fn::Sub: cdk-${Qualifier}-file-publishing-role-default-policy-${AWS::AccountId}-${AWS::Region}
  3. 运行 cdk bootstrap 命令。CDKToolkit CloudFormation 堆栈是使用前面的更改创建或更新的。

  4. 要将文件资产上传到项目中的现有 S3 存储桶,请编辑 CDK 的堆栈合成器。在您的 app.py 文件中包含以下内容:

    MyprojectStack(app, "MyprojectStack", synthesizer=cdk.DefaultStackSynthesizer(file_assets_bucket_name="<example-existing-bucket-name>"))

**注意:**您可以配置和自定义其他参数。有关详细信息,请参阅自定义引导

AWS 官方
AWS 官方已更新 5 个月前