簡體   English   中英

cfn 模板和管道都是使用 AWS CDK 創建的,如何使用 CodePipeline 部署 CloudFormation 堆棧?

[英]How to deploy a CloudFormation stack using CodePipeline when both, the cfn template and the pipeline where created using the AWS CDK?

使用 AWS CDK,我創建了一個帶有 Auto Scaling 組的簡單堆棧,並定義了啟動配置資源以在 ec2 實例創建期間執行一些 powershell 腳本。 這些腳本位於同一個 cdk typescript 項目中,我使用 aws-s3-asset 構造上傳腳本目錄。 當 CDK 合成模板時,它會使用自動生成的名稱創建 3 個 CloudFormation 參數,以引用資產的 S3 存儲桶。 此時一切正常,我執行 cdk deploy StackWithAutoScalingGroup 命令,cdk 自動填充 CloudFormation 參數的值並部署堆棧。

我決定實現一個 CodePipeline 堆棧 (StackWithTheCodePipline) 來部署 StackWithAutoScalingGroup,它從 CodeCommit 存儲庫中獲取代碼並執行代碼構建以合成模板,並且作為最后階段,它是用於部署堆棧的 CodeDeploy CloudFormation 操作。 這最后一步失敗了,因為 CloudFormation 參數不是由管道提供的。

我正在尋找一種從 StackWithTheCodePipline 訪問在 StackWithAutoScalingGroup 中創建的 s3 Assets 存儲桶的方法,以便提供所需的 CloudFormation 參數

任何幫助將不勝感激

StackWithAutoScalingGroup.ts

const captivaServer = new AutoScalingGroupStandard(this, 'CaptivaServer', {
      vpc: props.vpc,
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
      machineImage: new ec2.WindowsImage(ec2.WindowsVersion.WINDOWS_SERVER_2019_ENGLISH_FULL_BASE),
    });

const scripts = new assets.Asset(this, 'Scripts', {
path: path.join('cfninit', 'scripts'),
readers: [
captivaServer.instanceRole,
]
});

StackWithAutoScalingGroup.template.json(在堆棧合成后創建的參數)

"Parameters": {
    "SsmParameterValueawsserviceamiwindowslatestWindowsServer2019EnglishFullBaseC96584B6F00A464EAD1953AFF4B05118Parameter": {
      "Type": "AWS::SSM::Parameter::Value<String>",
      "Default": "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-Base"
    },
    "ScriptsS3Bucket1E273C2D": {
      "Type": "String",
      "Description": "S3 bucket for asset \"CdkCaptivaStack/Scripts\""
    },
    "ScriptsS3VersionKey0B5B668F": {
      "Type": "String",
      "Description": "S3 key for asset version \"CdkCaptivaStack/Scripts\""
    },
    "ScriptsArtifactHashC07F896B": {
      "Type": "String",
      "Description": "Artifact hash for asset \"CdkCaptivaStack/Scripts\""
    }
  }

StackWithTheCodePipline.ts

    new codepipeline.Pipeline(this, 'Pipeline', {
      stages: [
        {
          stageName: 'Source',
          actions: [
            new codepipeline_actions.CodeCommitSourceAction({
              actionName: 'CodeCommitSource',
              repository: code,
              output: sourceOutput,
            }),
          ],
        },
        {
          stageName: 'Build',
          actions: [
            new codepipeline_actions.CodeBuildAction({
              actionName: 'BuildStack',
              project: buildProject,
              input: sourceOutput,
              outputs: [buildOutput],
            }),
          ],
        },
        {
          stageName: 'DeployToTest',
          actions: [
            new codepipeline_actions.CloudFormationCreateUpdateStackAction({
              actionName: 'DeployStack',
              templatePath: buildOutput.atPath('StackWithAutoScalingGroup.template.json'),
              stackName: 'csg-cdk-captiva',
              //parameterOverrides: props.parameterOverrides,
              adminPermissions: true,
            }),
          ],
        },
      ],
    });

該操作提供了 parameterOverrides 屬性來設置所需的參數,但就像名稱是自動生成的一樣,我無法找到一種方法來了解模板不期望參數值的參數。

我期望的是一種了解生成的參數名稱的方法,以及一種引用 s3 資產存儲桶以提供參數值的方法。

       {
          stageName: 'DeployToTest',
          actions: [
            new codepipeline_actions.CloudFormationCreateUpdateStackAction({
              actionName: 'DeployStack',
              templatePath: buildOutput.atPath('StackWithAutoScalingGroup.template.json'),
              stackName: 'csg-cdk-captiva',
              parameterOverrides: {
                   'ScriptsS3Bucket1E273C2D':????,//how I can get the param name and also the values
                   'ScriptsS3VersionKey0B5B668F':???,
               }
              adminPermissions: true,
            }),
          ],
        },

我不確定如何設置。 我相信您也許可以做類似的事情

let yourS3Bucket = cdk.S3(blah)

parameterOverrides: {
  yourS3Bucket:yourS3Bucket.<your_property>
}

代替

parameterOverrides: {
                   'ScriptsS3Bucket1E273C2D':????,//how I can get the param name and also the values
                   'ScriptsS3VersionKey0B5B668F':???,
               }

這些都是偽代碼。 本質上,您可以將S3存儲桶分配給變量,然后在以后引用該變量。

你可以做幾件事:

  1. 在您的存儲桶上使用一個集合名稱(或在部署時使用上下文變量定義一個變量前綴的集合名稱),然后使用 Bucket.fromAttributes 將其導入到您的其他堆棧中

  2. 將 Bucket 對象作為堆棧上的屬性公開。 當您在應用程序中實例化堆棧時,您可以將該屬性作為自定義參數引用到另一個堆棧中(偽代碼)

在給定的堆棧內...

my_bucket = s3.Bucket...

在您的應用程序中

my_stack = MyStack(...
...
second_stack=SecondStack(.... specialBucket:mystack.my_bucket

在第二個堆棧中

你需要桶的東西(桶:specialBucket

這種方法的問題在於它鏈接了兩個堆棧,從而在它們之間建立了依賴關系。 這反過來意味着對一個堆棧的更改可能無法部署,因為另一個堆棧會不同步。 您可以通過在通用應用程序堆棧中創建 MyStack 和 SecondStack(來自上述示例)嵌套堆棧來解決此問題。 這使您能夠在堆棧之間移動部分並將它們全部部署為 CloudFormation 堆棧方面的單個應用程序,從而防止部署問題

最后...如果你部署不需要大量的復雜的步驟和東西跟着,我發現它容易簡單地用一個CodeBuild,安裝預編譯期間CDK和運行CDK部署堆疊*從內代碼構建。 以這種方式排列資產和諸如此類的東西要容易得多。

CodeCommit -> CodeBuild(即 cdk 部署)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM