Building a Lambda Template
This guide is designed to walk you through adding resources to the blank template to support an AWS Lambda patterned extension, in order to clarify how CDK-Cosmos works. We will be creating a lambda behind an ALB within a VPC to create a private site.
lib/ci-cd-solar-system.ts
You will need to import AWS s3 bucket and StandardPipeline from the CDK-Cosmos building blocks.
To the exports, you will need to add a lambda bucket and a standard pipeline. Currently recommending standard pipeline for lambda, which requires the use of a Makefile in your app code, but in future there may be a custom lambda pipeline.
Inside the constructor, add the below code after super();
. StandardPipeline provides a default build spec (buildSpec: StandardPipeline.DefaultBuildSpec()
to use), but we're passing a custom one to build the lambda function.
This section is optional but recommended. The template includes a function to allow you to add discrete stages to your cdk pipeline to deploy individual stacks by referencing the function in bin/main.ts
. The below function allows you to add stages to your standard pipeline. If desired, add this code below addCdkDeployEnvStageToCdkPipeline()
, within the export
statement.
lib/cosmos.ts
This file sets up the Code Repository (AWS CodeCommit) and Code Bucket (s3) for your extension.
Add the following imports:
Replace the export function with the below code.
bin/galaxy.ts
This file will remain unchanged, as we don't need to create any resources at the galaxy (account) level. Resources are either scoped to the cosmos (management account) or solar system (dev, test, prod environment etc) level.
lib/solar-system.ts
You will need to import the following constructs:
Add tag to solar system props
Add readonly bucket inside export statement
Add the following inside the constructor, after super();
. Here, you are using the codeBucket from lib/cosmos.ts
and the shared vpc through the portal construct. version state is managed through a CDK Cosmos feature.
Note: This template uses the SsmState construct, which has an active issue in the Cosmos backlog - (Issue #318)[https://github.com/cdk-cosmos/cosmos/issues/318]. Currently, you will need to pass a hardcoded appVersion on the first run of the pipeline so that a parameter is added to the AWS Parameter Store in each solar system. See details below on setting up the sample lambda app.
To add front end you will need a few extra resources:
imports
in constructor
bin/main.ts
As mentioned in the intro, this file instantiates all the resources you have defined in the above files and is where you can design your Cosmos infrastructure, including AWS accounts, stacks and pipeline stages.
Add the following to imports. This is required to update IAM policies to allow cross account access to Cosmos resources
You will need to change the app name from 'Demo' in the below line:
To the cosmos stack (after const cosmos
), add a resource policy to the code bucket. You will need to add all environments as account principals so they can access the zip file of the lambda code, which is stored in the management account.
In this file, you set the environment configuration for each galaxy and then instantiate a galaxy per account. Examples are included in the blank template. Duplicate these and replace the names as needed. It is essential that names match those set in your core CDK-Cosmos, e.g. Dev
must be consistently named.
For each solar system, create a new solar system stack, ensuring the name matches with your core Cosmos. This allows the portal construct to use resources from core cosmos. You will also need to pass app version as a prop.
Important note with solar systems: Currently, solar systems must be commented out in the first run of the bootstrapper. You can then uncomment solar systems, push up your changes and re-run the cdk pipeline. See Getting Started - Extension # Solar Systems for more information.
Optionally, add a deployment stage in the pipeline to target specific solar systems (can pass one or multiple stacks). If not, all stacks will be deployed in the final deploy stage of the pipeline. It is, however, recommended to separate dev and prod as a minimum.
Again optionally, you can also add a separate stage in the CDK pipeline to target specific stacks
As with the solar system, this should be commented out in the first run (as the solar system targeted by this pipeline stage has not yet been created). When you re-run the cdk pipeline, it will change itself to add the new stage. Changes to the pipeline will make it pause, and you will have to re-run it again. This is a property of CodePipeline, and something that may be addressed in future versions of CDK-Cosmos by implementing the new CDK Pipeline construct provided by AWS. In the meantime, the blank template includes an optional CiCd stage in the pipeline, which will allow you to deploy any changes needed to the CiCd infrastructure first and minimise waiting time on additional runs of the pipeline.
Internet connectivity
Lambdas within a VPC cannot by default access the internet. If you require that functionality, please refer to this (AWS guide)[https://aws.amazon.com/premiumsupport/knowledge-center/internet-access-lambda-function/]
Final Steps
At the end of this guide, you should have all the resources needed to upload a lambda function to your bootstrapped extension. You will be able to test it out by uploading the sample lambda app or your own app to the CodeCommit app-*-code-repo that will be created when you bootstrap your extension and running the code pipeline.
Note: This template uses the SsmState construct, which has an active issue in the Cosmos backlog - (Issue #318)[https://github.com/cdk-cosmos/cosmos/issues/318]. Currently, you will need to pass a hardcoded appVersion on the first run of the pipeline so that a parameter is added to the AWS Parameter Store in each solar system. You may also need to manually zip up and push your lambda function the first time, to create the app version parameter. If you are using the sample lambda app, you will be able to use the commands in the Makefile to achieve this:
(Bootstrap)[getting_started_extension.md] the template you have just created
Set versionState to
"1"
inlib/solar-system.ts
const versionState = new SsmState(this, 'VersionState', { name: '/' + this.nodeId('VersionState', '/'), value: 1, });
Clone the sample lambda app and
git set-url remote origin https://your-code-repo
where your-code-repo is the url of the code repository created in the bootstrapping processExport the name of the s3 bucket created in the management account as CODE_BUCKET and the app build
export CODE_BUCKET=app-demo-code-bucket export APP_BUILD_VERSION=1
Use the commands in the Makefile to build, zip & push the sample app up to your repo
make install make build make zip make push
Once you've made this first commit, you should be able to set versionState
back to appVersion
to update and pull the latest version of the app from the parameter store.
You should now be able to view and test your lambda function from each environment you've deployed it into!