Quickstart AWS Lambda Deployment

Quickly get started using Armory CD-as-a-Service to deploy a function to AWS Lambda. Install the CLI, connect to AWS Lambda with a single command, and deploy a sample function. Learn deployment file syntax.

Before you begin

Learning objectives

In this guide, you deploy an AWS Lambda function to four regions in your AWS Lambda account.

  1. Sign up for CD-as-a-Service.
  2. Install the CD-as-as-Service CLI on your Mac, Linux, or Windows workstation.
  3. Create AWS artifacts
    1. Create the IAM Role that CD-as-a-Service assumes to deploy your function.
    2. Create S3 buckets, one for each deployment region, to house your function’s zip files.
    3. Upload the sample function to each S3 bucket.
  4. Create your CD-as-a-Service deployment config file.
  5. Deploy the sample function.
  6. Test the deployed function in the AWS Lambda console.

Sign up for CD-as-a-Service

Access the registration screen to create an account. Fill in the required fields. When you’re done, click Create Account.

When you create your account, CD-as-a-Service does the following:

  • Creates an Organization for your company
  • Creates a Tenant for the Organization
  • Creates a User account with an Organization Admin role for you.

See Identity & Access Management for details.

You may have to log in after creating your account.

The Welcome to Continuous Deployment-as-a-Service Configuration page lists the steps you need to complete to begin using Armory CD-as-a-Service.

Install the CD-as-as-Service CLI

brew tap armory-io/armory
brew install armory-cli

You can install the CLI with a one-line script that does the following:

  1. Fetches the correct Armory Version Manager binary (avm) for your operating system
  2. Installs the AVM binary
  3. Uses the AVM to install the CLI binary (armory)
  4. Adds the AVM and the CLI to the path in your bash or zsh profile

Execute the following script on the machine that has access to your Kubernetes cluster:

curl -sL go.armory.io/get-cli | bash

After installation completes, you should start a new terminal session or source your profile.

  1. Download the AVM for your operating system and CPU architecture. You can manually download it from the repo or use the following command:

    curl -LO https://github.com/armory/avm/releases/latest/download/avm-<os>-<architecture>
    

    For example, the following command downloads the latest version for macOS (Darwin):

    curl -LO https://github.com/armory/avm/releases/latest/download/avm-darwin-amd64
    

    You can see the full list of available releases in the repo.

    Note: You can also download AVM from the releases AWS S3 bucket:

    curl -LO https://armory-cli-releases.s3.us-west-2.amazonaws.com/avm/latest/avm-darwin-amd64
    
  2. Give AVM execute permissions. For example (on macOS):

    chmod +x avm-darwin-amd64
    
  3. Confirm that /usr/local/bin is on your PATH:

    echo $PATH
    

    The command returns your PATH, which should now include /usr/local/bin/.

  4. Rename the AVM binary to avm and move it to /usr/local/bin, which is on your PATH. For example (on macOS):

    mv avm-darwin-amd64 /usr/local/bin/avm
    
  5. Run the following command to install the CLI:

    avm install
    

    The command installs the CLI and returns a directory that you need to add to your path, such as /Users/milton/.avm/bin.

    If you get an developer cannot be identified error when trying to run AVM, you must allow AVM to run.

    Show me how to allow AVM to run.

    On macOS, go to System Preferences > Security & Privacy > General and click Allow Anyway.

    For more information, see the macOS documentation about how to open a Mac app from an unidentified developer.


  6. Add the directory that AVM returned when you ran avm install to your path.

    Show me how to add the directory.

    You can either add the path directly to /etc/paths or add it to your shell profile. The following steps describe how to add it to your shell profile:

    1. Edit the resource file for your shell, such as .bashrc, .bash_profile, or .zshrc. For example:

      vi ~/.bashrc
      
    2. In the file, find the line for the PATH that your resource file exports. They follow the format export PATH=$HOME/bin:/usr/local/bin:$PATH.

    3. Insert the path provided by AVM (such as /Users/brianle/.avm/bin) before the ending $PATH. The line should look similar to this:

      export PATH=$HOME/bin:/usr/local/bin::/Users/milton/.avm/bin:$PATH
      
    4. Save the file.

    5. Reload your terminal, open a new session, or source your terminal profile file (for example, source .bash_profile).


  7. Run the following command to verify that the CLI is installed:

    armory
    

    The command returns basic information about the CLI, including available commands.

For the AVM or the CLI, you can use the -h flag for more information about specific commands.

Armory provides the CD-as-a-Service CLI as a Docker image.

docker pull armory/armory-cli

Download the latest armory-cli Windows executable from the repo Releases page. Install on the machine that has access to your Kubernetes cluster.

Log in with the CLI

armory login

Confirm the device code in your browser when prompted. Then return to this guide.

Create the Armory IAM role

