跳至內容

如何自訂 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 (KMS) 金鑰
  • IAM 角色
  • 用於版本控制的 SSM 參數

如需詳細資訊,請參閱 GitHub 網站上的用於自訂啟動的 AWS CDK 啟動程序範本

您可以針對以下使用案例自訂啟動程序範本:

  • 使用 AWS CDK 僅部署您使用的資源。
  • 更新或建立 S3 儲存貯體的自訂限定詞和名稱,以儲存 AWS CDK 應用程式檔案資產。
  • 使用現有的 S3 儲存貯體來儲存 AWS CDK 應用程式檔案資產。

解決方法

若要自訂啟動程序範本,請使用下列其中一種方法:

使用 AWS CDK 僅部署您使用的資源

AWS CDK 啟動程序會建立 CloudFormationExecutionRole 角色,供 CloudFormation 假設來部署您的堆疊。然後,CloudFormation 會使用此角色,透過 cdk deploy 命令從本機電腦進行部署,或透過 AWS CDK 管線進行 CI/CD 部署。

為了允許使用 AWS CDK 建立資源,CloudFormationExecutionRole 會具有 arn:aws:iam:aws:policy/AdministratorAccess 政策,該政策授予執行所有動作的完整存取權。請注意,此政策違反了最低權限原則。若要限制此政策,您必須建立新政策,然後使用新的自訂政策啟動 AWS CDK。

注意:請務必檢查所有命令,並將所有範例字串執行個體替換為所需的值。

  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 中只能儲存五個政策版本。如果您更新政策,請根據需要刪除較舊的版本。

更新或建立 S3 儲存貯體的自訂限定詞和名稱,以儲存 AWS CDK 應用程式檔案資產

  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 區段中的 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>"))

**注意:**您可以設定和自訂其他參數。如需詳細資訊,請參閱自訂啟動程序