deploy
Overview
carlin deploy
This command deploys the AWS cloud resources. Carlin takes the template path defined by --template-path, -t
option. If this option has no value, the algorithm will search for these files to be used as template:
./src/cloudformation.ts
,./src/cloudformation.js
,./src/cloudformation.yaml
,./src/cloudformation.yml
,./src/cloudformation.json
,
and deploy accordingly to the following algorithm:
- Add defaults to CloudFormation template and parameters.
- Check is CloudFormation template body is greater than max size limit.
- If is greater, upload to S3 base stack.
- If stack exists, update the stack, else create a new stack.
- If
terminationProtection
option is true orenvironment
is defined, then stack termination protection will be enabled.
When you use a method to generate your CloudFormation template, you can retrieve the options from the CLI plus the following variables after CLI validations and middlewares logic:
stackName
environment
packageName
projectName
For example, in your cloudformation.ts
file:
export default async ({ environment, region, stackName }) => {
// Do something with CLI options and the variables above.
}
Stack Name
Carlin creates automatically the
CloudFormation stack name
, unless it is already specified at the
--stack-name
option. This name is very important because it'll track the deployment when a update or a delete is performed.
This method is a BREAKING CHANGE for carlin, I hope we never have to change this algorithm, ever. Stack name is how we track the stacks on AWS. Suppose we change this algorithm. If we perform an update or destroy operation, carlin will create another stack or do nothing because the old stack won't be found due to stack name changing.
If stack name isn't previously defined, the name will be created accordingly with the following rules:
The name has to parts.
The first part is defined by the package.json name, if it is defined. Else, it'll be a random name starting with the string "Stack-", e.g. Stack-96830.
The second part will be defined by, whichever is defined first:
- environment,
- branch name in param-case,
undefined
.
Example:
Case | Package Name | Environment | Branch Name | --stack-name | Stack Name |
---|---|---|---|---|---|
#1 | @package/name | Production | main | MyStackName | MyStackName |
#2 | @package/name | Production | main | PackageName-Production | |
#3 | @package/name | main | PackageName-main | ||
#4 | @package/name | PackageName | |||
#5 | Production | main | Stack-96820-Production | ||
#6 | main | Stack-96820-main | |||
#7 | Stack-96820 |
Lambda
Carlin automatically handles Lambda functions in your CloudFormation templates by building and deploying code to S3. When Lambda functions are detected, Carlin analyzes Handler
properties in AWS::Lambda::Function
and AWS::Serverless::Function
resources, builds the code, and uploads it to S3.
Handler Format
Your Handler
property must follow the format path/to/file.exportedFunction
. For example, if you have src/auth/index.ts
with export validateUser
, set Handler
to auth/index.validateUser
. The base directory defaults to src
but can be configured with --lambda-entry-points-base-dir
.
Automatic S3 Parameters
Carlin automatically injects S3 parameters into your CloudFormation template:
- TypeScript
- Yaml
// Carlin adds these parameters automatically
Parameters: {
LambdaS3Bucket: { Type: 'String' },
LambdaS3Key: { Type: 'String' },
LambdaS3ObjectVersion: { Type: 'String' },
}
# Carlin adds these parameters automatically
Parameters:
LambdaS3Bucket:
Type: String
LambdaS3Key:
Type: String
LambdaS3ObjectVersion:
Type: String
Lambda Resource Configuration
Reference the S3 parameters in your Lambda resources. If Code
or CodeUri
properties are undefined, Carlin sets them automatically:
- TypeScript
- Yaml
Resources: {
MyLambda: {
Type: 'AWS::Lambda::Function',
Properties: {
Handler: 'auth/index.validateUser',
Code: {
S3Bucket: { Ref: 'LambdaS3Bucket' },
S3Key: { Ref: 'LambdaS3Key' },
S3ObjectVersion: { Ref: 'LambdaS3ObjectVersion' },
},
},
},
MyServerlessFunction: {
Type: 'AWS::Serverless::Function',
Properties: {
Handler: 'users/create.handler',
CodeUri: {
Bucket: { Ref: 'LambdaS3Bucket' },
Key: { Ref: 'LambdaS3Key' },
Version: { Ref: 'LambdaS3ObjectVersion' },
},
},
},
}
Resources:
MyLambda:
Type: AWS::Lambda::Function
Properties:
Handler: auth/index.validateUser
Code:
S3Bucket: !Ref LambdaS3Bucket
S3Key: !Ref LambdaS3Key
S3ObjectVersion: !Ref LambdaS3ObjectVersion
MyServerlessFunction:
Type: AWS::Serverless::Function
Properties:
Handler: users/create.handler
CodeUri:
Bucket: !Ref LambdaS3Bucket
Key: !Ref LambdaS3Key
Version: !Ref LambdaS3ObjectVersion
Lambda Build Process
Format Configuration
Carlin builds the Lambda code using esbuild. It can build the code as ESM or
CJS format. When building as ESM, it will split the code into multiple files,
which reduces the payload size when deploying the Lambda function. The file
extension of the output files will be .mjs
for ESM and .cjs
for CJS.
Configure output format with --lambda-format
. Default is esm
for modern JavaScript modules.
Destroy
To destroy the stack, just pass the option --destroy
to the deploy command:
carlin deploy --destroy
The destroy algorithm is the following:
- Check if
environment
is defined. If defined, do nothing. It doesn't destroy stacks with definedenvironment
. - Check if termination protection is disabled.
- Empty all buckets in the stack (if any).
- Delete the stack.
This operation is irreversible. You must pay attention because you may destroy resources that contains your App data, like DynamoDB, using this command.
To overcome this problem, destroy will only delete the resources if termination protetion isn't enabled and if --environment, -e, --env
isn't defined.
Examples
- Change the CloudFormation template path.
carlin deploy -t src/cloudformation.template1.yml
- Set environment.
carlin deploy -e Production
- Lambda exists. Don't bundle momentjs.
carlin deploy --lambda-externals momentjs
- Destroy a specific stack.
carlin deploy --destroy --stack-name StackToBeDeleted
Use Cases
Outputs
After deployment, Carlin prints the outputs defined in your CloudFormation template and saves them in two files:
.carlin/$STACK_NAME.json
file..carlin/latest-deploy.json
file.
Note: The .carlin
folder is created in the root of your project.
The latest-deploy.json
file is used by tests and other packages that need
to access the outputs of the last deployment, but don't have access to the
stack name. It's useful for end-to-end tests that need to access the outputs
of the last deployment and test the application.
API
Options
Option | Alias | Default | Description | Type |
---|---|---|---|---|
aws-account-id | AWS account id associated with the deployment. | string | ||
destroy | Destroy the deployment. You cannot destroy a deploy when "environment" is defined. | boolean | ||
lambda-dockerfile | Dockerfile | Instructions to create the Lambda image. | string | |
lambda-image | A Lambda image will be created instead using S3. | boolean | ||
lambda-external | External modules that will not be bundled in the Lambda code. | array | ||
lambda-entry-points-base-dir | src | Base directory for Lambda entry points. | string | |
lambda-entry-points | This is an array of files that each serve as an input to the bundling algorithm for Lambda functions. | string | ||
lambda-format | esm | Lambda code format. | string | |
lambda-outdir | dist | Output directory for built Lambda code. | string | |
parameters | p | A list of parameters that will be passed to CloudFormation Parameters when deploying. This option has the format to match CloudFormation parameter.
For example:
If you want to simplify the usage, you can pass a object with key and value only:
| ||
skip-deploy | skip | Skip the deploy command. | boolean | |
stack-name | Set the stack name. | string | ||
template-path | t | Path to the CloudFormation template. | string |