In order to deploy AWS resources, CD-as-a-Service needs to create a Trust Relationship in your AWS account by adding an IAM role. CD-as-a-Service assumes this role to execute deployments on your behalf. The Armory CLI provides a function that creates an AWS CloudFormation Stack with an IAM Role, by default named ArmoryRole. You need to create a Stack in each AWS Account you want to deploy your AWS Lambda functions to.

  1. In your default browser, log in to your AWS Account. You must have permissions to configure IAM roles.

  2. In your terminal, execute the following:

    armory aws create-role
    

    Type Y in the terminal to continue with Stack creation. This opens your browser to the CloudFormation page of your AWS Console. You complete the rest of this process in your browser.

  3. Review the resources that CD-as-a-Service is creating in your AWS account. The default IAM Role name is ArmoryRole.

  4. Click Create on the AWS CloudFormation page and wait for Stack creation to finish.

  5. After the CloudFormation Stack creation finishes, locate the created role ARN in the Outputs section. You can find it under the key RoleArnOutput. Make note of the ARN since you use it in your deployment config file.

Create S3 buckets

You need to store your AWS Lambda function as a zip file in an S3 bucket, and S3 bucket needs to be in the same region you deploy to. For this guide, you are going to deploy the AWS Lambda function to four regions so you need to create four buckets:

RegionBucket Name
us-east-1armory-demo-east-1
us-east-2armory-demo-east-2
us-west-1armory-demo-west-1
us-west-2armory-demo-west-2

Use the default values for the rest of the fields.

After you have finished, you should have four buckets.

Upload the AWS Lambda function to your buckets

Armory provides a basic AWS Lambda function called just-sweet-potatoes for you to deploy.

Expand to see the code

index.js has the following content:

exports.handler = async (event) => {
    
  const randomFact = potatolessFacts[Math.floor(Math.random() * potatolessFacts.length)];

  // Prepare the response
  const response = {
    statusCode: 200,
    body: randomFact,
  };

  return response;
};

const potatolessFacts = [
    "Sweet potatoes are a great source of vitamin A, which is important for vision health.",
    "There are over 400 varieties of sweet potatoes around the world.",
    "Sweet potatoes are not related to regular potatoes; they belong to the morning glory family.",
    "Sweet potatoes are high in fiber, making them good for digestion.",
    "Sweet potatoes come in different colors, including orange, purple, and white.",
    "Sweet potatoes are one of the oldest vegetables known to man.",
    "North Carolina is the largest producer of sweet potatoes in the United States.",
    "Sweet potatoes are often used in Thanksgiving dishes like casseroles and pies.",
  ];
  1. Download the function zip file.
  2. Upload the file to each of your armory-demo-lambda-deploy S3 buckets.
  3. Make a note of each bucket’s S3 path to the lambda function. The paths should be:
  • s3://armory-demo-east-1/just-sweet-potatoes.zip
  • s3://armory-demo-east-2/just-sweet-potatoes.zip
  • s3://armory-demo-west-1/just-sweet-potatoes.zip
  • s3://armory-demo-west-2/just-sweet-potatoes.zip

Create your deployment config file

First create a file called deploy.yaml with the following contents:

1
2
3
4
version: v1
kind: lambda
application: just-sweet-potatoes
description: A sample function for deployment using CD-as-a-Service
  • kind: lambda tells CD-as-a-Service the deployment type
  • application: This is the unique name of your deployment and appears in the Deployments list.
  • description: Brief description of your function (optional)

Add a canary strategy

A strategy defines how CD-as-a-Service deploys your AWS Lambda function to a target.

A canary strategy is a linear sequence of steps. The setWeight step defines the ratio of traffic between function versions.

Add a basic canary strategy with a single step that sets the weight to 100. This routes 100% of traffic to the new version. You use this allAtOnce strategy to initially deploy your function to AWS Lambda when the function does not exist in the AWS Lambda console. This strategy is also useful in non-production environments such as staging.

1
2
3
4
5
6
strategies:
  allAtOnce:
    canary:
      steps:
        - setWeight:
            weight: 100

Add targets

In CD-as-a-Service, a target is an (AWS Account, region) pair.

flowchart LR
    A[dev] --> B[staging]
    B --> C[prod-west-1]
    B --> D[prod-west-2]

When deploying to multiple targets, you can specify dependencies between targets using the constraints.dependsOn field. CD-as-a-Service deploys your AWS Lambda function from your S3 bucket to the dev target first. You want a linear, success-dependent progression from dev to prod, so there is a dependsOn constraint for staging and prod targets. staging depends on dev and the prod targets depend on staging.

Add the four targets, one in each region:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
targets:
  dev:
    account: <account-name>
    deployAsIamRole: <armory-role-arn>
    region: us-east-1
    strategy: allAtOnce
  staging:
    account:  <account-name>
    deployAsIamRole: <armory-role-arn>
    region: us-east-2
    strategy: allAtOnce
    constraints:
      dependsOn:
        - dev
  prod-west-1:
    account:  <account-name>
    deployAsIamRole: <armory-role-arn>
    region: us-west-1
    strategy: allAtOnce
    constraints:
      dependsOn:
        - staging
  prod-west-2:
    account:  <account-name>
    deployAsIamRole: <armory-role-arn>
    region: us-west-2
    strategy: allAtOnce
    constraints:
      dependsOn:
        - staging

