Search code examples
aws-lambdaamazon-iamaws-code-deploy

Resolving status callback in AWS codedeploy hook


I receive this error while running codedeploy

enter image description here

This is my appspec.yaml file

version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws:ecs:ap-southeast-1:xxx:task-definition/xxxx-def:latest"
        LoadBalancerInfo:
          ContainerName: "yyyyy"
          ContainerPort: 80
# Optional properties
        PlatformVersion: "LATEST"
        NetworkConfiguration:
          AwsvpcConfiguration:
            Subnets: ["subnet-xxx","subnet-yyy"]
            SecurityGroups: ["sg-zzz"]
Hooks:
  - BeforeInstall: "drush-updb"

And this is what drush-updb does in AWS lambda

def lambda_handler(event,context):
    client = boto3.client('ecs')
    response = client.run_task(
        overrides={
            'containerOverrides': [
            {
                'name': 'AAA-BBB',
                'command': [
                    "ccdd"
                ],
            }
        ]
        }
    )
    return {
        'statusCode': 200,
        'body': str(response)
    }

And lastly below is the IAM to run the code deploy.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ecs:DescribeServices",
                "ecs:CreateTaskSet",
                "ecs:UpdateServicePrimaryTaskSet",
                "ecs:DeleteTaskSet",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticloadbalancing:DescribeListeners",
                "elasticloadbalancing:ModifyListener",
                "elasticloadbalancing:DescribeRules",
                "elasticloadbalancing:ModifyRule",
                "lambda:InvokeFunction",
                "cloudwatch:DescribeAlarms",
                "sns:Publish",
                "s3:*"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:PassRole"
            ],
            "Effect": "Allow",
            "Resource": "*",
            "Condition": {
                "StringLike": {
                    "iam:PassedToService": [
                        "ecs-tasks.amazonaws.com"
                    ]
                }
            }
        }
    ]
}

I do have a status code for the return callback based on this link but it doesnt seems to work. So what kind of callback does codedeploy accepts?


Solution

  • I managed to resolve the issue. I need to explicitly invoke codedeploy.putLifecycleEventHookExecutionStatus after the run_task statement.

    So the lambda function looks like this

    def lambda_handler(event,context):
        client = boto3.client('ecs')
        response = client.run_task(
            overrides={
                'containerOverrides': [
                {
                    'name': 'AAA-BBB',
                    'command': [
                        "ccdd"
                    ],
                }
            ]
            }
        )
        if response:
            status='Succeeded'
    
        try:
            codedeploy.put_lifecycle_event_hook_execution_status(
                deploymentId=event["DeploymentId"],
                lifecycleEventHookExecutionId=event["LifecycleEventHookExecutionId"],
                status=status
            )
            return True
        except ClientError as e:
            print("Unexpected error: %s" % e)
            return False