web-dev-qa-db-ja.com

パラメータが更新されたときにCloudFormationスタックを強制的に更新するにはどうすればよいですか?

一部のパラメーターを受け取り、他のAWSリソースとともにEC2インスタンスを起動するAWS CloudFormationスタックを実行しています。パラメーターはEC2インスタンスのユーザーデータにフィードされ、その変更に基づいて、EC2インスタンスにあるWebアプリケーションに動的に変更が加えられます。

CFN Parameters

UserData: 
      Fn::Base64: 
        Fn::Join: 
          - ""
          - 
            - "#!/bin/bash \n"
            - "sh website-conf/website_mysql_config.sh "
            - " -c \""
            - 
              Ref: "CompanyName"

上記の例に示すように、CompanyNameは、userdataスクリプトに渡される多くのパラメーターの1つです。問題は、1つまたは複数のパラメーターが更新されると、CloudFormationがそれを検出せず、代わりにこのエラーをスローすることです。

CFN Error

そのため、スタックを更新するには、CloudFormationが変更を「確認」してスタックの更新を実行できるように、スタックを編集してASGに変更を加える必要があります。

パラメータが更新されたときにCFNがスタックを強制的に更新する方法はありますか?

7
captainblack

AWS CLI Update-Stackコマンドを使用します。 AWS CLIを使用する場合は、スタックにパラメーターを注入できるため、パラメーターを変更すると新しいスタックが生成されます。私はこれを自分で行って、Git /バージョンのコミットIDをUserDataに挿入しているので、スタックのJSON/Yamlへの変更をGitにコミットするだけで、スタックの更新が可能になります。パラメータファイルを変更すると、コメントだけでもスタックを更新できます。 Ref:CompanyNameを参照しているのと同じ方法でUserDataでGitコミットIDを参照しているため、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

プロセス

このアプローチでは、パラメーターのjsonまたはyamlファイルのパラメーターを変更し、それをバージョン管理にチェックインします。ビルドサーバーを使用している場合は、マスターをチェックアウトして上記の1行を実行するだけでスタックを更新できます。 AWS CodeBuildを使用すると、これが簡単になるため、ジェンキンが不要になります。

3
Usman Mutawakil

CloudFormationは、スタックにすでに作成されているリソースのプロパティの変更がない限り、スタックを更新しません。

例: 2つのパラメーターを渡す必要があるデータベースを作成するための単純なテンプレートがあると考えてください。

  1. db-name
  2. 領域

db-nameを使用して、値としてDBInstanceIdentifierに渡しているとします。

また、スタックのリソース(またはそのプロパティ)の作成において、入力パラメーターregionを何らかの目的で使用していないとします。これは、読みやすさの目的で保持するダミーパラメーターです。

CloudFormationテンプレートへの入力パラメーターとして(TEST-DB1, us-east-1)を渡し、リソースを正常に作成しました。

Scenario-1:スタックを更新した場合(引き続き既存のテンプレートを使用)、入力パラメータを(TEST-DB2, us-east-1)に変更するだけです。つまり、リージョンではなく、db-nameのみを変更します。次に、CloudFormationは、このパラメーターの更新により、スタックの実行中のリソースのプロパティが変更されたことを検出し、変更を変更セットとして計算して表示します。

Scenario-2:別の更新を行い(既存のテンプレートを引き続き使用して)、入力パラメータを(TEST-DB1, us-east-2)に変更するとします。つまり、db-nameではなく、リージョンのみを変更します。次に、CloudFormationは、このパラメーターの更新により、スタックの実行中のリソースのプロパティに変更はありませんError creating change setを示すことを検出します。

ボトムライン:入力パラメータを変更すると、リソース(またはセキュリティグループ、ポートなどの属性)が更新/置換される必要がありますのスタック。次に、AWS CloudFormationはそれらをレビュー用にChange Setsとして表示します。また、AWS CloudFormationが使用するメソッド(更新または置換)は、特定のリソースタイプで更新するプロパティによって異なります。

パラメーター "CompanyName"は、スタックの実行中のリソースに変更を加えていません。したがって、Error creating change setとして報告されます。スタックのリソース/リソースプロパティを作成するには、これを使用する必要があります。次に、CloudFormationは変更時に変更セットを検出します。同じことが、使用する他の入力パラメータにも当てはまります。

8

問題の答えはすでにこの状態で答えられています。CloudFormationは、スタックに既に作成されているリソースのプロパティに変更がない限り、スタックを更新しません。

また、質問に対する回答は、以下の説明をご確認ください。

CloudformationがAWS::CloudFormation::Initを使用してスタックを更新するように強制する方法があります。 cfn-initを使用することにより、各インスタンスは、メタデータ内のAWS::CloudFormation::Initによって行われた変更を検出すると、それ自体を更新できます。

最初に理解しなければならない概念があります。それは、少なくともAWS::CloudFormation::Initのケースでは、UserDataとメタデータの違いです。

  • Userdata:インスタンスが初めて起動されるときに1回だけ呼び出されます(これには、インスタンスを置き換える必要がある更新も含まれます)。したがって、スタックを更新する場合(新しいスタックを作成しない場合)、パラメーター値を変更しても、UserDataでパラメーターを呼び出しても何も変更されません。
  • Metadata:いつでも更新できます。機能させるには、変更されたメタデータを検出するデーモンが実行されていることを確認する必要があります(このデーモンはcfn-hupと呼ばれます)。

MetadataおよびAWS::CloudFormation::Initをすでに使用している場合、データはすぐには更新されません。私の知る限り、これはMetadata値を変更した後にデータが変更される条件です。

  • インスタンスを再起動します
  • パラメータを指定してcfn-initコマンドを再度実行します
  • Metadataの変更を確認するデーモンが15分に1回変更を確認しているため、約15分待機しています。
1
sin