AWS Lambda Deployment Overview

Learn what an Armory CD-as-a-Service deployment to AWS Lambda is, how CD-as-a-Service connects to your AWS Account, and how deployment works.

What a deployment is

A deployment encompasses the artifacts, configuration, and actions that deliver your code to remote environments. You can configure a deployment to deliver your AWS Lambda function to a single environment or multiple environments, either in sequence or in parallel depending on your deployment configuration.

You define your CD-as-a-Service deployment configuration in a YAML file, which you store within your source control, enabling code-like management. You trigger deployments using the Armory CLI, either from your CI system or your workstation.

How deployment works

CD-as-a-Service starts a deployment with a target environment, which is a combination of AWS account and region. The first target in a deployment does not depend on other targets. Then deployment progresses through the steps, conditions, and targets defined in your deployment process.

CD-as-a-Service automatically rolls back when:

  • There is an error deploying your AWS Lambda function
  • Deployment fails to finish within 30 minutes
  • A webhook fails
  • You configured your retrospective analysis step to automatically rollback
  • A user fails to issue a configured manual approval within a specified time frame
  • A deployment target constraint is not met

How CD-as-a-Service performs rollbacks:

  • If you have specified an AWS Lambda alias to use for routing traffic, CD-as-a-Service points the alias to the old version.
  • If you have not specified an alias to use for routing traffic, CD-as-a-Service publishes a new version with the old configuration, so that the live version of your AWS Lambda function has the same configuration as before the deployment started.

How CD-as-a-Service integrates with AWS

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.

You need to store your function zip files in an S3 bucket, and the S3 bucket should be in the same region you deploy to (this is an AWS limitation). For example, if you plan to deploy to three regions, you need three S3 buckets, one for each region. CD-as-a-Service deploys your AWS Lambda function’s archive from your S3 bucket.

AWS AccountsArmoryRoleRegionsS3 Buckets
1144
4411
4444
2266

For each AWS Lambda function you want to deploy, CD-as-a-Service needs the following:

  1. ArmoryRole ARN
  2. Region
  3. S3 path to the function zip file
  4. The ARN of your AWS Lambda execution role
  5. Your function’s runtime and handler method

This basic example deploys one function to one region in one account:

version: v1
kind: lambda
application: potatoless-facts
description: awsLambda
targets:
  us-east-1:
    account: armory-docs-dev
    deployAsIamRole: arn:aws:iam::111111111111:role/ArmoryRole
    region: us-east-1
    strategy: allAtOnce
strategies:
  allAtOnce:
    canary:
      steps:
        - setWeight:
            weight: 100
artifacts:
  - functionName: potatolessFacts
    path: s3://armory-docs-dev-us-east-1/potatolessfacts-justsweetpotatoes.zip
    type: zipFile
providerOptions:
  lambda:
    - name: potatolessFacts
      target: us-east-1
      runAsIamRole: arn:aws:iam::111111111111:role/lamdaExecutionRole
      handler: index.handler
      runtime: nodejs18.x

How to trigger a deployment

Define your deployment

With CD-as-a-Service, you declare your deployment configuration outcome in a YAML file.

For an AWS Lambda deployment, you only need to provide the following pieces of information:

  • The target you want to deploy to
  • The AWS Lambda function you want to deploy
  • Provider options for that AWS Lambda function
  • The canary strategy you want to use for the deployment

Elements of a deployment

Targets

Within a deployment, you define targets that are equivalent to the environments you are deploying to - a unique combination of AWS account (ArmoryRole ARN) and region.

The following example has multiple region-based targets in a single AWS account:

targets:
  Prod-East-1:
    account: armory-prod
    deployAsIamRole: arn:aws:iam::111111111111:role/ArmoryRole
    region: us-east-1
    strategy: allAtOnce
  Prod-West-2:
    account: armory-prod
    deployAsIamRole: arn:aws:iam::111111111111:role/ArmoryRole
    region: us-west-2
    strategy: allAtOnce

