Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS CodeDeploy is not able to deploy lambda function

I have a simple AWS CodePipeline with few steps.

  1. AWS CodeCommit (provide output "SourceCode")
  2. AWS CodeBuild (input "SourceCode", npm install, npm run-scripts build, output "FinalCode")
  3. AWS CodeDeploy (input "FinalCode", deploy to Lambda function)

And really, I try since few hours to get this F*** CodeDeploy working. Its not possible. I cant believe -.-

So we can take a look at the AWS CodeDeploy step. The mistake must be there. I tried different scenarios with CodeBuild. Output with artifacts.zip and appspecs.yml and something else.


CodeDeploy says:

Action execution failed
BundleType must be either YAML or JSON

When its triggered by CodePipeline.

I download the File from CodePipeline-S3-Bucket which is the input of the CodeDeploy. It contains all the needed files.

node_modules, appspec.yml and index.js

I don't know how to tell the pipeline to take this appspec.yml.

The interesting thing is, if I deploy it manually, its working. So CodeDeploy is not able to find the appspec.yml I think.

example of working scenario if I add appspec.yml manually

Here you can see.

Example of working result

But if I think about it, this makes no sense. Because in this app spec editor I cant specify the path to the ZIP archive I want to deploy.

Do anyone know how to finalize this last step?

I cant believe that its so hard :-D I was able to set up CodeCommit very easily. CodeBuild was very easy with buildspec.yml, too. And now Im not able to deploy because of ignored appspec.yml or something like that...

like image 370
Patrick Avatar asked Aug 06 '18 22:08

Patrick


People also ask

Can CodeDeploy deploy Lambda?

AWS CodeDeploy deploys the Lambda function revision you specified. The traffic is shifted to your Lambda function revision using the deployment AppSpec file you chose when you created your application. For more information, see Create a deployment with CodeDeploy.

What are the three different ways you can deploy your code to Lambda?

To deploy your function's code, you upload the deployment package from Amazon Simple Storage Service (Amazon S3) or your local machine. You can upload a . zip file as your deployment package using the Lambda console, AWS Command Line Interface (AWS CLI), or to an Amazon Simple Storage Service (Amazon S3) bucket.

How do you deploy a Lambda in AWS?

To deploy your function's code, you upload the deployment package from Amazon Simple Storage Service (Amazon S3) or your local machine. You can upload a . zip file as your deployment package using the Lambda console, AWS Command Line Interface (AWS CLI), or to an Amazon Simple Storage Service (Amazon S3) bucket.


2 Answers

I have the same problem. I spent literally days on this and I think there is something wrong with CouldFormatoin's AWS::CodeDeploy::DeploymentGroup

I have this yaml file in s3://my-backet-for-lambda-deployment/appspec.yaml:

appspec.yaml

version: 0.0
Resources:
  - my-lambda-app-MyLambdaApp-157EXYJT40C0U:
      Type: AWS::Lambda::Function
      Properties:
        Name: arn:aws:lambda:us-east-1:292285124316:function:my-lambda-app-MyLambdaApp-157EXYJT40C0U 
        Alias: production
        CurrentVersion: 8 
        TargetVersion: 9 

The appspec.yaml is correct, as I can manually specify it's location in S3 using the console and everything works. So I'm totally sure that the appspec.yaml is not at fault here.

Problem

I use the following AWS::CodeDeploy::DeploymentGroup

  MyDeploymentGroup:
    Type: AWS::CodeDeploy::DeploymentGroup
    Properties:
      ApplicationName: !Ref MyCodeDeployApp
      Deployment: 
        IgnoreApplicationStopFailures: false
        Revision:       
            RevisionType: S3
            S3Location: 
              Bucket: my-backet-for-lambda-deployment
              Key: appspec.yaml
              BundleType: YAML              
      DeploymentConfigName: CodeDeployDefault.LambdaAllAtOnce
      DeploymentStyle: 
        DeploymentOption: WITH_TRAFFIC_CONTROL
        DeploymentType: BLUE_GREEN
      ServiceRoleArn: !ImportValue MyCodeDeployRoleArn

Stack creation of the above resource fails with Property Deployment cannot be specified.

Workaround

I couldn't found any solution to this purely based on CloudFormatoin. So what I did was to create DeploymentGroup without defining Deployment, and then use CLI or boto3 to start the deployment.

Resources:

  MyCodeDeployApp:
    Type: AWS::CodeDeploy::Application
    Properties: 
      ComputePlatform: Lambda

  # DeploymentGroup without Deployment property
  MyDeploymentGroup:
    Type: AWS::CodeDeploy::DeploymentGroup
    Properties:
      ApplicationName: !Ref MyCodeDeployApp           
      DeploymentConfigName: CodeDeployDefault.LambdaAllAtOnce
      DeploymentStyle: 
        DeploymentOption: WITH_TRAFFIC_CONTROL
        DeploymentType: BLUE_GREEN
      ServiceRoleArn: !ImportValue MyCodeDeployRoleArn

Outputs:

  CodeDeployAppName:
    Value: !Ref MyCodeDeployApp

  DeploymentGroupName:
    Value: !Ref MyDeploymentGroup

Once the stack is create I can use bash to start a deployment:

aws deploy create-deployment \
    --application-name ${deployment_app_name} \
    --deployment-group-name ${deployment_group_name} \
    --s3-location bucket=my-backet-for-lambda-deployment,bundleType=YAML,key=appspec.yaml

P.S.

MyCodeDeployRoleArn role is also correct, so its not its fault either:

Resources:

  MyCodeDeployServiceRole:
    Type: AWS::IAM::Role
    Properties: 
      AssumeRolePolicyDocument:                   
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal: {Service: [codedeploy.amazonaws.com]}
            Action: ['sts:AssumeRole']
      Description: Role for deploying lambda
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/service-role/AWSCodeDeployRoleForLambda
      Policies: 
        - PolicyName: MyS3GetObjectPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: 
                  - s3:Get*
                  - s3:List*
                Resource: '*'            


Outputs:

  CodeDeployRoleArn:
    Value: !GetAtt MyCodeDeployServiceRole.Arn
    Export: 
      Name: MyCodeDeployRoleArn
like image 134
Marcin Avatar answered Sep 26 '22 08:09

Marcin


Hi @Patrick it sounds like there are a few things going on here.

  1. As @Putnik mentioned, in the picture YAML should be selected, but I don't think the picture is of the problem deployment.

  2. A Lambda deployment only needs an 'appspec file. So doing it through the console does not require customers to add a zip unless their appspec is in another repository (S3). The pictures posted make it look like your manual deployment test used a raw string appspec that was typed into the appspec file editor. (If you want to use a .zip, change the Revision Location to the S3 option.)

  3. It is not recognizing .yml as .yaml. I will look into this. For now, a workaround is to change the extension of your file to .yaml.

like image 40
annamataws Avatar answered Sep 25 '22 08:09

annamataws