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
If your template has Lambda functions, Carlin will handle the Lambda code build and deploy. First, it analyzes the CloudFormation template to find all Handler
properties in the AWS::Lambda::Function
and AWS::Serverless::Function
resources. If there are no Lambda functions in the template, Carlin will deploy the stack without the Lambda algorithm. If it finds Lambda functions in the template or if the --lambda-entry-points
option is passed, Carlin will build the Lambda code and upload it to an S3 bucket.
Your Handler
property must be in the format path/to/my/file.myMethodHandler
, where path/to/my/file
is the file path and myMethodHandler
is the exported function name. For example, if you have a file named src/Module/index.ts
with an export function named getModuleProperty
, the Handler
property must be Module/index.getModuleProperty
. Note that src
is the base directory and you can defined it in the --lambda-entry-points-base-dir
option (default is src
).
Once Carlin uploads the code to S3, it sets the LambdaS3Bucket
, LambdaS3Key
and LambdaS3ObjectVersion
parameters, the S3 bucket parameters that the Lambda code was stored, to the CloudFormation template:
- TypeScript
- Yaml
{
// ...
Parameters: {
LambdaS3Bucket: {
Type: 'String',
Description: 'The S3 bucket where the Lambda code is stored.',
},
LambdaS3Key: {
Type: 'String',
Description: 'The S3 key where the Lambda code is stored.',
},
LambdaS3ObjectVersion: {
Type: 'String',
Description: 'The S3 object version of the Lambda code.',
},
},
};
Parameters:
LambdaS3Bucket:
Type: String
Description: The S3 bucket where the Lambda code is stored.
LambdaS3Key:
Type: String
Description: The S3 key where the Lambda code is stored.
LambdaS3ObjectVersion:
Type: String
Description: The S3 object version of the Lambda code.
Once defined as parameters, you can reference them in your CloudFormation template using the intrinsic function Ref
. For example, you can set the Code
property of the AWS::Lambda::Function resource
or CodeUri
property
of the AWS::Serverless::Function resource, referencing the LambdaS3Bucket
, LambdaS3Key
and LambdaS3ObjectVersion
parameters. For example, you can set the Code
or CodeUri
properties as shown in the following example:
- TypeScript
- Yaml
{
// ...
Resources: {
LambdaFunction: {
Type: 'AWS::Lambda::Function',
Properties: {
Code: {
S3Bucket: {
Ref: 'LambdaS3Bucket',
},
S3Key: {
Ref: 'LambdaS3Key',
},
S3ObjectVersion: {
Ref: 'LambdaS3ObjectVersion',
},
},
},
},
ServerlessFunction: {
Type: 'AWS::Serverless::Function',
Properties: {
CodeUri: {
Bucket: {
Ref: 'LambdaS3Bucket',
},
Key: {
Ref: 'LambdaS3Key',
},
Version: {
Ref: 'LambdaS3ObjectVersion',
},
},
},
},
},
};
Resources:
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref LambdaS3Bucket
S3Key: !Ref LambdaS3Key
S3ObjectVersion: !Ref LambdaS3ObjectVersion
ServerlessFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri:
Bucket: !Ref LambdaS3Bucket
Key: !Ref LambdaS3Key
Version: !Ref LambdaS3ObjectVersion
If Code
or CodeUri
is not set, Carlin will automatically set them to the values of the parameters, as shown in the example above (if Code
or CodeUri
is defined, Carlin won't modify them).
Format
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.
Use the --lambda-format
option to define the format of the Lambda code. The default is esm
.
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 |