AMI Using the Lambda in Cloud formation Issue

0

AMIFunction: Type: AWS::Lambda::Function Properties: Handler: index.handler Role: !GetAtt LambdaExecutionRole.Arn Code: ZipFile: !Sub | import logging import cfnresponse import json import boto3 from threading import Timer from botocore.exceptions import WaiterError

        logger = logging.getLogger()
        logger.setLevel(logging.INFO)

        def handler(event, context):

          ec2 = boto3.resource('ec2')
          physicalId = event['PhysicalResourceId'] if 'PhysicalResourceId' in event else None

          def success(data={}):
            cfnresponse.send(event, context, cfnresponse.SUCCESS, data, physicalId)

          def failed(e):
            cfnresponse.send(event, context, cfnresponse.FAILED, str(e), physicalId)

          logger.info('Request received: %s\n' % json.dumps(event))

          try:
            instanceId = event['ResourceProperties']['InstanceId']
            if (not instanceId):
              raise 'InstanceID required'

            if not 'RequestType' in event:
              success({'Data': 'Unhandled request type'})
              return
              
            if event['RequestType'] == 'Delete':
              if (not physicalId.startswith('ami-')):
                raise 'Unknown PhysicalId: %s' % physicalId
              
              ec2client = boto3.client('ec2')
              images = ec2client.describe_images(ImageIds=[physicalId])
              for image in images['Images']:
                ec2.Image(image['ImageId']).deregister()
                snapshots = ([bdm['Ebs']['SnapshotId'] 
                              for bdm in image['BlockDeviceMappings'] 
                              if 'Ebs' in bdm and 'SnapshotId' in bdm['Ebs']])
                for snapshot in snapshots:
                  ec2.Snapshot(snapshot).delete()

              success({'Data': 'OK'})
            elif event['RequestType'] in set(['Create', 'Update']):
              if not physicalId:  # AMI creation has not been requested yet
                instance = ec2.Instance(instanceId)
                instance.wait_until_stopped()

                image = instance.create_image(Name="Automatic from CloudFormation stack ${AWS::StackName}")

                physicalId = image.image_id
              else:
                logger.info('Continuing in awaiting image available: %s\n' % physicalId)

              ec2client = boto3.client('ec2')
              waiter = ec2client.get_waiter('image_available')

              try:
                waiter.wait(ImageIds=[physicalId], WaiterConfig={'Delay': 30, 'MaxAttempts': 6})
              except WaiterError as e:
                # Request the same event but set PhysicalResourceId so that the AMI is not created again
                event['PhysicalResourceId'] = physicalId
                logger.info('Timeout reached, continuing function: %s\n' % json.dumps(event))
                lambda_client = boto3.client('lambda')
                lambda_client.invoke(FunctionName=context.invoked_function_arn, 
                                      InvocationType='Event',
                                      Payload=json.dumps(event))
                return

              success({'Data': 'OK'})
            else:
              success({'Data': 'OK'})
          except Exception as e:
            failed(e)
    Runtime: python3.9
    Timeout: 100

for this code getting error as **Failed to receive 1 resource signal(s) within the specified duration ** any solution ?

**lambda log:**Response { "errorMessage": "'ResponseURL'", "errorType": "KeyError", "requestId": "8e439e3f-a409-40d3-aecc-73c37e33ed7d", "stackTrace": [ " File "/var/task/index.py", line 78, in handler\n failed(e)\n", " File "/var/task/index.py", line 20, in failed\n cfnresponse.send(event, context, cfnresponse.FAILED, str(e), physicalId)\n", " File "/var/task/cfnresponse.py", line 19, in send\n responseUrl = event['ResponseURL']\n" ] }

Arfat
gefragt vor 25 Tagen132 Aufrufe
1 Antwort
0

Hi

CloudFormation stack timed out waiting for a signal from the Lambda function creating the AMI.

  • There workaround by increasing the timeout
  • Best way is You can modify this section to send a success signal to CloudFormation after creating the AMI and update the event['PhysicalResourceId'] with the newly created image ID.

Reference : https://github.com/aws-cloudformation/custom-resource-helper

https://hub.alfresco.com/t5/alfresco-platform-services-blog/how-a-lambda-backed-custom-resource-saved-the-day/ba-p/286986

https://medium.com/@angusyuen/cloudformation-custom-resources-be-cautious-of-physicalresourceid-b4a359657c12

profile picture
EXPERTE
GK
beantwortet vor 25 Tagen

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen