Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CodeDeploy can't find my AWS Lambda Function

I have an Issue with CodeDeploy and AWS Lambda when they work inside AWS CodePipeline. This is my setup:

  1. Source GitHub
  2. AWS CodeBuild
  3. AWS CodeDeploy

The Issue

Step 1. and 2. work without a problem, but when it comes to CodeDeploy I get the following error:

Action execution failed BundleType must be either YAML or JSON

If I unzip the Artifact generated by CodeBuild all the files are in place.

If I try to manually deploy to AWS Lambda from CodeDeploy I then get a different message...

Deployment Failed The deployment failed because either the target Lambda function FUNCTION_NAME does not exist or the specified function version or alias cannot be found

This is very confusion as to which Error message is valid, or if they are the same but have a different Error message.

The Setup

The ARN of the function is:

arn:aws:lambda:us-east-1:239748505547:function:email_submition

The ARN for the Alias is:

arn:aws:lambda:us-east-1:239748505547:function:email_submition:default

And my appspec.yml file has the following content

version: 0.0
Resources:
  - email_submition:
      Type: AWS::Lambda::Function
      Properties:
        Name: "email_submition"
        Alias: "default"
        CurrentVersion: "1"
        TargetVersion: "2"

And the folder structure of the project is:

.gitignore
appspec.yml
buildspec.yml
index.js
README.md

Question

What am I missing in this configuration?

like image 421
David Gatti Avatar asked Jan 28 '18 15:01

David Gatti


People also ask

What should be checked first when an AWS CodeDeploy deployment fails?

Here's the steps I would take: Confirm that you installed the CodeDeploy agent. Confirm that you've created the IAM service role. Confirm that you have the IAM Instance Profile and that it's associated with the instance.

How do I download Lambda function code?

Navigate over to your lambda function settings and on the top right you will have a button called " Actions ". In the drop down menu select " export " and in the popup click "Download deployment package" and the function will download in a . zip file. Click on the function.


2 Answers

So really this should be a comment not an answer. I do not have 50 rep yet so it's here.

I am having the same issues as you. I'm not sure if you found a solution or not. I was able to successfully execute a deployment with the following appspec.yml:

version: 0.0
Resources:
    - mylambdafunction:
        Type: AWS::Lambda::Function
        Properties:
            Name: "mylambdafunction"
            Alias: "staging"
            CurrentVersion: "2"
            TargetVersion: "3"

Both the current version and target version had to exist before CodeDeploy would work. Of course I've tested this by doing a manual deployment.

I think what is needed here is something that actually updates the code and creates a new version. Which is what I would have thought CodeDeploy would do.

Edit: Further research has yielded information about CodePipeline I hadn't realized.

Per here it looks like to run through the Pipeline you need your buildspec, appspec, and a cft. The reason the pipeline fails is because you need to include a CloudFormation Template for the lambda function, this is what deploys the actual code. The appspec.yml is there to migrate traffic from the old version to the new version but the cft is what does the deployment of new code.

Edit2: This example app got me squared away. Use CodeBuild to build your app but also to generate your CFT for doing actual deployment. This means you build your CFT with the lambda resource. This removes appspec completely from the resources and instead you use a CFT to define the Lambda function. Here is a link to the SAM docs.

like image 101
StoneyD Avatar answered Oct 03 '22 20:10

StoneyD


I can not help you with the CodeBuild part as I use a 3rd party CI solution but maybe I can help with the rest.

I think there is a mistake in the AWS documentation as I've never been able to get this to work either. They say to call "aws deploy push" on the command line and give it your appspec.yml file instead of a zip for Lambda, but no matter what you do, you will always get the error:

Action execution failed BundleType must be either YAML or JSON

I think this is because push automatically calls "register-application-revision" after it uploads. If you split this into separate parts, this will work.

Your appspec.yml should look like the

version: 0.0 Resources: - YourFunctionName: Type: "AWS::Lambda::Function" Properties: Name: "YourFunctionName" Alias: "YourFunctionNameAlias" CurrentVersion: "CurrentAliasVersionGoesHere" TargetVersion: "NewlyPublishedVersionGoesHere"

The version you use should be the version the current alias is attached to. The target version should be the new version you just published (see below) This part still confusing me a bit. I don't understand why it can't figure out what the current version the alias is pointing to by itself.

Also, note that you can always just upload new code for your Lambda code with update-function-code and it will overwrite the latest version. Or you can publish which will create a new version and always just call the latest version. CodeDeploy is only necessary if you want to do some fancy gradually deployment or have different versions for test and live code.

I'd try the following:

  1. Publish your lambda function:

aws lambda update-function-code --function-name YourFunction --zip-file fileb://~/your-code.zip --publish

Take note of the version number it created

  1. Upload your appspec.yml file to S3

aws s3 cp appspec.yml s3://your-deploy-bucket/your-deploy-dir/appspec.yml

  1. Register your application revision:

aws deploy register-application-revision --application-name YourApplcationName --s3-location bucket=your-deploy-bucket,key=your-deploy-dir/appspec.yml,bundleType=YAML

From the CLI this won't appear to do anything, but it did.

  1. Get the application revision to make sure it worked

aws deploy get-application-revision --application-name YourApplcationName --s3-location bucket=your-deploy-bucket,key=your-deploy-dir/appspec.yml,bundleType=YAML

  1. Create a deployment to deploy your code

aws deploy create-deployment --s3-location bucket=your-deploy-bucket,key=your-deploy-dir/appspec.yml,bundleType=YAML

like image 22
Mike Avatar answered Oct 03 '22 20:10

Mike