This example has targets that are separate AWS Accounts:

targets:
  Lab:
    account: armory-lab
    deployAsIamRole: "arn:aws:iam::111111111111:role/ArmoryRole"
    region: us-west-2
    strategy: rollingDeployment
  Staging:
    account: armory-core
    deployAsIamRole: "arn:aws:iam::222222222222:role/ArmoryRole"
    region: us-west-2
    strategy: rollingDeployment
  Audit:
    account: armory-audit
    deployAsIamRole: "arn:aws:iam::333333333333:role/ArmoryRole"
    region: us-west-2
    strategy: rollingDeployment
  ITSec:
    account: armory-itsec
    deployAsIamRole: "arn:aws:iam::444444444444:role/ArmoryRole"
    region: us-west-2
    strategy: rollingDeployment

Target constraints

You can also configure your deployment targets to use constraints that prevent a deployment from beginning or completing until certain conditions are met. For example, you can configure your deployment to wait for your code to be deployed to your staging environment before promoting that code to production.

CD-as-a-Service offers you multiple constraint options including:

  • dependsOn: Use dependsOn to specify a target deployment that must successfully complete prior to starting this target’s deployment.
  • beforeDeployment: You can use this constraint to implement a checklist of things that need to happen before a target starts deploying. For example, you can use the beforeDeployment constraints with the pause step to require a manual approval.
  • afterDeployment: You can use this constraint to prevent downstream deployments from starting until some set of post deployment tasks finishes. For example, you can use this with the runWebhook step to execute a set of end-to-end tests in a staging environment before deploying to production.

This example has multiple targets and illustrates dependsOn, beforeDeployment, and afterDeployment constraints.

targets:
  Lab:
    account: armory-lab
    deployAsIamRole: "arn:aws:iam::111111111111:role/ArmoryRole"
    region: us-west-2
    strategy: rollingDeployment
  Staging:
    account: armory-core
    deployAsIamRole: "arn:aws:iam::222222222222:role/ArmoryRole"
    region: us-west-2
    strategy: rollingDeployment
    constraints:
      dependsOn: 
        - Lab
      afterDeployment:
        - runWebhook:
            name: Integration-Tests
  Audit:
    account: armory-audit
    deployAsIamRole: "arn:aws:iam::333333333333:role/ArmoryRole"
    region: us-west-2
    strategy: rollingDeployment
    constraints:
      dependsOn:
        - Lab
      afterDeployment:
        - runWebhook:
            name: Audit-Analysis
  ITSec:
    account: armory-itsec
    deployAsIamRole: "arn:aws:iam::444444444444:role/ArmoryRole"
    region: us-west-2
    strategy: rollingDeployment
    constraints:
      dependsOn:
        - Lab
      afterDeployment:
        - runWebhook:
            name: Security-Scans            
  Prod-West-2:
    account: armory-prod
    deployAsIamRole: "arn:aws:iam::555555555555:role/ArmoryRole"
    region: us-west-2
    strategy: rollingDeployment
    constraints:
      dependsOn:
        - Staging
        - Audit
        - ITSec
      beforeDeployment:
        - runWebhook:
            name: Send-Slack-Deployment-Approval-Required
        - pause:
            untilApproved: true

Artifacts

An artifact is your AWS Lambda function name and the S3 path to the function’s archive. You should have an entry for each deployment target region. The functionName is unique for each entry in the artifacts collection.

artifacts:
  - functionName: hello-world-python
    path: s3://armory-demos-us-west-2/hello-world-python.zip
    type: zipFile

Provider options

This section is where you provide additional information about your function. Each target has an entry.

