更新参数后,如何强制CloudFormation堆栈更新?

cap*_*ack 6 amazon-ec2 amazon-web-services aws-cloudformation autoscaling

我正在运行一个AWS CloudFormation堆栈,该堆栈带有一些参数,并与其他AWS资源一起启动EC2实例。将参数输入到EC2实例的用户数据中,并基于此参数对驻留在EC2实例上的Web应用程序进行动态更改。

CFN参数

UserData: 
      Fn::Base64: 
        Fn::Join: 
          - ""
          - 
            - "#!/bin/bash \n"
            - "sh website-conf/website_mysql_config.sh "
            - " -c \""
            - 
              Ref: "CompanyName"
Run Code Online (Sandbox Code Playgroud)

如上面的示例所示,CompanyName是传递给userdata脚本的许多参数之一。问题是,当更新任何一个或多个参数时,CloudFormation不会检测到该参数,而是引发此错误。

CFN错误

因此,为了更新堆栈,我必须编辑堆栈并对ASG进行更改,以便CloudFormation“看到”更改并执行堆栈更新。

有没有办法在更新参数时强制CFN更新堆栈?

Mad*_*aju 7

除非堆栈中已经创建的资源的属性发生变化,否则CloudFormation不会更新堆栈。

例如: 考虑我有一个简单的模板来创建数据库,我需要在其中传递2个参数:

  1. 数据库名称
  2. 区域

假设我正在使用db-name将其作为值传递给DBInstanceIdentifier

还要假设我没有region以任何方式将输入参数用于创建堆栈资源(或其属性)的任何目的,它更多是为了可读性而保留的虚拟参数。

我将(TEST-DB1, us-east-1)输入参数传递给CloudFormation模板,并成功创建了资源。

Scenario-1: 现在,如果我更新堆栈(仍使用现有模板),只需将输入参数更改为(TEST-DB2, us-east-1)。即:仅更改数据库名称,而不更改区域。然后,CloudFormation将检测到此参数更新导致堆栈中正在运行的资源的属性发生更改,并将这些更改计算并显示为更改集。

Scenario-2: 假设我进行了另一个更新(仍然使用现有模板)属性,只是将输入参数更改为(TEST-DB1, us-east-2)。即:仅更改区域,而不更改数据库名称。然后CloudFormation将检测到此参数更新,导致堆栈中正在运行的资源的属性没有任何变化,将显示Error creating change set

底线: 输入参数的更改必须导致堆栈中任何资源(或其属性,如安全组,端口等)更新/替换。然后,AWS CloudFormation将显示它们以Change Sets供您查看。此外,AWS CloudFormation使用的方法(更新或替换)取决于您为给定资源类型更新的属性。

您的参数“ CompanyName”不会对堆栈的运行资源进行任何更改。因此它报告为Error creating change set。您需要使用它来创建堆栈的任何资源/资源属性。然后,CloudFormation将在您对其进行更改时检测到更改集。这同样适用于您使用的任何其他输入参数。


Usm*_*kil 6

使用 AWS CLI 更新堆栈命令。如果您使用 AWS CLI,您可以将参数注入您的堆栈,因此对任何参数的任何更改都会产生一个新堆栈。我自己这样做是为了将 Git/版本提交 ID 注入 UserData,因此只需将堆栈的 JSON/Yaml 更改提交到 Git 即可允许堆栈更新。对参数文件的任何更改都将允许堆栈更新,即使只是注释。我在 UserData 中引用我的 Git 提交 ID 的方式与您引用 Ref:CompanyName 的方式相同,因此当我更改 Git 提交 ID 时,userData 部分会在堆栈更新时更新。

更新堆栈命令

aws cloudformation update-stack --stack-name MyStack --template-body file:///Users/Documents/Git/project/cloudformation/stack.json --parameters file:///Users/Documents/Git/project/cloudformation/parameters/stack-parameters.dev.json --capabilities CAPABILITY_IAM
Run Code Online (Sandbox Code Playgroud)

过程

通过这种方法,您可以对参数 json 或 yaml 文件进行参数更改,然后将其签入版本控制。现在,如果您使用构建服务器,您可以通过检查 master 并运行上面的那一行来更新您的堆栈。使用 AWS CodeBuild 使这变得简单,因此您不需要 jenkins。