Skip to main content

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:

  1. ./src/cloudformation.ts,
  2. ./src/cloudformation.js,
  3. ./src/cloudformation.yaml,
  4. ./src/cloudformation.yml,
  5. ./src/cloudformation.json,

and deploy accordingly to the following algorithm:

Algorithm
  1. Add defaults to CloudFormation template and parameters.
  2. Check is CloudFormation template body is greater than max size limit.
    1. If is greater, upload to S3 base stack.
  3. If stack exists, update the stack, else create a new stack.
  4. If terminationProtection option is true or environment 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.

caution

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:

  1. The name has to parts.

  2. 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.

  3. The second part will be defined by, whichever is defined first:

    1. environment,
    2. branch name in param-case,
    3. undefined.

Example:

CasePackage NameEnvironmentBranch Name--stack-nameStack Name
#1@package/nameProductionmainMyStackNameMyStackName
#2@package/nameProductionmainPackageName-Production
#3@package/namemainPackageName-main
#4@package/namePackageName
#5ProductionmainStack-96820-Production
#6mainStack-96820-main
#7Stack-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:

{
// ...
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:

{
// ...
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:

Algorithm
  1. Check if environment is defined. If defined, do nothing. It doesn't destroy stacks with defined environment.
  2. Check if termination protection is disabled.
  3. Empty all buckets in the stack (if any).
  4. Delete the stack.
danger

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:

  1. .carlin/$STACK_NAME.json file.
  2. .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

OptionAliasDefaultDescriptionType
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-dockerfileDockerfile

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-dirsrc

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-formatesm

Lambda code format.



string
lambda-outdirdist

Output directory for built Lambda code.



string
parametersp

A list of parameters that will be passed to CloudFormation Parameters when deploying.



This option has the format to match CloudFormation parameter.

{
 key: string,
 value: string,
 usePreviousValue: boolean,
 resolvedValue: string
}[]

For example:

[
 {
   key: 'key1',
   value: 'value1',
 },
 {
   key: 'key2',
   value: 'value2',
 }
]

If you want to simplify the usage, you can pass a object with key and value only:

{
 key1: 'value1',
 key2: 'value2'
}
skip-deployskip

Skip the deploy command.



boolean
stack-name

Set the stack name.



string
template-patht

Path to the CloudFormation template.



string