スキップしてコンテンツを表示

Amazon EC2 Windows インスタンスがブートストラップを完了する前に CREATE_COMPLETE としてシグナルを返さないようにする方法を教えてください。

所要時間3分
0

AWS CloudFormation の cfn-init と cfn-signal ヘルパースクリプトを使って Amazon Elastic Compute Cloud (Amazon EC2) Windows インスタンスをブートストラップしようとしています。ただし、cfn-init スクリプトは、インスタンスがブートストラップを完了する前にシグナルを返します。

簡単な説明

Amazon EC2 Windows インスタンスでは、EC2ConfigService プロセスが UserData スクリプトを呼び出します。次に、UserData が cfn-init.exe を呼び出して、cfn-init が EC2ConfigService の子プロセスとして実行されるようにします。

次の理由により、インスタンスが CREATE_COMPLETE としてシグナルを送り返すことがあります。

  • cfn-init.exe のステップの 1 つでシステムの再起動が必要な場合、シャットダウンして Ec2ConfigService プロセスに戻ることがあります。引き続き UserData スクリプトを処理し、cfn-signal.exe を実行して AWS CloudFormation にシグナルを返します。
  • UserData スクリプトは 1 回実行されるため、cfn-signal.exe ファイルは再起動後にシグナルを返しません。

次のコード例では、cfn-signal.exe は UserData スクリプトから直接呼び出されます。cfn-init.exe プロセスが再起動した場合、UserData スクリプトは 1 回実行されるため、cfn-signal.exe コマンドを呼び出すことはできません。

JSON の例:

"UserData": {
  "Fn::Base64": {
    "Fn::Join": [
      "",
      [
        "<script>\n",
        "cfn-init.exe -v -s ",
        {
          "Ref": "AWS::StackId"
        },
        " -r WindowsInstance",
        " --configsets ascending",
        " --region ",
        {
          "Ref": "AWS::Region"
        },
        "\n",
        "cfn-signal.exe -e %ERRORLEVEL% --stack ",
        {
          "Ref": "AWS::StackId"
        },
        " --resource WindowsInstance --region ",
        {
          "Ref": "AWS::Region"
        },
        "\n",
        "</script>"
      ]
    ]
  }
}

YAML の例:

UserData:
  Fn::Base64: !Sub |
    <script>
    cfn-init.exe -v -s ${AWS::StackId} -r WindowsInstance --configsets ascending --region ${AWS::Region}
    cfn-signal.exe -e %ERRORLEVEL% --stack ${AWS::StackId} --resource WindowsInstance --region ${AWS::Region}
    </script>

