

# Build your application with AWS SAM
<a name="serverless-building"></a>

After you have added your infrastructure as code (IaC) to your AWS SAM template, you’ll be ready to start building your application using the **sam build** command. This command creates build artifacts from the files in your application project directory (that is, your AWS SAM template file, application code, and any applicable language-specific files and dependencies). These build artifacts prepare your serverless application for later steps of your application's development, such as local testing and deploying to the AWS Cloud. Both testing and deploying use build artifacts as inputs.

You can use **sam build** to build your entire serverless application. Additionally, you can create customized builds, like one's with specific functions, layers, or custom runtimes. To read more on how and why you use **sam build**, see the topics in this section. For an introduction to using the `sam build` command, see [Introduction to building with AWS SAM](using-sam-cli-build.md).

**Topics**
+ [Introduction to building with AWS SAM](using-sam-cli-build.md)
+ [Default build with AWS SAM](serverless-sam-cli-using-build.md)
+ [Customize builds with AWS SAM](building-lambda-functions.md)

# Introduction to building with AWS SAM
<a name="using-sam-cli-build"></a>

Use the AWS Serverless Application Model Command Line Interface (AWS SAM CLI) `sam build` command to prepare your serverless application for subsequent steps in your development workflow, such as local testing or deploying to the AWS Cloud. This command creates a `.aws-sam` directory that structures your application in a format and location that `sam local` and `sam deploy` require.
+ For an introduction to the AWS SAM CLI, see [What is the AWS SAM CLI?](what-is-sam-overview.md#what-is-sam-cli).
+ For a list of `sam build` command options, see [sam build](sam-cli-command-reference-sam-build.md).
+ For an example of using `sam build` during a typical development workflow, see [Step 2: Build your application](serverless-getting-started-hello-world.md#serverless-getting-started-hello-world-build).

**Note**  
Using `sam build` requires that you start with the basic components of a serverless application on your development machine. This includes an AWS SAM template, AWS Lambda function code, and any language-specific files and dependencies. To learn more, see [Create your application in AWS SAM](using-sam-cli-init.md).

**Topics**
+ [Building applications with sam build](#using-sam-cli-build-apps)
+ [Local testing and deployment](#using-sam-cli-build-test-deploy)
+ [Best practices](#using-sam-cli-build-best)
+ [Options for sam build](#using-sam-cli-build-options)
+ [Troubleshooting](#using-sam-cli-build-troubleshooting)
+ [Examples](#using-sam-cli-build-examples)
+ [Learn more](#using-sam-cli-build-learn)

## Building applications with sam build
<a name="using-sam-cli-build-apps"></a>

Before using `sam build`, consider configuring the following:

1. **Lambda functions and layers** – The `sam build` command can build Lambda functions and layers. To learn more about Lambda layers, see [Building Lambda layers in AWS SAM](building-layers.md).

1. **Lambda runtime** – The *runtime* provides a language-specific environment that runs your function in an execution environment when invoked. You can configure native and custom runtimes.

   1. **Native runtime** – Author your Lambda functions in a supported Lambda runtime and build you functions to use a native Lambda runtime in the AWS Cloud.

   1. **Custom runtime** – Author your Lambda functions using any programming language and build your runtime using a custom process defined in a makefile or third-party builder such as esbuild. To learn more, see [Building Lambda functions with custom runtimes in AWS SAM](building-custom-runtimes.md).

1. **Lambda package type** – Lambda functions can be packaged in the following Lambda deployment package types:

   1. **.zip file archive** – Contains your application code and its dependencies.

   1. **Container image** – Contains the base operating system, the runtime, Lambda extensions, your application code and its dependencies.

These application settings can be configured when initializing an application using `sam init`.
+ To learn more about using `sam init`, see [Create your application in AWS SAM](using-sam-cli-init.md).
+ To learn more about configuring these settings in your application, see [Default build with AWS SAM](serverless-sam-cli-using-build.md).

**To build an application**

1. `cd` to the root of your project. This is the same location as your AWS SAM template.

   ```
   $ cd sam-app
   ```

1. Run the following:

   ```
   sam-app $ sam build <arguments> <options>
   ```
**Note**  
A commonly used option is `--use-container`. To learn more, see [Building a Lambda function inside of a provided container](#using-sam-cli-build-options-container).

   The following is an example of the AWS SAM CLI output:

   ```
   sam-app $ sam build
   Starting Build use cache
   Manifest file is changed (new hash: 3298f1304...d4d421) or dependency folder (.aws-sam/deps/4d3dfad6-a267-47a6-a6cd-e07d6fae318c) is missing for (HelloWorldFunction), downloading dependencies and copying/building source
   Building codeuri: /Users/.../sam-app/hello_world runtime: python3.12 metadata: {} architecture: x86_64 functions: HelloWorldFunction
   Running PythonPipBuilder:CleanUp
   Running PythonPipBuilder:ResolveDependencies
   Running PythonPipBuilder:CopySource
   Running PythonPipBuilder:CopySource
   
   Build Succeeded
   
   Built Artifacts  : .aws-sam/build
   Built Template   : .aws-sam/build/template.yaml
   
   Commands you can use next
   =========================
   [*] Validate SAM template: sam validate
   [*] Invoke Function: sam local invoke
   [*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
   [*] Deploy: sam deploy --guided
   ```

1. The AWS SAM CLI creates a `.aws-sam` build directory. The following is an example:

   ```
   .aws-sam
   ├── build
   │   ├── HelloWorldFunction
   │   │   ├── __init__.py
   │   │   ├── app.py
   │   │   └── requirements.txt
   │   └── template.yaml
   └── build.toml
   ```

Depending on how your application is configured, the AWS SAM CLI does the following:

1. Downloads, installs, and organizes dependencies in the `.aws-sam/build` directory.

1. Prepares your Lambda code. This can include compiling your code, creating executable binaries, and building container images.

1. Copies build artifacts to the `.aws-sam` directory. The format will vary based on your application package type.

   1. For .zip package types, the artifacts are not zipped yet so that they can be used for local testing. The AWS SAM CLI zips your application when using `sam deploy`.

   1. For container image package types, a container image is created locally and referenced in the `.aws-sam/build.toml` file.

1. Copies the AWS SAM template over to the `.aws-sam` directory and modifies it with new file paths when necessary.

The following are the major components that make up your build artifacts in the `.aws-sam` directory:
+ **The build directory** – Contains your Lambda functions and layers structured independently of each other. This results in a unique structure for each function or layer in the `.aws-sam/build` directory.
+ **The AWS SAM template** – Modified with updated values based on changes during the build process.
+ **The build.toml file** – A configuration file that contains build settings used by the AWS SAM CLI.

## Local testing and deployment
<a name="using-sam-cli-build-test-deploy"></a>

When performing local testing with `sam local` or deployment with `sam deploy`, the AWS SAM CLI does the following:

1. It first checks to see if an `.aws-sam` directory exists and if an AWS SAM template is located within that directory. If these conditions are met, the AWS SAM CLI considers this as the root directory of your application.

1. If these conditions are not met, the AWS SAM CLI considers the original location of your AWS SAM template as the root directory of your application.

When developing, if changes are made to your original application files, run `sam build` to update the `.aws-sam` directory before testing locally.

## Best practices
<a name="using-sam-cli-build-best"></a>
+ Don’t edit any code under the `.aws-sam/build` directory. Instead, update your original source code in your project folder and run `sam build` to update the `.aws-sam/build` directory.
+ When you modify your original files, run `sam build` to update the `.aws-sam/build` directory.
+ You may want the AWS SAM CLI to reference your project’s original root directory instead of the `.aws-sam` directory, such as when developing and testing with `sam local`. Delete the `.aws-sam` directory or the AWS SAM template in the `.aws-sam` directory to have the AWS SAM CLI recognize your original project directory as the root project directory. When ready, run `sam build` again to create the `.aws-sam` directory.
+ When you run `sam build`, the `.aws-sam/build` directory gets overwritten each time. The `.aws-sam` directory does not. If you want to store files, such as logs, store them in `.aws-sam` to prevent them from being overwritten.

## Options for sam build
<a name="using-sam-cli-build-options"></a>

### Building a single resource
<a name="using-sam-cli-build-options-resource"></a>

Provide the resource’s logical ID to build only that resource. The following is an example:

```
$ sam build HelloWorldFunction
```

To build a resource of a nested application or stack, provide the application or stack logical ID along with the resource logical ID using the format `<stack-logical-id>/<resource-logical-id>` :

```
$ sam build MyNestedStack/MyFunction
```

### Building a Lambda function inside of a provided container
<a name="using-sam-cli-build-options-container"></a>

The `--use-container` option downloads a container image and uses it to build your Lambda functions. The local container is then referenced in your `.aws-sam/build.toml` file.

This option requires Docker to be installed. For instructions, see [Installing Docker](install-docker.md).

The following is an example of this command:

```
$ sam build --use-container
```

You can specify the container image to use with the `--build-image` option. The following is an example:

```
$ sam build --use-container --build-image amazon/aws-sam-cli-build-image-nodejs20.x
```

To specify the container image to use for a single function, provide the function logical ID. The following is an example:

```
$ sam build --use-container --build-image Function1=amazon/aws-sam-cli-build-image-python3.12
```

### Building container images with BuildKit
<a name="using-sam-cli-build-options-buildkit"></a>

When building Lambda functions with the `Image` package type, you can use BuildKit as the build engine by passing the `--use-buildkit` option. BuildKit provides improved build performance, better caching, and enhanced build output compared to the legacy Docker build engine.

This option requires having either the Docker or Finch CLIs installed and in your `PATH`.

You can combine `--use-buildkit` with other build options. The following is an example:

```
$ sam build --use-buildkit --parallel
```

**Note**  
The `--use-buildkit` flag is for container image builds only. It will not have any effect for zip functions being built with `--use-container`.

### Pass environment variables to the build container
<a name="using-sam-cli-build-options-env"></a>

Use the `--container-env-var` to pass environment variables to the build container. The following is an example:

```
$ sam build --use-container --container-env-var Function1.GITHUB_TOKEN=<token1> --container-env-var GLOBAL_ENV_VAR=<global-token>
```

To pass environment variables from a file, use the `--container-env-var-file` option. The following is an example:

```
$ sam build --use-container --container-env-var-file <env.json>
```

Example of the `env.json` file:

```
{
  "MyFunction1": {
    "GITHUB_TOKEN": "TOKEN1"
  },
  "MyFunction2": {
    "GITHUB_TOKEN": "TOKEN2"
  }
}
```

### Speed up the building of applications that contain multiple functions
<a name="using-sam-cli-build-options-speed"></a>

When you run `sam build` on an application with multiple functions, the AWS SAM CLI builds each function one at a time. To speed up the build process, use the `--parallel` option. This builds all of your functions and layers at the same time.

The following is an example of this command:

```
$ sam build —-parallel
```

### Speed up build times by building your project in the source folder
<a name="using-sam-cli-build-options-source"></a>

For supported runtimes and build methods, you can use the `--build-in-source` option to build your project directly in the source folder. By default, the AWS SAM CLI builds in a temporary directory, which involves copying over source code and project files. With `--build-in-source`, the AWS SAM CLI builds directly in your source folder, which speeds up the build process by removing the need to copy files to a temporary directory.

For a list of supported runtimes and build methods, see `--build-in-source`.

## Troubleshooting
<a name="using-sam-cli-build-troubleshooting"></a>

To troubleshoot the AWS SAM CLI, see [AWS SAM CLI troubleshooting](sam-cli-troubleshooting.md).

## Examples
<a name="using-sam-cli-build-examples"></a>

### Building an application that uses a native runtime and .zip package type
<a name="using-sam-cli-build-examples-tutorial1"></a>

For this example, see [Tutorial: Deploy a Hello World application with AWS SAM](serverless-getting-started-hello-world.md).

### Building an application that uses a native runtime and image package type
<a name="using-sam-cli-build-examples-image"></a>

First, we run `sam init` to initialize a new application. During the interactive flow, we select the `Image` package type. The following is an example:

```
$ sam init
...
Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
        1 - Hello World Example
        2 - Multi-step workflow
        3 - Serverless API
        4 - Scheduled task
        5 - Standalone function
        6 - Data processing
        7 - Hello World Example With Powertools
        8 - Infrastructure event management
        9 - Serverless Connector Hello World Example
        10 - Multi-step workflow with Connectors
        11 - Lambda EFS example
        12 - DynamoDB Example
        13 - Machine Learning
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: ENTER

Which runtime would you like to use?
        ...
        10 - java8
        11 - nodejs20.x
        12 - nodejs18.x
        13 - nodejs16.x
        ...
Runtime: 12

What package type would you like to use?
        1 - Zip
        2 - Image
Package type: 2

Based on your selections, the only dependency manager available is npm.
We will proceed copying the template using npm.

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: ENTER

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: ENTER

Project name [sam-app]: ENTER

Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)

    -----------------------
    Generating application:
    -----------------------
    Name: sam-app
    Base Image: amazon/nodejs18.x-base
    Architectures: x86_64
    Dependency Manager: npm
    Output Directory: .
    Configuration file: sam-app/samconfig.toml

    Next steps can be found in the README file at sam-app/README.md
    
...
```

The AWS SAM CLI initializes an application and creates the following project directory:

```
sam-app
├── README.md
├── events
│   └── event.json
├── hello-world
│   ├── Dockerfile
│   ├── app.mjs
│   ├── package.json
│   └── tests
│       └── unit
│           └── test-handler.mjs
├── samconfig.toml
└── template.yaml
```

Next, we run `sam build` to build our application:

```
sam-app $ sam build
Building codeuri: /Users/.../build-demo/sam-app runtime: None metadata: {'DockerTag': 'nodejs18.x-v1', 'DockerContext': '/Users/.../build-demo/sam-app/hello-world', 'Dockerfile': 'Dockerfile'} architecture: arm64 functions: HelloWorldFunction
Building image for HelloWorldFunction function
Setting DockerBuildArgs: {} for HelloWorldFunction function
Step 1/4 : FROM public.ecr.aws/lambda/nodejs:18
 ---> f5b68038c080
Step 2/4 : COPY app.mjs package*.json ./
 ---> Using cache
 ---> 834e565aae80
Step 3/4 : RUN npm install
 ---> Using cache
 ---> 31c2209dd7b5
Step 4/4 : CMD ["app.lambdaHandler"]
 ---> Using cache
 ---> 2ce2a438e89d
Successfully built 2ce2a438e89d
Successfully tagged helloworldfunction:nodejs18.x-v1

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
```

### Building an application that includes a compiled programming language
<a name="using-sam-cli-build-examples-compiled"></a>

In this example, we build an application that contains a Lambda function using the Go runtime.

First, we initialize a new application using `sam init` and configure our application to use Go:

```
$ sam init

...

Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
        1 - Hello World Example
        2 - Multi-step workflow
        3 - Serverless API
        ...
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: ENTER

Which runtime would you like to use?
        ...
        4 - dotnetcore3.1
        5 - go1.x
        6 - go (provided.al2)
        ...
Runtime: 5

What package type would you like to use?
        1 - Zip
        2 - Image
Package type: 1

Based on your selections, the only dependency manager available is mod.
We will proceed copying the template using mod.

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: ENTER

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: ENTER

Project name [sam-app]: ENTER

Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)

    -----------------------
    Generating application:
    -----------------------
    Name: sam-app
    Runtime: go1.x
    Architectures: x86_64
    Dependency Manager: mod
    Application Template: hello-world
    Output Directory: .
    Configuration file: sam-app/samconfig.toml
    
    Next steps can be found in the README file at sam-app-go/README.md
        
...
```

The AWS SAM CLI initializes the application. The following is an example of the application directory structure:

```
sam-app
├── Makefile
├── README.md
├── events
│   └── event.json
├── hello-world
│   ├── go.mod
│   ├── go.sum
│   ├── main.go
│   └── main_test.go
├── samconfig.toml
└── template.yaml
```

We reference the `README.md` file for this application’s requirements.

```
...
## Requirements
* AWS CLI already configured with Administrator permission
* [Docker installed](https://www.docker.com/community-edition)
* [Golang](https://golang.org)
* SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)
...
```

Next, we run `sam local invoke` to test our function. This command errors since Go is not installed on our local machine:

```
sam-app $ sam local invoke
Invoking hello-world (go1.x)
Local image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-go1.x
Building image.................................................................................................................................................................................................................................................
Using local image: public.ecr.aws/lambda/go:1-rapid-x86_64.

Mounting /Users/.../Playground/build/sam-app/hello-world as /var/task:ro,delegated inside runtime container
START RequestId: c6c5eddf-042b-4e1e-ba66-745f7c86dd31 Version: $LATEST
fork/exec /var/task/hello-world: no such file or directory: PathError
null
END RequestId: c6c5eddf-042b-4e1e-ba66-745f7c86dd31
REPORT RequestId: c6c5eddf-042b-4e1e-ba66-745f7c86dd31  Init Duration: 0.88 ms  Duration: 175.75 ms Billed Duration: 176 ms Memory Size: 128 MB     Max Memory Used: 128 MB
{"errorMessage":"fork/exec /var/task/hello-world: no such file or directory","errorType":"PathError"}%
```

Next, we run `sam build` to build our application. We encounter an error since Go is not installed on our local machine:

```
sam-app $ sam build
Starting Build use cache
Cache is invalid, running build and copying resources for following functions (HelloWorldFunction)
Building codeuri: /Users/.../Playground/build/sam-app/hello-world runtime: go1.x metadata: {} architecture: x86_64 functions: HelloWorldFunction

Build Failed
Error: GoModulesBuilder:Resolver - Path resolution for runtime: go1.x of binary: go was not successful
```

While we could configure our local machine to properly build our function, we instead use the `--use-container` option with `sam build`. The AWS SAM CLI downloads a container image, builds our function using the native GoModulesBuilder, and copies the resulting binary to our `.aws-sam/build/HelloWorldFunction` directory.

```
sam-app $ sam build --use-container
Starting Build use cache
Starting Build inside a container
Cache is invalid, running build and copying resources for following functions (HelloWorldFunction)
Building codeuri: /Users/.../build/sam-app/hello-world runtime: go1.x metadata: {} architecture: x86_64 functions: HelloWorldFunction

Fetching public.ecr.aws/sam/build-go1.x:latest-x86_64 Docker container image.....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Mounting /Users/.../build/sam-app/hello-world as /tmp/samcli/source:ro,delegated inside runtime container
Running GoModulesBuilder:Build

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
```

The following is an example of the `.aws-sam` directory:

```
.aws-sam
├── build
│   ├── HelloWorldFunction
│   │   └── hello-world
│   └── template.yaml
├── build.toml
├── cache
│   └── c860d011-4147-4010-addb-2eaa289f4d95
│       └── hello-world
└── deps
```

Next, we run `sam local invoke`. Our function is successfully invoked:

```
sam-app $ sam local invoke
Invoking hello-world (go1.x)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/go:1-rapid-x86_64.

Mounting /Users/.../Playground/build/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: cfc8ffa8-29f2-49d4-b461-45e8c7c80479 Version: $LATEST
END RequestId: cfc8ffa8-29f2-49d4-b461-45e8c7c80479
REPORT RequestId: cfc8ffa8-29f2-49d4-b461-45e8c7c80479  Init Duration: 1.20 ms  Duration: 1782.46 ms        Billed Duration: 1783 ms        Memory Size: 128 MB     Max Memory Used: 128 MB
{"statusCode":200,"headers":null,"multiValueHeaders":null,"body":"Hello, 72.21.198.67\n"}%
```

## Learn more
<a name="using-sam-cli-build-learn"></a>

To learn more about using the `sam build` command, see the following:
+ **[Learning AWS SAM: sam build](https://www.youtube.com/watch?v=fDhYKp4op_g)** – Serverless Land "Learning AWS SAM" series on YouTube.
+ **[Learning AWS SAM \$1 sam build \$1 E3 ](https://www.youtube.com/watch?v=vsAvRyLnB7Y)** – Serverless Land "Learning AWS SAM" series on YouTube.
+ **[AWS SAM build: how it provides artifacts for deployment (Sessions With SAM S2E8)](https://www.youtube.com/watch?v=bNbBd6XoDHg)** – Sessions with AWS SAM series on YouTube.
+ **[AWS SAM custom builds: How to use Makefiles to customize builds in SAM (S2E9)](https://www.youtube.com/watch?v=wpccutnSbAk)** – Sessions with AWS SAM series on YouTube.

# Default build with AWS SAM
<a name="serverless-sam-cli-using-build"></a>

To build your serverless application, use the `sam build` command. This command also gathers the build artifacts of your application's dependencies and places them in the proper format and location for next steps, such as locally testing, packaging, and deploying.

You specify your application's dependencies in a manifest file, such as `requirements.txt` (Python) or `package.json` (Node.js), or by using the `Layers` property of a function resource. The `Layers` property contains a list of [AWS Lambda layer](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) resources that the Lambda function depends on.

The format of your application's build artifacts depends on each function's `PackageType` property. The options for this property are:
+ **`Zip`** – A .zip file archive, which contains your application code and its dependencies. If you package your code as a .zip file archive, you must specify a Lambda runtime for your function.
+ **`Image`** – A container image, which includes the base operating system, runtime, and extensions, in addition to your application code and its dependencies.

For more information about Lambda package types, see [Lambda deployment packages](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-package.html) in the *AWS Lambda Developer Guide*.

**Topics**
+ [Building a .zip file archive](#build-zip-archive)
+ [Building a container image](#build-container-image)
+ [Container environment variable file](#serverless-sam-cli-using-container-environment-file)
+ [Speed up build times by building your project in the source folder](#serverless-sam-cli-using-build-in-source)
+ [Examples](#building-applications-examples)
+ [Building functions outside of AWS SAM](#building-applications-skip)

## Building a .zip file archive
<a name="build-zip-archive"></a>

To build your serverless application as a .zip file archive, declare `PackageType: Zip` for your serverless function.

AWS SAM builds your application for the [architecture](sam-resource-function.md#sam-function-architectures) that you specify. If you don't specify an architecture, AWS SAM uses `x86_64` by default.

If your Lambda function depends on packages that have natively compiled programs, use the `--use-container` flag. This flag locally compiles your functions in a container that behaves like a Lambda environment, so they're in the right format when you deploy them to the AWS Cloud.

When you use the `--use-container` option, by default AWS SAM pulls the container image from [Amazon ECR Public](https://docs.aws.amazon.com/AmazonECR/latest/public/what-is-ecr.html). If you would like to pull a container image from another repository or for a specific version of AWS SAM CLI, you can use the `--build-image` option and provide the URI of an alternate container image. Following are two example commands for building applications using container images from a specific version of AWS SAM CLI:

```
# Build a Node.js 20 application using a container image for a specific version of AWS SAM CLI (1.136.0)
sam build --use-container --build-image public.ecr.aws/sam/build-nodejs22.x:1.136.0

# Build a function resource using the Python 3.13 container image from a specific version of AWS SAM CLI (1.136.0)(
sam build --use-container --build-image Function1=public.ecr.aws/sam/build-python3.13:1.136.0
```

For additional examples of building a .zip file archive application, see the Examples section later in this topic.

## Building a container image
<a name="build-container-image"></a>

To build your serverless application as a container image, declare `PackageType: Image` for your serverless function. You must also declare the `Metadata` resource attribute with the following entries:

`Dockerfile`  
The name of the Dockerfile associated with the Lambda function.

`DockerContext`  
The location of the Dockerfile.

`DockerTag`  
(Optional) A tag to apply to the built image.

`DockerBuildArgs`  
Build arguments for the build.  
The AWS SAM CLI doesn't redact or obfuscate any information you include in `DockerBuildArgs` arguments. We strongly recommend you don't use this section to store sensitive information, such as passwords or secrets.

`DockerImage`  
(Optional) A custom name for the built Docker image. If not specified, the function's logical resource ID is used.

The following is an example `Metadata` resource attribute section:

```
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: ./hello_world
      DockerTag: v1
      DockerImage: my-custom-image
```

To download a sample application that's configured with the `Image` package type, see [Tutorial: Deploy a Hello World application with AWS SAM](serverless-getting-started-hello-world.md). At the prompt asking which package type you want to install, choose `Image`.

**Note**  
If you specify a multi-architecture base image in your Dockerfile, AWS SAM builds your container image for your host machine's architecture. To build for a different architecture, specify a base image that uses the specific target architecture.

By default, the AWS SAM CLI uses the legacy Docker build engine when building container images. To use BuildKit, an improved container backend that improves performance and handles more complex builds, pass the `--use-buildkit` flag with your build command:

```
$ sam build --use-buildkit
```

Using `--use-buildkit` requires having the Docker or Finch CLI installed.

## Container environment variable file
<a name="serverless-sam-cli-using-container-environment-file"></a>

To provide a JSON file that contains environment variables for the build container, use the `--container-env-var-file` argument with the `sam build` command. You can provide a single environment variable that applies to all serverless resources, or different environment variables for each resource.

### Format
<a name="serverless-sam-cli-using-container-environment-file-format"></a>

The format for passing environment variables to a build container depends on how many environment variables you provide for your resources.

To provide a single environment variable for all resources, specify a `Parameters` object like the following:

```
{
  "Parameters": {
    "GITHUB_TOKEN": "TOKEN_GLOBAL"
  }
}
```

To provide different environment variables for each resource, specify objects for each resource like the following:

```
{
  "MyFunction1": {
    "GITHUB_TOKEN": "TOKEN1"
  },
  "MyFunction2": {
    "GITHUB_TOKEN": "TOKEN2"
  }
}
```

Save your environment variables as a file, for example, named `env.json`. The following command uses this file to pass your environment variables to the build container:

```
sam build --use-container --container-env-var-file env.json
```

### Precedence
<a name="serverless-sam-cli-using-container-environment-file-precedence"></a>
+ The environment variables that you provide for specific resources take precedence over the single environment variable for all resources.
+ Environment variables that you provide on the command line take precedence over environment variables in a file.

## Speed up build times by building your project in the source folder
<a name="serverless-sam-cli-using-build-in-source"></a>

For supported runtimes and build methods, you can use the `--build-in-source` option to build your project directly in the source folder. By default, the AWS SAM CLI builds in a temporary directory, which involves copying over source code and project files. With `--build-in-source`, the AWS SAM CLI builds directly in your source folder, which speeds up the build process by removing the need to copy files to a temporary directory.

For a list of supported runtimes and build methods, see `--build-in-source`.

## Examples
<a name="building-applications-examples"></a>

### Example 1: .zip file archive
<a name="examples-zip-archives"></a>

The following `sam build` commands build a .zip file archive:

```
# Build all functions and layers, and their dependencies
sam build

# Run the build process inside a Docker container that functions like a Lambda environment
sam build --use-container

# Build a Node.js 20 application using a container image for a specific version of AWS SAM CLI (1.136.0)
sam build --use-container --build-image public.ecr.aws/sam/build-nodejs22.x:1.136.0

# Build a function resource using the Python 3.13 container image from a specific version of AWS SAM CLI (1.136.0)(
sam build --use-container --build-image Function1=public.ecr.aws/sam/build-python3.13:1.136.0

# Build and run your functions locally
sam build && sam local invoke

# For more options
sam build --help
```

### Example 2: Container image
<a name="examples-container-image-1"></a>

The following AWS SAM template builds as a container image:

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      ImageConfig:
        Command: ["app.lambda_handler"]
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: ./hello_world
      DockerTag: v1
```

The following is an example Dockerfile:

```
FROM public.ecr.aws/lambda/python:3.12

COPY app.py requirements.txt ./

RUN python3.12 -m pip install -r requirements.txt

# Overwrite the command by providing a different command directly in the template.
CMD ["app.lambda_handler"]
```

### Example 3: npm ci
<a name="examples-npm-ci"></a>

For Node.js applications, you can use `npm ci` instead of `npm install` to install dependencies. To use `npm ci`, specify `UseNpmCi: True` under `BuildProperties` in your Lambda function's `Metadata` resource attribute. To use `npm ci`, your application must have a `package-lock.json` or `npm-shrinkwrap.json` file present in the `CodeUri` for your Lambda function.

The following example uses `npm ci` to install dependencies when you run `sam build`:

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.handler
      Runtime: nodejs20.x
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
    Metadata:
      BuildProperties:
        UseNpmCi: True
```

### Python parent packages
<a name="building-applications-python-parent-packages"></a>

For Python applications, you can preserve your package structure during the build process to enable absolute imports. To preserve package structure, specify `ParentPackageMode` under `BuildProperties` in your Lambda function's `Metadata` resource attribute.

The following example preserves the `app` package structure when you run `sam build`:

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.main.handler
      Runtime: python3.12
      Architectures:
        - x86_64
    Metadata:
      BuildProperties:
        ParentPackageMode: explicit
        ParentPackages: app
```

With this configuration, your code can use absolute imports like `from app.utils import logger` instead of relative imports like `from .utils import logger`.

## Building functions outside of AWS SAM
<a name="building-applications-skip"></a>

By default, when you run **sam build**, AWS SAM builds all of your function resources. Other options include:
+ **Build all function resources outside of AWS SAM** – If you build all of your function resources manually or through another tool, **sam build** is not required. You can skip **sam build** and move on to the next step in your process, such as performing local testing or deploying your application.
+ **Build some function resources outside of AWS SAM** – If you want AWS SAM to build some of your function resources while having other function resources built outside of AWS SAM, you can specify this in your AWS SAM template.

### Build some function resources outside of AWS SAM
<a name="building-applications-skip-some"></a>

To have AWS SAM skip a function when using **sam build**, configure the following in your AWS SAM template:

1. Add the `SkipBuild: True` metadata property to your function.

1. Specify the path to your built function resources.

Here is an example, with `TestFunction` configured to be skipped. Its built resources are located at `built-resources/TestFunction.zip`.

```
TestFunction:
  Type: AWS::Serverless::Function
  Properties:
    CodeUri: built-resources/TestFunction.zip
    Handler: TimeHandler::handleRequest
    Runtime: java11
  Metadata:
    SkipBuild: True
```

Now, when you run **sam build**, AWS SAM will do the following:

1. AWS SAM will skip functions configured with `SkipBuild: True`.

1. AWS SAM will build all other function resources and cache them in the `.aws-sam` build directory.

1. For skipped functions, their template in the `.aws-sam` build directory will automatically be updated to reference the specified path to your built function resources.

   Here is an example of the cached template for `TestFunction` in the `.aws-sam` build directory:

   ```
   TestFunction:
     Type: AWS::Serverless::Function
     Properties:
       CodeUri: ../../built-resources/TestFunction.zip
       Handler: TimeHandler::handleRequest
       Runtime: java11
     Metadata:
       SkipBuild: True
   ```

# Customize builds with AWS SAM
<a name="building-lambda-functions"></a>

You can customize your build to include specific Lambda functions or Lambda layers. A function is a resource that you can invoke to run your code in Lambda. A Lambda layer allows you to extract code from a Lambda function that can then be re-used across several Lambda functions. You may choose to customize your build with specific Lambda functions when you want to focus on developing and deploying individual serverless functions without the complexity of managing shared dependencies or resources. Additionally, you may choose to build a Lambda layer to help you reduce the size of your deployment packages, separate core function logic from dependencies, and allow you to share dependencies across multiple functions.

The topics in this section explore some of the different ways you can build Lambda functions with AWS SAM. This includes building Lambda functions with customer runtimes and building Lambda layers. Custom runtimes let you install and use a language not listed in Lambda runtimes in the AWS Lambda Developer Guide. This allows you to create a specialized execution environment for running serverless functions and applications. Building only Lambda layers (instead of building your entire application) can benefit you in a few ways. It can help you reduce the size of your deployment packages, separate core function logic from dependencies, and allow you to share dependencies across multiple functions.

For more information on functions, see [Lambda concepts](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-concepts.html) in the *AWS Lambda Developer Guide*.

**Topics**
+ [Building Node.js Lambda functions with esbuild in AWS SAM](serverless-sam-cli-using-build-typescript.md)
+ [Building .NET Lambda functions with Native AOT compilation in AWS SAM](build-dotnet7.md)
+ [Building Rust Lambda functions with Cargo Lambda in AWS SAM](building-rust.md)
+ [Building Python Lambda functions with uv in AWS SAM](building-python-uv.md)
+ [Building Lambda functions with custom runtimes in AWS SAM](building-custom-runtimes.md)
+ [Building Lambda layers in AWS SAM](building-layers.md)

# Building Node.js Lambda functions with esbuild in AWS SAM
<a name="serverless-sam-cli-using-build-typescript"></a>

To build and package Node.js AWS Lambda functions, you can use the AWS SAM CLI with the esbuild JavaScript bundler. The esbuild bundler supports Lambda functions that you write in TypeScript.

To build a Node.js Lambda function with esbuild, add a `Metadata` object to your `AWS:Serverless::Function` resource and specify `esbuild` for the `BuildMethod`. When you run the **sam build** command, AWS SAM uses esbuild to bundle your Lambda function code.

## Metadata properties
<a name="serverless-sam-cli-using-build-typescript-metadata"></a>

The `Metadata` object supports the following properties for esbuild.

### BuildMethod
<a name="serverless-sam-cli-using-build-typescript-metadata-buildmethod"></a>

Specifies the bundler for your application. The only supported value is `esbuild`.

### BuildProperties
<a name="serverless-sam-cli-using-build-typescript-metadata-buildproperties"></a>

Specifies the build properties for your Lambda function code.

The `BuildProperties` object supports the following properties for esbuild. All of the properties are optional. By default, AWS SAM uses your Lambda function handler for the entry point.

**EntryPoints**  
Specifies entry points for your application.

**External**  
Specifies the list of packages to omit from the build. For more information, see [External](https://esbuild.github.io/api/#external) in the *esbuild website*.

**Format**  
Specifies the output format of the generated JavaScript files in your application. For more information, see [Format](https://esbuild.github.io/api/#format) in the *esbuild website*.

**Loader**  
Specifies the list of configurations for loading data for a given file type.

**MainFields**  
Specifies which `package.json` fields to try to import when resolving a package. The default value is `main,module`.

**Minify**  
Specifies whether to minify the bundled output code. The default value is `true`.

**OutExtension**  
Customize the file extension of the files that esbuild generates. For more information, see [Out extension](https://esbuild.github.io/api/#out-extension) in the *esbuild website*.

**Sourcemap**  
Specifies whether the bundler produces a source map file. The default value is `false`.  
When set to `true`, `NODE_OPTIONS: --enable-source-maps` is appended to the Lambda function's environment variables, and a source map is generated and included in the function.  
Alternatively, when `NODE_OPTIONS: --enable-source-maps` is included in the function's environment variables, `Sourcemap` is automatically set to `true`.  
When conflicting, `Sourcemap: false` takes precedence over `NODE_OPTIONS: --enable-source-maps`.  
By default, Lambda encrypts all environment variables at rest with AWS Key Management Service (AWS KMS). When using source maps, for the deployment to succeed, your function's execution role must have permission to perform the `kms:Encrypt` action.

**SourcesContent**  
Specifies whether to include your source code in your source map file. Configure this property when `Sourcemap` is set to `'true'`.  
+ Specify `SourcesContent: 'true'` to include all source code.
+ Specify `SourcesContent: 'false'` to exclude all source code. This results in smaller source maps file sizes, which is useful in production by reducing start-up times. However, source code won't be available in the debugger.
The default value is `SourcesContent: true`.  
For more information, see [Sources content](https://esbuild.github.io/api/#sources-content) in the *esbuild website*.

**Target**  
Specifies the target ECMAScript version. The default value is `es2020`.

## TypeScript Lambda function example
<a name="serverless-sam-cli-using-build-typescript-example"></a>

The following example AWS SAM template snippet uses esbuild to create a Node.js Lambda function from TypeScript code in `hello-world/app.ts`.

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.handler
      Runtime: nodejs20.x
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api 
          Properties:
            Path: /hello
            Method: get
      Environment:
        Variables:
          NODE_OPTIONS: --enable-source-maps
    Metadata:
      BuildMethod: esbuild
      BuildProperties:
        Format: esm
        Minify: false
        OutExtension:
          - .js=.mjs
        Target: "es2020"
        Sourcemap: true
        EntryPoints: 
          - app.ts
        External:
          - "<package-to-exclude>"
```

# Building .NET Lambda functions with Native AOT compilation in AWS SAM
<a name="build-dotnet7"></a>

Build and package your .NET 8 AWS Lambda functions with the AWS Serverless Application Model (AWS SAM), utilizing Native Ahead-of-Time (AOT) compilation to improve AWS Lambda cold-start times.

**Topics**
+ [.NET 8 Native AOT overview](#build-dotnet7-overview)
+ [Using AWS SAM with your .NET 8 Lambda functions](#build-dotnet7-sam)
+ [Install prerequisites](#build-dotnet7-prerequisites)
+ [Define .NET 8 Lambda functions in your AWS SAM template](#build-dotnet7-sam-define)
+ [Build your application with the AWS SAM CLI](#build-dotnet7-sam-build)
+ [Learn more](#build-dotnet7-learn-more)

## .NET 8 Native AOT overview
<a name="build-dotnet7-overview"></a>

Historically, .NET Lambda functions have cold-start times which impact user experience, system latency, and usage costs of your serverless applications. With .NET Native AOT compilation, you can improve cold-start times of your Lambda functions. To learn more about Native AOT for .NET 8, see [Using Native AOT](https://github.com/dotnet/runtime/tree/main/src/coreclr/nativeaot#readme) in the *Dotnet GitHub repository*.

## Using AWS SAM with your .NET 8 Lambda functions
<a name="build-dotnet7-sam"></a>

Do the following to configure your .NET 8 Lambda functions with the AWS Serverless Application Model (AWS SAM):
+ Install prerequisites on your development machine.
+ Define .NET 8 Lambda functions in your AWS SAM template.
+ Build your application with the AWS SAM CLI.

## Install prerequisites
<a name="build-dotnet7-prerequisites"></a>

The following are required prerequisites:
+ The AWS SAM CLI
+ The .NET Core CLI
+ The Amazon.Lambda.Tools .NET Core Global Tool
+ Docker

**Install the AWS SAM CLI**

1. To check if you already have the AWS SAM CLI installed, run the following:

   ```
   sam --version
   ```

1. To install the AWS SAM CLI, see [Install the AWS SAM CLI](install-sam-cli.md).

1. To upgrade an installed version of the AWS SAM CLI, see [Upgrading the AWS SAM CLI](manage-sam-cli-versions.md#manage-sam-cli-versions-upgrade).

**Install the .NET Core CLI**

1. To download and install the .NET Core CLI, see [Download .NET](https://dotnet.microsoft.com/download) from Microsoft's website.

1. For more information on the .NET Core CLI, see [.NET Core CLI](https://docs.aws.amazon.com/lambda/latest/dg/csharp-package-cli.html) in the *AWS Lambda Developer Guide*.

**Install the Amazon.Lambda.Tools .NET Core Global Tool**

1. Run the following command:

   ```
   dotnet tool install -g Amazon.Lambda.Tools
   ```

1. If you already have the tool installed, you can make sure that it is the latest version using the following command:

   ```
   dotnet tool update -g Amazon.Lambda.Tools
   ```

1. For more information about the Amazon.Lambda.Tools .NET Core Global Tool, see the [AWS Extensions for .NET CLI](https://github.com/aws/aws-extensions-for-dotnet-cli) repository on GitHub.

**Install Docker**
+ Building with Native AOT, requires Docker to be installed. For installation instructions, see [Installing Docker to use with the AWS SAM CLI](install-docker.md).

## Define .NET 8 Lambda functions in your AWS SAM template
<a name="build-dotnet7-sam-define"></a>

To define a .NET8 Lambda function in your AWS SAM template, do the following:

1. Run the following command from a starting directory of your choice::

   ```
   sam init
   ```

1. Select `AWS Quick Start Templates` to choose a starting template.

1. Choose the `Hello World Example` template.

1. Choose to not use the most popular runtime and package type by entering `n`.

1. For runtime, choose `dotnet8`.

1. For package type, choose `Zip`.

1. For your starter template, choose `Hello World Example using native AOT`.

**Install Docker**
+ Building with Native AOT, requires Docker to be installed. For installation instructions, see [Installing Docker to use with the AWS SAM CLI](install-docker.md).

```
Resources:
HelloWorldFunction:
  Type: AWS::Serverless::Function
  Properties:
    CodeUri: ./src/HelloWorldAot/
    Handler: bootstrap
    Runtime: dotnet8
    Architectures:
      - x86_64
    Events:
      HelloWorldAot:
        Type: Api 
        Properties:
          Path: /hello
          Method: get
```

**Note**  
When the `Event` property of an `AWS::Serverless::Function` is set to `Api`, but the `RestApiId` property is not specified, AWS SAM generates the `AWS::ApiGateway::RestApi` CloudFormation resource.

## Build your application with the AWS SAM CLI
<a name="build-dotnet7-sam-build"></a>

 From your project's root directory, run the `sam build` command to begin building your application. If the `PublishAot` property has been defined in your .NET 8 project file, the AWS SAM CLI will build with Native AOT compilation. To learn more about the `PublishAot` property, see [Native AOT Deployment](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/) in Microsoft's *.NET documentation*.

To build your function, the AWS SAM CLI invokes the .NET Core CLI which uses the Amazon.Lambda.Tools .NET Core Global Tool.

**Note**  
When building, if a `.sln` file exists in the same or parent directory of your project, the directory containing the `.sln` file will be mounted to the container. If a `.sln` file is not found, only the project folder is mounted. Therefore, if you are building a multi-project application, ensure the `.sln` file is property located.

## Learn more
<a name="build-dotnet7-learn-more"></a>

For more information on building .NET 8 Lambda functions, see [Introducing the .NET 8 runtime for AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-net-8-runtime-for-aws-lambda/).

For a reference of the **sam build** command, see [sam build](sam-cli-command-reference-sam-build.md).

# Building Rust Lambda functions with Cargo Lambda in AWS SAM
<a name="building-rust"></a>


|  | 
| --- |
| This feature is in preview release for AWS SAM and is subject to change. | 

Use the AWS Serverless Application Model Command Line Interface (AWS SAM CLI) with your Rust AWS Lambda functions.

**Topics**
+ [Prerequisites](#building-rust-prerequisites)
+ [Configuring AWS SAM to use with Rust Lambda functions](#building-rust-configure)
+ [Examples](#building-rust-examples)

## Prerequisites
<a name="building-rust-prerequisites"></a>

**Rust language**  
To install Rust, see [Install Rust](https://www.rust-lang.org/tools/install) in the *Rust language website*.

**Cargo Lambda**  
The AWS SAM CLI requires installation of [https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html), a subcommand for Cargo. For installation instructions, see [Installation](https://www.cargo-lambda.info/guide/installation.html) in the *Cargo Lambda documentation*.

**Docker**  
Building and testing Rust Lambda functions requires Docker. For installation instructions, see [Installing Docker](install-docker.md).

**Opt in to AWS SAM CLI beta feature**  
Since this feature is in preview, you must opt in using one of the following methods:  

1. Use the environment variable: `SAM_CLI_BETA_RUST_CARGO_LAMBDA=1`.

1. Add the following to your `samconfig.toml` file:

   ```
   [default.build.parameters]
   beta_features = true
   [default.sync.parameters]
   beta_features = true
   ```

1. Use the `--beta-features` option when using a supported AWS SAM CLI command. For example:

   ```
   $ sam build --beta-features
   ```

1. Choose option `y` when the AWS SAM CLI prompts you to opt in. The following is an example:

   ```
   $ sam build
   Starting Build use cache
   Build method "rust-cargolambda" is a beta feature.
   Please confirm if you would like to proceed
   You can also enable this beta feature with "sam build --beta-features". [y/N]: y
   ```

## Configuring AWS SAM to use with Rust Lambda functions
<a name="building-rust-configure"></a>

### Step 1: Configure your AWS SAM template
<a name="building-rust-configure-template"></a>

Configure your AWS SAM template with the following:
+ **Binary** – Optional. Specify when your template contains multiple Rust Lambda functions.
+ **BuildMethod** – `rust-cargolambda`.
+ **CodeUri** – path to your `Cargo.toml` file.
+ **Handler** – `bootstrap`.
+ **Runtime** – `provided.al2`.

To learn more about custom runtimes, see [Custom AWS Lambda runtimes](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html) in the *AWS Lambda Developer Guide*.

Here is an example of a configured AWS SAM template:

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Metadata:
      BuildMethod: rust-cargolambda
      BuildProperties: function_a
    Properties:
      CodeUri: ./rust_app
      Handler: bootstrap
      Runtime: provided.al2
...
```

### Step 2: Use the AWS SAM CLI with your Rust Lambda function
<a name="building-rust-configure-cli"></a>

Use any AWS SAM CLI command with your AWS SAM template. For more information, see [AWS SAM CLI](using-sam-cli.md).

## Examples
<a name="building-rust-examples"></a>

### Hello World example
<a name="building-rust-examples-hello"></a>

**In this example, we build the sample Hello World application using Rust as our runtime.**

First, we initialize a new serverless application using `sam init`. During the interactive flow, we select the **Hello World application** and choose the **Rust** runtime.

```
$ sam init
...
Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
        1 - Hello World Example
        2 - Multi-step workflow
        3 - Serverless API
        ...
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: ENTER

Which runtime would you like to use?
        1 - dotnet8
        2 - dotnet6
        3 - go (provided.al2)
        ...
        18 - python3.11
        19 - python3.10
        20 - ruby3.3
        21 - ruby3.2
        22 - rust (provided.al2)
        23 - rust (provided.al2023)
Runtime: 22

Based on your selections, the only Package type available is Zip.
We will proceed to selecting the Package type as Zip.

Based on your selections, the only dependency manager available is cargo.
We will proceed copying the template using cargo.

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: ENTER

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: ENTER

Project name [sam-app]: hello-rust

    -----------------------
    Generating application:
    -----------------------
    Name: hello-rust
    Runtime: rust (provided.al2)
    Architectures: x86_64
    Dependency Manager: cargo
    Application Template: hello-world
    Output Directory: .
    Configuration file: hello-rust/samconfig.toml
    
    Next steps can be found in the README file at hello-rust/README.md
        

Commands you can use next
=========================
[*] Create pipeline: cd hello-rust && sam pipeline init --bootstrap
[*] Validate SAM template: cd hello-rust && sam validate
[*] Test Function in the Cloud: cd hello-rust && sam sync --stack-name {stack-name} --watch
```

The following is the structure of our Hello World application:

```
hello-rust
├── README.md
├── events
│   └── event.json
├── rust_app
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── samconfig.toml
└── template.yaml
```

In our AWS SAM template, our Rust function is defined as the following:

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function 
    Metadata:
      BuildMethod: rust-cargolambda 
    Properties:
      CodeUri: ./rust_app 
      Handler: bootstrap   
      Runtime: provided.al2
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
            Path: /hello
            Method: get
```

Next, we run `sam build` to build our application and prepare for deployment. The AWS SAM CLI creates a `.aws-sam` directory and organizes our build artifacts there. Our function is built using Cargo Lambda and stored as an executable binary at `.aws-sam/build/HelloWorldFunction/bootstrap`.

**Note**  
If you plan on running the **sam local invoke** command in MacOS, you need to build functions different before invoking. To do this, use the following command:  
**SAM\$1BUILD\$1MODE=debug sam build**
This command is only needed if local testing will be done. This is not recommended when building for deployment.

```
hello-rust$ sam build
Starting Build use cache
Build method "rust-cargolambda" is a beta feature.
Please confirm if you would like to proceed
You can also enable this beta feature with "sam build --beta-features". [y/N]: y

Experimental features are enabled for this session.
Visit the docs page to learn more about the AWS Beta terms https://aws.amazon.com/service-terms/.

Cache is invalid, running build and copying resources for following functions (HelloWorldFunction)
Building codeuri: /Users/.../hello-rust/rust_app runtime: provided.al2 metadata: {'BuildMethod': 'rust-cargolambda'} architecture: x86_64 functions: HelloWorldFunction
Running RustCargoLambdaBuilder:CargoLambdaBuild
Running RustCargoLambdaBuilder:RustCopyAndRename

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
```

Next, we deploy our application using `sam deploy --guided`.

```
hello-rust$ sam deploy --guided

Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Found
        Reading default arguments  :  Success

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [hello-rust]: ENTER
        AWS Region [us-west-2]: ENTER
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [Y/n]: ENTER
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]: ENTER
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]: ENTER
        HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]: ENTER
        SAM configuration file [samconfig.toml]: ENTER
        SAM configuration environment [default]: ENTER

        Looking for resources needed for deployment:

        ...

        Uploading to hello-rust/56ba6585d80577dd82a7eaaee5945c0b  817973 / 817973  (100.00%)

        Deploying with following values
        ===============================
        Stack name                   : hello-rust
        Region                       : us-west-2
        Confirm changeset            : True
        Disable rollback             : False
        Deployment s3 bucket         : aws-sam-cli-managed-default-samclisam-s3-demo-bucket-1a4x26zbcdkqr
        Capabilities                 : ["CAPABILITY_IAM"]
        Parameter overrides          : {}
        Signing Profiles             : {}

Initiating deployment
=====================

        Uploading to hello-rust/a4fc54cb6ab75dd0129e4cdb564b5e89.template  1239 / 1239  (100.00%)


Waiting for changeset to be created..

CloudFormation stack changeset
---------------------------------------------------------------------------------------------------------
Operation                  LogicalResourceId          ResourceType               Replacement              
---------------------------------------------------------------------------------------------------------
+ Add                      HelloWorldFunctionHelloW   AWS::Lambda::Permission    N/A                      
                           orldPermissionProd                                                             
...                    
---------------------------------------------------------------------------------------------------------

Changeset created successfully. arn:aws:cloudformation:us-west-2:012345678910:changeSet/samcli-deploy1681427201/f0ef1563-5ab6-4b07-9361-864ca3de6ad6


Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y

2023-04-13 13:07:17 - Waiting for stack create/update to complete

CloudFormation events from stack operations (refresh every 5.0 seconds)
---------------------------------------------------------------------------------------------------------
ResourceStatus             ResourceType               LogicalResourceId          ResourceStatusReason     
---------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS         AWS::IAM::Role             HelloWorldFunctionRole     -                        
CREATE_IN_PROGRESS         AWS::IAM::Role             HelloWorldFunctionRole     Resource creation        
...
---------------------------------------------------------------------------------------------------------

CloudFormation outputs from deployed stack
---------------------------------------------------------------------------------------------------------
Outputs                                                                                                 
---------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole                                                           
Description         Implicit IAM Role created for Hello World function                                  
Value               arn:aws:iam::012345678910:role/hello-rust-HelloWorldFunctionRole-10II2P13AUDUY      

Key                 HelloWorldApi                                                                       
Description         API Gateway endpoint URL for Prod stage for Hello World function                    
Value               https://ggdxec9le9.execute-api.us-west-2.amazonaws.com/Prod/hello/                  

Key                 HelloWorldFunction                                                                  
Description         Hello World Lambda Function ARN                                                     
Value               arn:aws:lambda:us-west-2:012345678910:function:hello-rust-HelloWorldFunction-       
yk4HzGzYeZBj                                                                                            
---------------------------------------------------------------------------------------------------------


Successfully created/updated stack - hello-rust in us-west-2
```

To test, we can invoke our Lambda function using the API endpoint.

```
$ curl https://ggdxec9le9.execute-api.us-west-2.amazonaws.com/Prod/hello/
Hello World!%
```

To test our function locally, first we ensure our function’s `Architectures` property matches our local machine.

```
...
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Metadata:
      BuildMethod: rust-cargolambda # More info about Cargo Lambda: https://github.com/cargo-lambda/cargo-lambda
    Properties:
      CodeUri: ./rust_app   # Points to dir of Cargo.toml
      Handler: bootstrap    # Do not change, as this is the default executable name produced by Cargo Lambda
      Runtime: provided.al2
      Architectures:
        - arm64
...
```

Since we modified our architecture from `x86_64` to `arm64` in this example, we run `sam build` to update our build artifacts. We then run `sam local invoke` to locally invoke our function.

```
hello-rust$ sam local invoke
Invoking bootstrap (provided.al2)
Local image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-provided.al2
Building image.....................................................................................................................................
Using local image: public.ecr.aws/lambda/provided:al2-rapid-arm64.

Mounting /Users/.../hello-rust/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container
START RequestId: fbc55e6e-0068-45f9-9f01-8e2276597fc6 Version: $LATEST
{"statusCode":200,"body":"Hello World!"}END RequestId: fbc55e6e-0068-45f9-9f01-8e2276597fc6
REPORT RequestId: fbc55e6e-0068-45f9-9f01-8e2276597fc6  Init Duration: 0.68 ms  Duration: 130.63 ms     Billed Duration: 131 ms     Memory Size: 128 MB     Max Memory Used: 128 MB
```

### Single Lambda function project
<a name="building-rust-examples-single"></a>

**Here is an example of a serverless application containing one Rust Lambda function. **

Project directory structure:

```
.
├── Cargo.lock
├── Cargo.toml
├── src
│   └── main.rs
└── template.yaml
```

AWS SAM template:

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Metadata:
      BuildMethod: rust-cargolambda
    Properties:
      CodeUri: ./             
      Handler: bootstrap
      Runtime: provided.al2
...
```

### Multiple Lambda function project
<a name="building-rust-examples-multiple"></a>

**Here is an example of a serverless application containing multiple Rust Lambda functions.**

Project directory structure:

```
.
├── Cargo.lock
├── Cargo.toml
├── src
│   ├── function_a.rs
│   └── function_b.rs
└── template.yaml
```

AWS SAM template:

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
Resources:
  FunctionA:
    Type: AWS::Serverless::Function
    Metadata:
      BuildMethod: rust-cargolambda
      BuildProperties:
        Binary: function_a 
    Properties:
      CodeUri: ./           
      Handler: bootstrap     
      Runtime: provided.al2
  FunctionB:
    Type: AWS::Serverless::Function
    Metadata:
      BuildMethod: rust-cargolambda
      BuildProperties:
        Binary: function_b
    Properties:
      CodeUri: ./
      Handler: bootstrap
      Runtime: provided.al2
```

`Cargo.toml` file:

```
[package]
name = "test-handler"
version = "0.1.0"
edition = "2021"

[dependencies]
lambda_runtime = "0.6.0"
serde = "1.0.136"
tokio = { version = "1", features = ["macros"] }
tracing = { version = "0.1", features = ["log"] }
tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt"] }

[[bin]]
name = "function_a"
path = "src/function_a.rs"

[[bin]]
name = "function_b"
path = "src/function_b.rs"
```

# Building Python Lambda functions with uv in AWS SAM
<a name="building-python-uv"></a>


|  | 
| --- |
| This feature is in preview release for AWS SAM and is subject to change. | 

Use the AWS Serverless Application Model Command Line Interface (AWS SAM CLI) with uv, a fast Python package installer and resolver, to build your Python AWS Lambda functions.

**Topics**
+ [Prerequisites](#building-python-uv-prerequisites)
+ [Configuring AWS SAM to use with Python Lambda functions and uv](#building-python-uv-configure)
+ [Examples](#building-python-uv-examples)

## Prerequisites
<a name="building-python-uv-prerequisites"></a>

**Python**  
To install Python, see [Download Python](https://www.python.org/downloads/) in the *Python website*.

**uv**  
The AWS SAM CLI requires installation of [https://docs.astral.sh/uv/](https://docs.astral.sh/uv/), an extremely fast Python package installer and resolver. For installation instructions, see [Installation](https://docs.astral.sh/uv/getting-started/installation/) in the *uv documentation*.

**Opt in to AWS SAM CLI beta feature**  
Since this feature is in preview, you must opt in using one of the following methods:  

1. Use the environment variable: `SAM_CLI_BETA_PYTHON_UV=1`.

1. Add the following to your `samconfig.toml` file:

   ```
   [default.build.parameters]
   beta_features = true
   [default.sync.parameters]
   beta_features = true
   ```

1. Use the `--beta-features` option when using a supported AWS SAM CLI command. For example:

   ```
   $ sam build --beta-features
   ```

1. Choose option `y` when the AWS SAM CLI prompts you to opt in. The following is an example:

   ```
   $ sam build
   Starting Build use cache
   Build method "python-uv" is a beta feature.
   Please confirm if you would like to proceed
   You can also enable this beta feature with "sam build --beta-features". [y/N]: y
   ```

## Configuring AWS SAM to use with Python Lambda functions and uv
<a name="building-python-uv-configure"></a>

### Step 1: Configure your AWS SAM template
<a name="building-python-uv-configure-template"></a>

Configure your AWS SAM template with the following:
+ **BuildMethod** – `python-uv`.
+ **CodeUri** – path to your function code directory containing `pyproject.toml` or `requirements.txt`.
+ **Handler** – your function handler (e.g., `app.lambda_handler`).
+ **Runtime** – Python runtime version (e.g., `python3.12`).

Here is an example of a configured AWS SAM template:

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./my_function
      Handler: app.lambda_handler
      Runtime: python3.12
    Metadata:
      BuildMethod: python-uv
...
```

## Examples
<a name="building-python-uv-examples"></a>

### Hello World example
<a name="building-python-uv-examples-hello"></a>

**In this example, we build a sample Hello World application using Python with uv as the package manager.**

uv can use either `pyproject.toml` or `requirements.txt` to read dependencies. If both are given, `sam build` will read from `requirements.txt` for dependencies.

The following is the structure of our Hello World application:

```
hello-python-uv
├── README.md
├── events
│   └── event.json
├── hello_world
│   ├── __init__.py
│   ├── app.py
│   └── pyproject.toml
├── samconfig.toml
└── template.yaml
```

`pyproject.toml` file:

```
[project]
name = "my-function"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "requests>=2.31.0",
    "boto3>=1.28.0",
]
```

In our AWS SAM template, our Python function is defined as the following:

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.12
      Architectures:
        - x86_64
    Metadata:
      BuildMethod: python-uv
```

Next, we run `sam build` to build our application and prepare for deployment. The AWS SAM CLI creates a `.aws-sam` directory and organizes our build artifacts there. Our function dependencies are installed using uv and stored at `.aws-sam/build/HelloWorldFunction/`.

```
hello-python-uv$ sam build
Starting Build use cache
Build method "python-uv" is a beta feature.
Please confirm if you would like to proceed
You can also enable this beta feature with "sam build --beta-features". [y/N]: y

Experimental features are enabled for this session.
Visit the docs page to learn more about the AWS Beta terms https://aws.amazon.com/service-terms/.

Cache is invalid, running build and copying resources for following functions (HelloWorldFunction)
Building codeuri: /Users/.../hello-python-uv/hello_world runtime: python3.12 metadata: {'BuildMethod': 'python-uv'} architecture: x86_64 functions: HelloWorldFunction
Running PythonUvBuilder:UvBuild
Running PythonUvBuilder:CopySource

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
```

**Note**  
The `python-uv` build method is configured per function in the `Metadata` section. Each function in your template can use a different build method, allowing you to mix uv-based functions with `pip`-based functions in the same AWS SAM template. If no build method is specified, `pip` is used by default.

# Building Lambda functions with custom runtimes in AWS SAM
<a name="building-custom-runtimes"></a>

You can use the `sam build` command to build custom runtimes required for your Lambda function. You declare your Lambda function to use a custom runtime by specifying `Runtime: provided` for the function.

To build a custom runtime, declare the `Metadata` resource attribute with a `BuildMethod: makefile` entry. You provide a custom makefile, where you declare a build target of the form `build-function-logical-id` that contains the build commands for your runtime. Your makefile is responsible for compiling the custom runtime if necessary, and copying the build artifacts into the proper location required for subsequent steps in your workflow. The location of the makefile is specified by the `CodeUri` property of the function resource, and must be named `Makefile`.

## Examples
<a name="building-custom-runtimes-examples"></a>

### Example 1: Custom runtime for a function written in Rust
<a name="building-custom-runtimes-examples-rust"></a>

**Note**  
We recommend building Lambda functions with Cargo Lambda. To learn more, see [Building Rust Lambda functions with Cargo Lambda in AWS SAM](building-rust.md).

The following AWS SAM template declares a function that uses a custom runtime for a Lambda function written in Rust, and instructs `sam build` to execute the commands for the `build-HelloRustFunction` build target.

```
Resources:
  HelloRustFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: HelloRust
      Handler: bootstrap.is.real.handler
      Runtime: provided
      MemorySize: 512
      CodeUri: .
    Metadata:
      BuildMethod: makefile
```

The following makefile contains the build target and commands that will be executed. Note that the `CodeUri` property is set to `.`, so the makefile must be located in the project root directory (that is, the same directory as the application's AWS SAM template file). The filename must be `Makefile`.

```
build-HelloRustFunction:
	cargo build --release --target x86_64-unknown-linux-musl
	cp ./target/x86_64-unknown-linux-musl/release/bootstrap $(ARTIFACTS_DIR)
```

For more information about setting up your development environment in order to execute the `cargo build` command in the previous `makefile`, see the [Rust Runtime for AWS Lambda](https://aws.amazon.com/blogs/opensource/rust-runtime-for-aws-lambda/) blog post.

### Example 2: Makefile builder for Python3.12 (alternative to using the bundled builder)
<a name="building-custom-runtimes-examples-python"></a>

You might want to use a library or module that is not included in a bundled builder. This example shows a AWS SAM template for a Python3.12 runtime with a makefile builder.

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.12
    Metadata:
      BuildMethod: makefile
```

The following makefile contains the build target and commands that will be executed. Note that the `CodeUri` property is set to `hello_world`, so the makefile must be located in the root of the `hello_world` subdirectory, and the filename must be `Makefile`.

```
build-HelloWorldFunction:
	cp *.py $(ARTIFACTS_DIR)
	cp requirements.txt $(ARTIFACTS_DIR)
	python -m pip install -r requirements.txt -t $(ARTIFACTS_DIR)
	rm -rf $(ARTIFACTS_DIR)/bin
```

# Building Lambda layers in AWS SAM
<a name="building-layers"></a>



You can use AWS SAM to build custom Lambda layers. Lambda layers allow you to extract code from a Lambda function that can then be re-used across several Lambda functions. Building only Lambda layers (instead of building your entire application) can benefit you in a few ways. It can help you reduce the size of your deployment packages, separate core function logic from dependencies, and allow you to share dependencies across multiple functions. For information about layers, see [AWS Lambda layers](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) in the *AWS Lambda Developer Guide*.

## How to build a Lambda layer in AWS SAM
<a name="w2aac18c23c19c34b7"></a>

**Note**  
Before you can build a Lambda layer, you must first write a Lambda layer in your AWS SAM template. For information and examples on doing this, see [Increase efficiency using Lambda layers with AWS SAM](serverless-sam-cli-layers.md).

To build a custom layer, declare it in your AWS Serverless Application Model (AWS SAM) template file and include a `Metadata` resource attribute section with a `BuildMethod` entry. Valid values for `BuildMethod` are identifiers for an [AWS Lambda runtime](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html), or `makefile`. Include a `BuildArchitecture` entry to specify the instruction set architectures that your layer supports. Valid values for `BuildArchitecture` are [Lambda instruction set architectures](https://docs.aws.amazon.com/lambda/latest/dg/foundation-arch.html).

If you specify `makefile`, provide the custom makefile, where you declare a build target of the form `build-layer-logical-id` that contains the build commands for your layer. Your makefile is responsible for compiling the layer if necessary, and copying the build artifacts into the proper location required for subsequent steps in your workflow. The location of the makefile is specified by the `ContentUri` property of the layer resource, and must be named `Makefile`.

**Note**  
When you create a custom layer, AWS Lambda depends on environment variables to find your layer code. Lambda runtimes include paths in the `/opt` directory where your layer code is copied into. Your project's build artifact folder structure must match the runtime's expected folder structure so your custom layer code can be found.  
For example, for Python you can place your code in the `python/` subdirectory. For NodeJS, you can place your code in the `nodejs/node_modules/` subdirectory.  
For more information, see [Including library dependencies in a layer](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-path) in the *AWS Lambda Developer Guide*.

The following is an example `Metadata` resource attribute section.

```
    Metadata:
      BuildMethod: python3.12
      BuildArchitecture: arm64
```

**Note**  
If you don't include the `Metadata` resource attribute section, AWS SAM doesn't build the layer. Instead, it copies the build artifacts from the location specified in the `CodeUri` property of the layer resource. For more information, see the [ContentUri](sam-resource-layerversion.md#sam-layerversion-contenturi) property of the `AWS::Serverless::LayerVersion` resource type.

When you include the `Metadata` resource attribute section, you can use the `sam build` command to build the layer, both as an independent object, or as a dependency of an AWS Lambda function.
+ ****As an independent object.**** You might want to build just the layer object, for example when you're locally testing a code change to the layer and don't need to build your entire application. To build the layer independently, specify the layer resource with the `sam build layer-logical-id` command.
+ **As a dependency of a Lambda function.** When you include a layer's logical ID in the `Layers` property of a Lambda function in the same AWS SAM template file, the layer is a dependency of that Lambda function. When that layer also includes a `Metadata` resource attribute section with a `BuildMethod` entry, you build the layer either by building the entire application with the `sam build` command or by specifying the function resource with the `sam build function-logical-id` command.

## Examples
<a name="building-applications-examples"></a>

### Template example 1: Build a layer against the Python 3.12 runtime environment
<a name="building-applications-examples-python"></a>

The following example AWS SAM template builds a layer against the Python 3.12 runtime environment.

```
Resources:
  MyLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      ContentUri: my_layer
      CompatibleRuntimes:
        - python3.12
    Metadata:
      BuildMethod: python3.12   # Required to have AWS SAM build this layer
```

### Template example 2: Build a layer using a custom makefile
<a name="building-applications-examples-makefile"></a>

The following example AWS SAM template uses a custom `makefile` to build the layer.

```
Resources:
  MyLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      ContentUri: my_layer
      CompatibleRuntimes:
        - python3.12
    Metadata:
      BuildMethod: makefile
```

The following `makefile` contains the build target and commands that will be executed. Note that the `ContentUri` property is set to `my_layer`, so the makefile must be located in the root of the `my_layer` subdirectory, and the filename must be `Makefile`. Note also that the build artifacts are copied into the `python/` subdirectory so that AWS Lambda will be able to find the layer code.

```
build-MyLayer:
  mkdir -p "$(ARTIFACTS_DIR)/python"
  cp *.py "$(ARTIFACTS_DIR)/python"
  python -m pip install -r requirements.txt -t "$(ARTIFACTS_DIR)/python"
```

**Note**  
When the `makefile` is called, the appropriate target is triggered and artifacts should be copied to the exposed environmental variable `$ARTIFACTS_DIR`. For more information, refer to [aws-lambda-builders in GitHub](https://github.com/aws/aws-lambda-builders/blob/develop/aws_lambda_builders/workflows/custom_make/DESIGN.md).

### Example sam build commands
<a name="building-applications-examples-commands"></a>

The following `sam build` commands build layers that include the `Metadata` resource attribute sections.

```
# Build the 'layer-logical-id' resource independently
$ sam build layer-logical-id
            
# Build the 'function-logical-id' resource and layers that this function depends on
$ sam build function-logical-id

# Build the entire application, including the layers that any function depends on
$ sam build
```