Replace:

  • <account-name> with the name of your AWS Account, such as armory-docs-dev
  • <armory-role-arn> with the ARN of the role you created in the Create the Armory IAM role section

Add AWS Lambda artifacts

In this section, you declare your AWS Lambda function artifacts. You have an entry for each deployment region.

The function is named just-sweet-potatoes in each S3 bucket, but the functionName is unique for each entry in the artifacts collection. For this guide, the target name is appended to the function’s name to create the functionName value for each entry.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
artifacts:
  - functionName: just-sweet-potatoes-dev
    path: s3://armory-demo-east-1/just-sweet-potatoes.zip
    type: zipFile
  - functionName: just-sweet-potatoes-staging
    path: s3://armory-demo-east-2/just-sweet-potatoes.zip
    type: zipFile
  - functionName: just-sweet-potatoes-prod-west-1
    path: s3://armory-demo-west-1/just-sweet-potatoes.zip
    type: zipFile
  - functionName: just-sweet-potatoes-prod-west-2
    path: s3://armory-demo-west-2/just-sweet-potatoes.zip
    type: zipFile

Add provider options

This section defines options specific to the cloud provider to which you are deploying. You need to populate provider options for each deployment target.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
providerOptions:
  lambda:
    - target: dev
      name: just-sweet-potatoes-dev      
      runAsIamRole: <execution-role-arn>
      handler: index.handler
      runtime: python3.10
    - target: staging
      name: just-sweet-potatoes-staging      
      runAsIamRole: <execution-role-arn>
      handler: index.handler
      runtime: python3.10
    - target: prod-west-1
      name: just-sweet-potatoes-prod-west-1      
      runAsIamRole: <execution-role-arn>
      handler: index.handler
      runtime: python3.10
    - target: prod-west-2
      name: just-sweet-potatoes-prod-west-2      
      runAsIamRole: <execution-role-arn>
      handler: index.handler
      runtime: python3.10
  • target: CD-as-a-Service deployment target name
  • name: This is the same value as artifacts.functionName and trafficManagement.alias.functionName for the target region. This function name appears on your AWS Lambda Functions list page.
  • runAsIamRole: Replace <execution-role-arn> with the ARN of your AWS Lambda execution role, which is not the ArmoryRole ARN.
  • handler: The function’s handler method, such as index.handler. This value is written to the Runtime settings section in the AWS Lambda function details page.
  • runtime: runtime identifier, such as python3.22 or nodejs18.x. This value is written to the Runtime settings section in the AWS Lambda function details page.

Deploy the sample function

First deployment

Start your deployment using the CLI:

armory deploy start -f deploy.yaml

You can use the link provided by the CLI to observe your deployment’s progression in the CD-as-a-Service Console. CD-as-a-Service deploys your resources to dev. Once those resources have deployed successfully, CD-as-a-Service deploys to staging and then prod.

Second deployment

CD-as-a-Service is designed to help you build safety into your app deployment process. It does so by giving you declarative levers to control the scope of your deployment.

CD-as-a-Service has four kinds of constraints that you can use to control your deployment:

You can use these constraints between environments and within environments. During your next deployment, you want to issue a manual approval before deploying to to the prod targets. Add to your staging target an afterDeployment constraint with a manual judgment:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
targets:
  dev:
    account: <account-name>
    deployAsIamRole: <armory-role-arn>
    region: us-east-1
    strategy: allAtOnce
  staging:
    account:  <account-name>
    deployAsIamRole: <armory-role-arn>
    region: us-east-2
    strategy: allAtOnce
    constraints:
      dependsOn:
        - dev
      afterDeployment:
        - pause:
            untilApproved: true
  prod-west-1:
    account:  <account-name>
    deployAsIamRole: <armory-role-arn>
    region: us-west-1
    strategy: allAtOnce
    constraints:
      dependsOn:
        - staging
  prod-west-2:
    account:  <account-name>
    deployAsIamRole: <armory-role-arn>
    region: us-west-2
    strategy: allAtOnce
    constraints:
      dependsOn:
        - staging

Start your second deployment using the CLI:

armory deploy start -f deploy.yaml

Use the link provided by the CLI to observe your deployment’s progression in the CD-as-a-Service Console.

In this second deployment, you see that CD-as-a-Service paused deployment to prod. Click the Approve button in the staging node to continue deployment.

Test the deployed function

Go to the us-east-1 Lamba section of your AWS Account. You should see your deployed just-sweet-potatoes-dev function there.

  1. Click just-sweet-potatoes-dev to open the function’s details page.

  2. Click the Test tab.

  3. Click the Test button in the Test event section to test the function.

  4. Expand the Details section to see the test results.

Clean up

  1. Delete the deployed AWS Lambda functions from each region.
  2. Delete the AWS Lambda zip files from each S3 bucket. Delete each S3 bucket.
  3. Delete the CloudFormation Stack. This also deletes the associated IAM Role.

What’s next


Last modified November 27, 2023: (803ecce)