내용으로 건너뛰기

인스턴스가 부트스트랩을 완료하기 전에 Amazon EC2 Windows 인스턴스가 CREATE_COMPLETE로 다시 신호를 보내지 않게 하려면 어떻게 해야 하나요?

4분 분량
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의 단계 중 하나에서 시스템을 재부팅해야 하는 경우 시스템이 종료되고 Ec2ConfigService 프로세스로 돌아갈 수 있습니다. 시스템은 UserData 스크립트를 계속 처리한 다음 cfn-signal.exe를 실행하여 AWS CloudFormation에 다시 신호를 보냅니다.
  • UserData 스크립트는 한 번 실행되기 때문에 재부팅 후에도 cfn-signal.exe 파일은 다시 신호를 보내지 않습니다.

다음 코드 예제에서는 UserData 스크립트에서 직접 cfn-signal.exe를 호출합니다. cfn-init.exe 프로세스가 재부팅을 수행하는 경우 UserData 스크립트가 한 번 실행되므로 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. 재부팅이 필요한 구성과 그렇지 않은 구성을 구분하려면 템플릿의 configsets에서 Metadata 섹션을 사용하세요.

  2. AWS::EC2::Instance 또는 AWS::AutoScaling::LaunchConfiguration 리소스의 UserData 섹션에서 템플릿의 AWS::CloudFormation::Init Metadata 섹션으로 cfn-signal.exe를 옮깁니다.

  3. 마지막 구성 집합에서 실행한 마지막 명령으로 cfn-signal.exe를 실행합니다.

  4. JSON 또는 YAML 템플릿에서 UserDatacfn-init로 변경하고 오름차순 구성 집합을 지정합니다.
    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 매개 변수를 forever로 설정합니다.
    참고: waitAfterCompletion의 기본값은 60초입니다. 값을 forever로 변경하면 재부팅이 완료된 후에만 cfn-init이 종료되고 다시 시작됩니다.

관련 정보

AWS CloudFormation Windows 스택의 부트스트래핑

AWS 공식업데이트됨 2년 전