providerOptions:
  lambda:
    - target: Lab
      name: hello-world-python
      runAsIamRole:  arn:aws:iam::111111111111:role/LambdaExecutionRole
      handler: lambda_function.lambda_handler
      runtime: python3.10
    - target: Staging
      name: hello-world-python
      runAsIamRole:  arn:aws:iam::222222222222:role/LambdaExecutionRole
      handler: lambda_function.lambda_handler
      runtime: python3.10
    - target: Audit
      name: hello-world-python
      runAsIamRole:  arn:aws:iam::333333333333:role/LambdaExecutionRole
      handler: lambda_function.lambda_handler
      runtime: python3.10
    - target: ITSec
      name: hello-world-python
      runAsIamRole:  arn:aws:iam::444444444444:role/LambdaExecutionRole
      handler: lambda_function.lambda_handler
      runtime: python3.10
    - target: Prod-West-2
      name: hello-world-python
      runAsIamRole:  arn:aws:iam::555555555555:role/LambdaExecutionRole
      handler: lambda_function.lambda_handler
      runtime: python3.10

Be sure to view the AWS Lambda Quickstart and config file reference for additional examples.

Strategies

A deployment strategy is the method by which CD-as-a-Service deploys your changes to a target. Strategies can use different techniques to allow for rapid rollback should a problem be discovered, minimizing the impact of potential issues to a small subset of users. You could also use a strategy optimized for speed.

For AWS Lambda deployments, CD-as-a-Service supports a canary deployment strategy, which involves releasing a new software version to a small subset of users or systems while leaving the majority on the current version. This strategy allows for real-world testing and monitoring of the new version’s performance and stability. If the canary users experience positive results, the new version can be gradually rolled out to a wider audience.

This example routes 100% of traffic to the new version. You’d 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.

strategies:
  allAtOnce:
    canary:
      steps:
        - setWeight:
            weight: 100

For subsequent deployments, you could use a canary strategy that splits traffic. CD-as-a-Service uses your function’s AWS Lambda alias when splitting traffic between versions.

This example is for deployment to multiple regions in a single AWS Account. The canary strategy splits traffic. You declare your function’s alias in the trafficManagement section. There are two entries in the trafficManagement section since both staging and prod targets use the traffic split strategy.

This example assumes you have already created an alias named v2.

targets:
  prod-us-east-1:
    account: armory-docs-dev
    region: us-east-1
    deployAsIamRole: "arn:aws:iam::111111111111:role/ArmoryRole"
    strategy: trafficSplit
  prod-us-east-2:
    account: armory-docs-dev
    region: us-east-2
    deployAsIamRole: "arn:aws:iam::111111111111:role/ArmoryRole"
    strategy: trafficSplit
strategies:
  trafficSplit:
    canary:
      steps:
        - setWeight:
            weight: 25
        - pause:
            untilApproved: true
        - setWeight:
            weight: 100
artifacts:
  - functionName: just-sweet-potatoes-us-east-1
    path: s3://armory-demo-east-1/just-sweet-potatoes.zip
    type: zipFile
  - functionName: just-sweet-potatoes-us-east-2
    path: s3://armory-demo-east-2/just-sweet-potatoes.zip
    type: zipFile
providerOptions:
  lambda:
    - name: just-sweet-potatoes-us-east-1
      target: prod-us-east-1
      runAsIamRole: "arn:aws:iam::111111111111:role/LambdaExecutionRole"
      handler: index.handler
      runtime: nodejs18.x
    - name: just-sweet-potatoes-us-east-2
      target: prod-us-east-2
      runAsIamRole: "arn:aws:iam::111111111111:role/LambdaExecutionRole"
      handler: index.handler
      runtime: nodejs18.x
trafficManagement:
  - targets: ['prod-us-east-1']
    alias:
      - functionName: just-sweet-potatoes-us-east-1
        aliasName: v2
  - targets: ['prod-us-east-2']
    alias:
      - functionName: just-sweet-potatoes-us-east-2
        aliasName: v2

What’s next


Last modified December 7, 2023: (ce17eae)