解決方法

  1. テンプレートの cfn-init Metadata セクションのコンフィグセットを使用して、再起動が必要な設定とそうでない設定を分離します。

  2. cfn-signal.exe を AWS::EC2::Instance または AWS::AutoScaling::LaunchConfiguration リソースの UserData セクションから、テンプレートの AWS::CloudFormation::Init メタデータセクションに移動します。

  3. 最後の configset で実行される最後のコマンドとして cfn-signal.exe を実行します。

  4. JSON または YAML テンプレートで、UserDatacfn-init に変更し、昇順の configset を指定します。
    JSON の例:

    {
      "AWSTemplateFormatVersion": "2010-09-09",
      "Description": "cfn-init example using configsets",
      "Parameters": {
        "AMI": {
          "Type": "AWS::EC2::Image::Id"
        }
      },
      "Resources": {
        "WindowsInstance": {
          "Type": "AWS::EC2::Instance",
          "Metadata": {
            "AWS::CloudFormation::Init": {
              "configSets": {
                "ascending": [
                  "config1",
                  "config2",
                  "config3"
                ]
              },
              "config1": {
                "files": {
                  "C:\\setup\\setenvironment.ps1": {
                    "content": {
                      "Fn::Join": [
                        "",
                        [
                          "$Folder = 'C:\\Program Files\\Server\\packages\\bin.20182.18.0826.0815\\'\n",
                          "$OldPath = [System.Environment]::GetEnvironmentVariable('path')\n",
                          "$NewPath = $OldPath + ';' + $Folder\n",
                          "[System.Environment]::SetEnvironmentVariable('path',$NewPath,'Machine')"
                        ]
                      ]
                    }
                  }
                }
              },
              "config2": {
                "commands": {
                  "0-restart": {
                    "command": "powershell.exe -Command Restart-Computer",
                    "waitAfterCompletion": "forever"
                  }
                }
              },
              "config3": {
                "commands": {
                  "01-setenvironment": {
                    "command": "powershell.exe -ExecutionPolicy Unrestricted C:\\setup\\setenvironment.ps1",
                    "waitAfterCompletion": "0"
                  },
                  "02-signal-resource": {
                    "command": {
                      "Fn::Join": [
                        "",
                        [
                          "cfn-signal.exe -e %ERRORLEVEL% --resource WindowsInstance --stack ",
                          {
                            "Ref": "AWS::StackName"
                          },
                          " --region ",
                          {
                            "Ref": "AWS::Region"
                          }
                        ]
                      ]
                    }
                  }
                }
              }
            }
          },
          "Properties": {
            "ImageId": {
              "Ref": "AMI"
            },
            "InstanceType": "t2.medium",
            "UserData": {
              "Fn::Base64": {
                "Fn::Join": [
                  "",
                  [
                    "<script>\n",
                    "cfn-init.exe -v -s ",
                    {
                      "Ref": "AWS::StackId"
                    },
                    " -r WindowsInstance",
                    " --configsets ascending",
                    " --region ",
                    {
                      "Ref": "AWS::Region"
                    },
                    "</script>"
                  ]
                ]
              }
            }
          },
          "CreationPolicy": {
            "ResourceSignal": {
              "Count": "1",
              "Timeout": "PT30M"
            }
          }
        }
      }
    }

    YAML の例:

    AWSTemplateFormatVersion: '2010-09-09'
    Description: cfn-init example using configsets
    Parameters:
      AMI:
        Type: 'AWS::EC2::Image::Id'
    Resources:
      WindowsInstance:
        Type: 'AWS::EC2::Instance'
        Metadata:
          AWS::CloudFormation::Init:
            configSets:
              ascending:
                - config1
                - config2
                - config3
            config1:
              files:
                C:\setup\setenvironment.ps1:
                  content: !Sub |
                    $Folder = 'C:\Program Files\Server\packages\bin.20182.18.0826.0815\'
                    $OldPath = [System.Environment]::GetEnvironmentVariable('path')
                    $NewPath = $OldPath + ';' + $Folder
                    [System.Environment]::SetEnvironmentVariable('path',$NewPath,'Machine')
            config2:
              commands:
                0-restart:
                  command: powershell.exe -Command Restart-Computer
                  waitAfterCompletion: forever
            config3:
              commands:
                01-setenvironment:
                  command: powershell.exe -ExecutionPolicy Unrestricted C:\setup\setenvironment.ps1
                  waitAfterCompletion: '0'
                02-signal-resource:
                    command: !Sub >
                      cfn-signal.exe -e %ERRORLEVEL% --resource WindowsInstance --stack ${AWS::StackName} --region ${AWS::Region}
        Properties:
          ImageId: !Ref AMI
          InstanceType: t2.medium
          UserData:
            Fn::Base64: !Sub |
              <script>
              cfn-init.exe -v -s ${AWS::StackId} -r WindowsInstance --configsets ascending --region ${AWS::Region}
              </script>
        CreationPolicy:
          ResourceSignal:
            Count: 1
            Timeout: PT30M

    前述のテンプレートでは、シグナルは UserData で実行されず、cfn-init プロセスによって提供される終了コードを取得できません。デフォルトでは、CloudFormation は UserData または Metadata からのシグナルがない限り、スタックの作成または更新に失敗します。その後、スタックは「タイムアウト超過」エラーを返します。
    **ヒント:**障害のトラブルシューティングを行うには、Windows インスタンスの c:\cfn\log のログを使用してください。

  5. waitAfterCompletion パラメーターを [無期限] に設定します。
    注:****waitAfterCompletionのデフォルト値は 60 秒です。値を forever に変更した場合、cfn-init は終了し、再起動が完了した後にのみ再開します。

関連情報

Bootstrapping AWS CloudFormation Windows スタック

AWS公式更新しました 2年前
コメントはありません

関連するコンテンツ