Rollback EC2 Provisioning if UserData Execution Fails

0

I am creating an EC2 instance (Windows) via Cloud Formation. I am also executing some User Data scripts (PowerShell). Sometimes, some scripts throw errors. If that happens, I want to roll back and terminate the EC2 instance. I am using the WaitCondition resource as mentioned in the link. Even when the instance is successfully provisioned and the User Data is successfully executed, the WaitCondition doesn't receive a success signal and the instance is getting rolled back. Please help.

 DBEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !GetAtt AMIInfo.Id
      KeyName: !Ref sshKeyName
      InstanceType: !Ref dbInstanceType
      IamInstanceProfile: !Ref EC2InstanceProfile
      PropagateTagsToVolumeOnCreation: True
      SecurityGroupIds:
        - !Ref EC2SecurityGroup
      SubnetId: !Select [ 0, !Ref pvtSubnetIdRef ]
      Tags:
        - Key: "Name"
          Value: !Ref dbInstanceName
      UserData:
        Fn::Base64:
          !Sub |
          <powershell>
            # START LOG.
            $LASTEXITCODE=0
            $ErrorActionPreference = "Stop"
            cfn-init.exe -v --stack ${AWS::StackName} --resource DBEC2Instance --region ${AWS::Region}              
            $timestamp = Get-Date -Format yyyyMMdd-hhmm
            Start-Transcript -Path $logpath -Force
            
            #  DOWNLOAD FILES
            write "Downloading files from S3 bucket '${bucketName}'"
            Get-S3Object -BucketName ${bucketName} -KeyPrefix ${S3Path}/ | Read-S3Object -Folder "C:\"

            #  CALL CUSTOM UTILITY
            write "running CustomUtility'.
            write "Last Exit Code: $LASTEXITCODE"
            cfn-signal.exe -e $LASTEXITCODE --stack ${AWS::StackName}  --resource DBEC2Instance --region ${AWS::Region}
            if ( $LASTEXITCODE -ne 0 ) 
            { 
              write-error "CustomUtility exit code '$LASTEXITCODE' does not indicate success. Refer logs for details." 
            }
            
          </powershell>  
  
  WaitHandle:
    Type: AWS::CloudFormation::WaitConditionHandle
  WaitCondition:
    Type: AWS::CloudFormation::WaitCondition
    DependsOn: DBEC2Instance
  # Properties:
    #   Handle: !Ref 'WaitHandle'
    #   Timeout: '900'
    #   Count: 1
    CreationPolicy:
      ResourceSignal:
        Timeout: PT10M
        Count: 1
已提問 9 個月前檢視次數 282 次
1 個回答
1

From your post, I have noticed that you are using both wait condition handle and CreationPolicy and the syntax is also used incorrectly.

For Amazon EC2 and Auto Scaling resources, we recommend that you use a CreationPolicy attribute instead of wait conditions. Add a CreationPolicy attribute to those resources, and use the cfn-signal helper script to signal when an instance creation process has completed successfully.

You can use a wait condition for situations like the following:

  • To coordinate stack resource creation with configuration actions that are external to the stack creation.
  • To track the status of a configuration process.

For these situations, we recommend that you associate a CreationPolicy attribute with the wait condition so that you don't have to use a wait condition handle. For more details please refer to our public document

Below is the sample Cloudformation template -

Parameters:
  InstanceKey:
    Type: 'AWS::EC2::KeyPair::KeyName'
Resources:
  DBEC2Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: ami-xxxxxxxxxxxx
      KeyName: !Ref InstanceKey
      InstanceType: m5.large
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup
      UserData: !Base64 
        'Fn::Sub': |
          <powershell>
            # START LOG. 
            $lastexitcode = 0       
            $timestamp = Get-Date -Format yyyyMMdd-hhmm
            write " Date: $timestamp."
            #  CALL CUSTOM UTILITY
            write "running CustomUtility."
            cfn-signal.exe -e $lastexitcode --stack ${AWS::StackName}  --resource WaitCondition --region ${AWS::Region}
          </powershell> 
           
  WaitCondition:
    Type: 'AWS::CloudFormation::WaitCondition'
    CreationPolicy:
      ResourceSignal:
        Timeout: PT5M
        Count: 1
  InstanceSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: Allow ssh on the instance
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3389
          ToPort: 3389
          CidrIp: x.x.x.x/x
AWS
支援工程師
已回答 9 個月前
  • Thank you for your help. However, it is not working. As you can see my code, I tried WaitConditionHandle, but it is not linked to any other resource. So, I am not sure, whether there will be any impact. Also, the documentation is not very clear on how to get this working. I have a couple of more questions, though.

    1. In my code, I have cfn-init also. Is it not required?
    2. In the WaitCondition, don't we need a DependsOn property on the EC2 Instance

您尚未登入。 登入 去張貼答案。

一個好的回答可以清楚地回答問題並提供建設性的意見回饋,同時有助於提問者的專業成長。

回答問題指南