简体   繁体   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?

Using the AWS CDK I created a simple stack with an auto scaling group, and also define launch configuration resource to execute some powershell scripts during the ec2 instance creation.使用 AWS CDK,我创建了一个带有 Auto Scaling 组的简单堆栈,并定义了启动配置资源以在 ec2 实例创建期间执行一些 powershell 脚本。 The scripts are located in the same cdk typescript project and I use and aws-s3-asset construct to upload the scripts directory.这些脚本位于同一个 cdk typescript 项目中,我使用 aws-s3-asset 构造上传脚本目录。 When the CDK synthtize the template it creates 3 CloudFormation parameters with autogenerated names to reference the S3 bucket of the assets.当 CDK 合成模板时,它会使用自动生成的名称创建 3 个 CloudFormation 参数,以引用资产的 S3 存储桶。 At this point every thing works perfect, I execute the cdk deploy StackWithAutoScalingGroup command, the cdk automatically populates the value of CloudFormation parameters and deploys the stack.此时一切正常,我执行 cdk deploy StackWithAutoScalingGroup 命令,cdk 自动填充 CloudFormation 参数的值并部署堆栈。

I decided to implement a CodePipeline stack(StackWithTheCodePipline) to deploy the StackWithAutoScalingGroup, it fetches the code from a CodeCommit repository the executes code build to synthesize the template and as final stage it is a CodeDeploy CloudFormation action used to deploy the stack.我决定实现一个 CodePipeline 堆栈 (StackWithTheCodePipline) 来部署 StackWithAutoScalingGroup,它从 CodeCommit 存储库中获取代码并执行代码构建以合成模板,并且作为最后阶段,它是用于部署堆栈的 CodeDeploy CloudFormation 操作。 This final step is failing because the CloudFormation params where not provided by the pipeline.这最后一步失败了,因为 CloudFormation 参数不是由管道提供的。

Im looking for a way to access the s3 Assets bucket created in the StackWithAutoScalingGroup from the StackWithTheCodePipline in order to provide the required CloudFormation params我正在寻找一种从 StackWithTheCodePipline 访问在 StackWithAutoScalingGroup 中创建的 s3 Assets 存储桶的方法,以便提供所需的 CloudFormation 参数

Any help will be appreciated任何帮助将不胜感激

StackWithAutoScalingGroup.ts 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 created afters the stack is Synthesized) 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 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,
            }),
          ],
        },
      ],
    });

The action provides the parameterOverrides property to set the required parameters but like the names was autogenerated I'm not able to find a way to know the parameters that the template expect neither the value for the parameters.该操作提供了 parameterOverrides 属性来设置所需的参数,但就像名称是自动生成的一样,我无法找到一种方法来了解模板不期望参数值的参数。

What I'm expect is a way to know the generated param names and also a way to reference the s3 assets bucket to provide the value for the parameters.我期望的是一种了解生成的参数名称的方法,以及一种引用 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,
            }),
          ],
        },

I'm not entirely sure of how things are setup. 我不确定如何设置。 I believe you may be able to do something like 我相信您也许可以做类似的事情

let yourS3Bucket = cdk.S3(blah)

parameterOverrides: {
  yourS3Bucket:yourS3Bucket.<your_property>
}

Instead of 代替

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

Those are very much pseudo code. 这些都是伪代码。 In essence, you can assign the S3 bucket to a variable and then reference that variable later. 本质上,您可以将S3存储桶分配给变量,然后在以后引用该变量。

You can do a few things:你可以做几件事:

  1. use a set name on your bucket (or a set name with a variable prefix defined at deploy using context variables) and then use Bucket.fromAttributes to import it into your other stack在您的存储桶上使用一个集合名称(或在部署时使用上下文变量定义一个变量前缀的集合名称),然后使用 Bucket.fromAttributes 将其导入到您的其他堆栈中

  2. Expose the Bucket object as an attribute on your stack.将 Bucket 对象作为堆栈上的属性公开。 When you instantiate the stack in your app you can then reference that attribute as a custom parameter into another stack (pseudo code)当您在应用程序中实例化堆栈时,您可以将该属性作为自定义参数引用到另一个堆栈中(伪代码)

inside a given stack...在给定的堆栈内...

my_bucket = s3.Bucket...

in your app在您的应用程序中

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

in the second stack在第二个堆栈中

something you need the bucket for(bucket: specialBucket你需要桶的东西(桶:specialBucket

The issue with this method is that it links the two stacks creating a dependency between them.这种方法的问题在于它链接了两个堆栈,从而在它们之间建立了依赖关系。 This in turn means changes to one may not be able to be deployed because the other stack would fall out of sync.这反过来意味着对一个堆栈的更改可能无法部署,因为另一个堆栈会不同步。 You can solve this by making both MyStack and SecondStack (from the above example) Nested Stacks in a common app stack.您可以通过在通用应用程序堆栈中创建 MyStack 和 SecondStack(来自上述示例)嵌套堆栈来解决此问题。 That give you the ability to move pieces around between stacks and deploy them all as a single application in terms of CloudFormation stacks, preventing deployment issues这使您能够在堆栈之间移动部分并将它们全部部署为 CloudFormation 堆栈方面的单个应用程序,从而防止部署问题

And finally... if you deployment does not require a lot of complex steps and things to follow, I have found it FAR easier to simply use a CodeBuild, install cdk during the pre-build, and run cdk deploy Stack* from inside a codebuild.最后...如果你部署不需要大量的复杂的步骤和东西跟着,我发现它容易简单地用一个CodeBuild,安装预编译期间CDK和运行CDK部署堆叠*从内代码构建。 The assets and whatnot are much easier to line up that way.以这种方式排列资产和诸如此类的东西要容易得多。

CodeCommit -> CodeBuild (that cdk Deploys) CodeCommit -> CodeBuild(即 cdk 部署)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AWS CDK 部署在 CodePipeline/CodeBuild - AWS CDK deploy in CodePipeline/CodeBuild 使用 AWS cdk 部署停靠的 .NET6 lambda 时如何自定义 docker 构建上下文? - How to customize docker build context when deploy a dockized .NET6 lambda using AWS cdk? 解决了|| 使用 AWS-CDK Typescript 更新单个堆栈时出现 RDS 堆栈问题 - SOLVED || Issue with RDS stack when updating a single stack using AWS-CDK Typescript 使用 AWS CDK typescript 时默认堆栈不正确 - Default Stack not correct while using AWS CDK typescript 如何使用 AWS CDK TYPESCRIPT 引用现有 VPC 来部署 Beanstalk 应用程序 - How to refer exsisting VPC to deploy Beanstalk app using AWS CDK TYPESCRIPT 如何使用aws cdk管理多个环境? - How to manage multiple environments using aws cdk? 如何使用 importValue() 从现有 Cloudformation 堆栈中检索数组 - How to retrieve an array using importValue() from an existing Cloudformation stack 如何使用 TypeScript 在 AWS CDK 中的 VPC 中导入现有私有子网? - How to import existing private subnets in a VPC in AWS CDK using TypeScript? 如何使用AWS CDK使用ApiGateway和S3设置CloudFront? - How to setup CloudFront with ApiGateway and S3 using AWS CDK? 如何使用 AWS CDK 检查自定义 VPC 是否已存在? - How to check if a custom VPC already exist using AWS CDK?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM