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-projectcargo lambda new --extension extension-projectLogs 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-projectcargo lambda new --extension --logs logs-projectTemplates
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-projectcargo lambda new \
--template https://github.com/calavera/custom-template \
new-projectThe --template flag also accepts routes to specific repository branches and tags:
cargo lambda new \
--template https://github.com/calavera/custom-template/branch/stable \
new-projectcargo lambda new \
--template https://github.com/calavera/custom-template/branch/stable \
new-projectcargo lambda new \
--template https://github.com/calavera/custom-template/tag/v0.1.0 \
new-projectcargo lambda new \
--template https://github.com/calavera/custom-template/tag/v0.1.0 \
new-projectTIP
You can use shortcuts like gh:, gl:, or bb: to refer to GitHub, GitLab, and Bitbucket repositories. For example, cargo lambda new --template gh:calavera/custom-template new-project is equivalent to cargo lambda new --template https://github.com/calavera/custom-template 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-projectcargo lambda new \
--template git@github.com:cargo-lambda/custom-template.git \
new-projectTemplate 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-projectcargo lambda new \
--template https://github.com/calavera/custom-template \
--render-file package.json \
--render-file lib/cdk-stack.ts \
new-projectTemplate 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-projectcargo lambda new \
--template https://github.com/calavera/custom-template \
--render-var CDK_VERSION=2 \
--render-var CDK_STACK=lambda-stack.ts \
new-projectYou 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-projectcargo lambda new \
--template https://github.com/calavera/custom-template \
--render-var ci_provider=.github \
new-projectFor 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-projectcargo lambda new \
--template https://github.com/calavera/custom-template \
--ignore-file package-lock.json \
--ignore-file yarn-lock.json \
new-projectInteractive 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-projectcargo lambda new \
--template https://github.com/calavera/custom-template \
--no-interactive \
new-projectCustom 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-projectcargo lambda new \
--template https://github.com/your-org/custom-template \
new-projectIf 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-projectcargo lambda new \
--template https://github.com/your-org/custom-template \
--no-interactive \
new-project