Cargo Lambda New
The new
command creates new Rust packages with a basic skeleton to help you start writing AWS Lambda functions with Rust. This command will create this package in a new sub-directory inside the directory where it's invoked. Run cargo lambda new PACKAGE-NAME
to generate your new package.
This command uses templates packed as zip files, or from local directories. The default template supports HTTP Lambda functions, as well as functions that receive events defined in the aws_lambda_events crate. You can provide your own template using the --template
flag.
The files Cargo.toml
, README.md
, and src/main.rs
in the template are parsed with Liquid to dynamically render different files based on a series of global variables. You can see all the variables in the source code.
After creating a new package, you can use the build command to compile the source code.
Extensions
You can also use this subcommand to create new Lambda Extension projects. Use the flag --extension
to create the right project:
cargo lambda new --extension extension-project
cargo lambda new --extension extension-project
Logs extensions
If you want to build a Lambda Logs extension, add the --logs
to the previous command. Cargo Lambda will create the scaffolding for a Logs extension:
cargo lambda new --extension --logs logs-project
cargo lambda new --extension --logs logs-project
Templates
Cargo Lambda uses template repositories as scaffolding for new projects. You can see the default template for functions and the default template for extensions in GitHub.
Cargo Lambda can also download custom templates from other public GitHub repositories by using the --template
with the repository url, for example:
cargo lambda new \
--template https://github.com/calavera/custom-template \
new-project
cargo lambda new \
--template https://github.com/calavera/custom-template \
new-project
The --template
flag also accepts routes to specific repository branches and tags:
cargo lambda new \
--template https://github.com/calavera/custom-template/branch/stable \
new-project
cargo lambda new \
--template https://github.com/calavera/custom-template/branch/stable \
new-project
cargo lambda new \
--template https://github.com/calavera/custom-template/tag/v0.1.0 \
new-project
cargo lambda new \
--template https://github.com/calavera/custom-template/tag/v0.1.0 \
new-project
Private template repositories
If you want to use a template that's in a private repository, Cargo Lambda uses the same method as git clone
to download the repository. This means that you need to have access to the repository and that you need to have the credentials to access it configured in your machine.
To download a private repository with SSH, you need to have the SSH key configured in your machine. You can use the same SSH URLs as you use with git clone
.
cargo lambda new \
--template git@github.com:cargo-lambda/custom-template.git \
new-project
cargo lambda new \
--template git@github.com:cargo-lambda/custom-template.git \
new-project
Template rendering
Cargo Lambda uses Liquid to render files from a given template.
By default, only a few files in a template are rendered by Liquid, the rest are copied into the new project's directory as they are. These are the files rendered by Liquid by default:
- README.md
- Cargo.toml
- src/main.rs
- src/lib.rs
- src/bin/*.rs
If you want to render additional files you can use the flag --render-file
with a path relative to the root of the directory where the project is created:
cargo lambda new \
--template https://github.com/calavera/custom-template \
--render-file package.json \
--render-file lib/cdk-stack.ts \
new-project
cargo lambda new \
--template https://github.com/calavera/custom-template \
--render-file package.json \
--render-file lib/cdk-stack.ts \
new-project
Template variables
When you create a new project, Cargo Lambda adds several variables to the template engine that you can use in any file that's rendered by Liquid.
These are the variables for function templates:
- project_name: The name of the project and package.
- bin_name: The name of the main binary to compile if it's different than the project name.
- http_function: Whether the function is an http function.
- http_feature: the lambda event feature type that integrates with an http function.
- event_type: the Rust event type that the function receives.
- event_type_feature: the lambda event feature name in the aws_lambda_events crate.
- event_type_import: The Rust import statement that the function uses.
These are the variables for extension templates:
- project_name: The name of the project and package.
- bin_name: The name of the main binary to compile if it's different than the project name.
- logs: Whether the extension is a Logs extension or not.
You can add additional variables to render by a template with the flag --render-var
. This flag takes variables in the format KEY=VALUE
:
cargo lambda new \
--template https://github.com/calavera/custom-template \
--render-var CDK_VERSION=2 \
--render-var CDK_STACK=lambda-stack.ts \
new-project
cargo lambda new \
--template https://github.com/calavera/custom-template \
--render-var CDK_VERSION=2 \
--render-var CDK_STACK=lambda-stack.ts \
new-project
You can also use Liquid variables in file paths themselves. This allows you to dynamically generate file paths based on template variables:
cargo lambda new \
--template https://github.com/calavera/custom-template \
--render-var ci_provider=.github \
new-project
cargo lambda new \
--template https://github.com/calavera/custom-template \
--render-var ci_provider=.github \
new-project
For example, a template containing a file path like /workflows/build.yml
would be rendered as .github/workflows/build.yml
with the above command.
Ignore files
By default, Cargo Lambda will ignore the .git
directory and the LICENSE
file in the template repository. If you want to ignore additional files in a new project, you can use the flag --ignore-file
:
cargo lambda new \
--template https://github.com/calavera/custom-template \
--ignore-file package-lock.json \
--ignore-file yarn-lock.json \
new-project
cargo lambda new \
--template https://github.com/calavera/custom-template \
--ignore-file package-lock.json \
--ignore-file yarn-lock.json \
new-project
Interactive options
Cargo Lambda's new
subcommand displays several interactive questions for the default templates to work. If you have a custom template and you want to skip these questions, you can use the flag --no-interactive
:
cargo lambda new \
--template https://github.com/calavera/custom-template \
--no-interactive \
new-project
cargo lambda new \
--template https://github.com/calavera/custom-template \
--no-interactive \
new-project
Custom templates
Cargo Lambda allows you to create custom templates with interactive prompts to collect user input during project creation. To create a custom template, add a CargoLambda.toml
file to your template repository with the following structure. The template files can be placed either in the root directory or in a subdirectory called template
. Cargo Lambda will automatically detect and use the template
subdirectory if it exists. The CargoLambda.toml
file can be located in the root directory or in the template
directory. If you don't want to add it to the final project directory, it's recommended to place it in the root directory, and put the template files in the template
directory.
[template]
# Disable the default interactive prompts that cargo-lambda shows
disable_default_prompts = true
# Specify which files should be processed by the Liquid template engine
render_files = [
"Cargo.toml",
"README.md",
"src/main.rs"
]
# Process all files in the template with Liquid (overrides render_files)
render_all_files = true
# Files to ignore when copying the template
ignore_files = [
"README.md"
]
# Files to conditionally render based on a promptvariable
[template.render_conditional_files]
".github" = { var = "github_actions", match = true }
# Files to conditionally ignore based on a prompt variable
[template.ignore_conditional_files]
"Apache.txt" = { var = "license", not_match = "APACHE" }
"MIT.txt" = { var = "license", not_match = "MIT" }
# Define custom interactive prompts
[template.prompts]
project_description = { message = "What is the description of your project?", default = "My Lambda" }
enable_tracing = { message = "Would you like to enable tracing?", default = false }
runtime = { message = "Which runtime would you like to use?", choices = ["provided.al2023", "provided.al2"], default = "provided.al2023" }
architecture = { message = "Which architecture would you like to target?", choices = ["x86_64", "arm64"], default = "x86_64" }
memory = { message = "How much memory (in MB) would you like to allocate?", default = "128" }
timeout = { message = "What timeout (in seconds) would you like to set?", default = "3" }
github_actions = { message = "Would you like to add GitHub Actions CI/CD support?", default = false }
license = { message = "Would you like to add a license?", choices = ["Ignore license", "MIT", "APACHE"], default = "Ignore license" }
[template]
# Disable the default interactive prompts that cargo-lambda shows
disable_default_prompts = true
# Specify which files should be processed by the Liquid template engine
render_files = [
"Cargo.toml",
"README.md",
"src/main.rs"
]
# Process all files in the template with Liquid (overrides render_files)
render_all_files = true
# Files to ignore when copying the template
ignore_files = [
"README.md"
]
# Files to conditionally render based on a promptvariable
[template.render_conditional_files]
".github" = { var = "github_actions", match = true }
# Files to conditionally ignore based on a prompt variable
[template.ignore_conditional_files]
"Apache.txt" = { var = "license", not_match = "APACHE" }
"MIT.txt" = { var = "license", not_match = "MIT" }
# Define custom interactive prompts
[template.prompts]
project_description = { message = "What is the description of your project?", default = "My Lambda" }
enable_tracing = { message = "Would you like to enable tracing?", default = false }
runtime = { message = "Which runtime would you like to use?", choices = ["provided.al2023", "provided.al2"], default = "provided.al2023" }
architecture = { message = "Which architecture would you like to target?", choices = ["x86_64", "arm64"], default = "x86_64" }
memory = { message = "How much memory (in MB) would you like to allocate?", default = "128" }
timeout = { message = "What timeout (in seconds) would you like to set?", default = "3" }
github_actions = { message = "Would you like to add GitHub Actions CI/CD support?", default = false }
license = { message = "Would you like to add a license?", choices = ["Ignore license", "MIT", "APACHE"], default = "Ignore license" }
Configuration Options
disable_default_prompts
: When set totrue
, disables Cargo Lambda's built-in promptsrender_files
: List of files that should be processed by the Liquid template enginerender_all_files
: Whentrue
, all files in the template will be processed by Liquidrender_conditional_files
: Table of files that should be conditionally rendered based on variable valuesignore_conditional_files
: Table of files that should be conditionally ignored based on variable valuesignore_files
: List of files that should not be copied to the new projectprompts
: Table of interactive prompts to collect user input
Prompt Configuration
Each prompt can have the following properties:
name
: Variable name to use in templates (required)message
: Question to display to the user (required)default
: Default value if user doesn't provide input (optional)choices
: Array of valid options for the user to choose from (optional)help
: Help message to display to the user (optional)
Conditional Rendering
Each conditional render or ignore can have the following properties:
var
: Variable name to use in templates (required)match
: Value that the variable should match to render or ignore the filenot_match
: Value that the variable should not match to render or ignore the file
Using prompt values in templates
The values collected from these prompts are available in your template files through Liquid variables. For example:
[package]
name = "{{ project_name }}"
description = "{{ project_description }}"
[package]
name = "{{ project_name }}"
description = "{{ project_description }}"
#[function_name = "{{ project_name }}"]
#[tracing(enable = {{ enable_tracing }})]
pub async fn handler() -> Result<()> {
// ...
}
#[function_name = "{{ project_name }}"]
#[tracing(enable = {{ enable_tracing }})]
pub async fn handler() -> Result<()> {
// ...
}
To use your custom template:
cargo lambda new \
--template https://github.com/your-org/custom-template \
new-project
cargo lambda new \
--template https://github.com/your-org/custom-template \
new-project
If you want to skip the interactive prompts, use the --no-interactive
flag:
cargo lambda new \
--template https://github.com/your-org/custom-template \
--no-interactive \
new-project
cargo lambda new \
--template https://github.com/your-org/custom-template \
--no-interactive \
new-project