{"id":1016,"date":"2026-05-30T03:22:39","date_gmt":"2026-05-30T03:22:39","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/?p=1016"},"modified":"2026-05-30T03:22:41","modified_gmt":"2026-05-30T03:22:41","slug":"aws-sam-cli-complete-tutorial-from-basics-to-advanced","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/aws-sam-cli-complete-tutorial-from-basics-to-advanced\/","title":{"rendered":"AWS SAM CLI \u2014 Complete Tutorial from Basics to Advanced"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">AWS SAM CLI is a command-line tool used to <strong>create, build, test, debug, package, deploy, monitor, sync, and delete serverless applications on AWS<\/strong>. SAM stands for <strong>Serverless Application Model<\/strong>. AWS SAM itself is an open-source infrastructure-as-code framework built on top of AWS CloudFormation, and the SAM CLI is the developer tool you run locally. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/what-is-sam.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In simple words:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>AWS SAM = the serverless framework\/template syntax<\/strong><br><strong>AWS SAM CLI = the command-line tool used to work with SAM projects<\/strong><\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">1. What is AWS SAM CLI?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">AWS SAM CLI helps you work with serverless applications that commonly include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>AWS Lambda<\/li>\n\n\n\n<li>Amazon API Gateway<\/li>\n\n\n\n<li>Amazon DynamoDB<\/li>\n\n\n\n<li>Amazon SQS<\/li>\n\n\n\n<li>Amazon SNS<\/li>\n\n\n\n<li>Amazon EventBridge<\/li>\n\n\n\n<li>AWS Step Functions \/ durable workflows<\/li>\n\n\n\n<li>Lambda layers<\/li>\n\n\n\n<li>Lambda container images<\/li>\n\n\n\n<li>IAM permissions<\/li>\n\n\n\n<li>CloudFormation stacks<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">AWS SAM templates use simplified syntax for serverless resources. During deployment, SAM transforms that template into CloudFormation resources. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/what-is-sam.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, instead of writing a very large CloudFormation template for Lambda + API Gateway, SAM lets you write a smaller <code>AWS::Serverless::Function<\/code> resource.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">2. Why use AWS SAM CLI?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use AWS SAM CLI because it gives you a practical local-to-cloud workflow:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam init\nsam build\nsam local invoke\nsam local start-api\nsam deploy --guided\nsam logs\nsam delete\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AWS describes the core SAM CLI workflow as creating, building, testing, deploying, and syncing serverless applications. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/using-sam-cli-corecommands.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The big advantages are:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Benefit<\/th><th>Explanation<\/th><\/tr><\/thead><tbody><tr><td>Local testing<\/td><td>Run Lambda functions and API Gateway-style endpoints locally before deploying.<\/td><\/tr><tr><td>Infrastructure as code<\/td><td>Define Lambda, API Gateway, DynamoDB, permissions, outputs, and parameters in <code>template.yaml<\/code>.<\/td><\/tr><tr><td>Faster development<\/td><td>Use <code>sam sync --watch<\/code> to push local changes quickly to a development stack.<\/td><\/tr><tr><td>CloudFormation compatibility<\/td><td>SAM becomes CloudFormation during deployment, so you still get stacks, change sets, rollback, outputs, and drift-style IaC benefits.<\/td><\/tr><tr><td>Beginner-friendly serverless<\/td><td>Less boilerplate than raw CloudFormation for common Lambda\/API workloads.<\/td><\/tr><tr><td>CI\/CD support<\/td><td>SAM can generate pipeline configuration and bootstrap deployment resources.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3. Common AWS SAM CLI use cases<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">AWS SAM is useful for:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>REST APIs \/ HTTP APIs<\/strong><br>Example: API Gateway route <code>\/hello<\/code> invokes a Lambda function.<\/li>\n\n\n\n<li><strong>Event-driven processing<\/strong><br>Example: S3 upload triggers Lambda; SQS message triggers Lambda; EventBridge schedule triggers Lambda.<\/li>\n\n\n\n<li><strong>Serverless CRUD apps<\/strong><br>Example: API Gateway + Lambda + DynamoDB.<\/li>\n\n\n\n<li><strong>Background jobs<\/strong><br>Example: scheduled reports, file processing, async queue workers.<\/li>\n\n\n\n<li><strong>Local Lambda testing<\/strong><br>Example: invoke a Lambda function with a fake S3\/SQS\/API Gateway event.<\/li>\n\n\n\n<li><strong>Multi-environment deployments<\/strong><br>Example: <code>dev<\/code>, <code>staging<\/code>, and <code>prod<\/code> stacks with different parameters.<\/li>\n\n\n\n<li><strong>CI\/CD deployment pipelines<\/strong><br>Example: GitHub Actions, GitLab CI, Bitbucket Pipelines, AWS CodePipeline.<\/li>\n\n\n\n<li><strong>Migration from console-created serverless apps<\/strong><br>AWS mentions SAM as useful when moving console-created Lambda\/API Gateway resources into infrastructure as code. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/what-is-sam.html\">AWS Documentation<\/a>)<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4. AWS SAM vs AWS SAM CLI vs CloudFormation vs CDK<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Tool<\/th><th>What it is<\/th><th>Best for<\/th><\/tr><\/thead><tbody><tr><td>AWS SAM<\/td><td>Serverless IaC framework<\/td><td>Declarative serverless apps<\/td><\/tr><tr><td>AWS SAM CLI<\/td><td>Local CLI tool<\/td><td>Build, test, deploy, sync, debug<\/td><\/tr><tr><td>CloudFormation<\/td><td>General AWS IaC service<\/td><td>Any AWS infrastructure<\/td><\/tr><tr><td>AWS CDK<\/td><td>Programmatic IaC<\/td><td>Developers who prefer TypeScript\/Python\/Java\/etc.<\/td><\/tr><tr><td>Serverless Framework<\/td><td>Third-party framework<\/td><td>Multi-cloud or plugin-heavy workflows<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Use <strong>SAM<\/strong> when you want CloudFormation-compatible IaC with a simpler serverless syntax. AWS says SAM is useful when you want simplified serverless development while keeping CloudFormation power. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/what-is-sam.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5. Prerequisites<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Before using AWS SAM CLI, you need:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>An AWS account<\/li>\n\n\n\n<li>IAM credentials or IAM Identity Center access<\/li>\n\n\n\n<li>AWS CLI installed<\/li>\n\n\n\n<li>AWS credentials configured<\/li>\n\n\n\n<li>AWS SAM CLI installed<\/li>\n\n\n\n<li>Docker installed, if you want local Lambda-like containers or <code>sam build --use-container<\/code> (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/prerequisites.html\">AWS Documentation<\/a>)<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">AWS recommends temporary credentials where possible instead of long-term access keys. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/prerequisites.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6. Install AWS CLI<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Install AWS CLI first, then configure credentials.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Check installation:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws --version\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Configure credentials using the standard AWS CLI flow:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws configure\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You will be asked for:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>AWS Access Key ID\nAWS Secret Access Key\nDefault region name\nDefault output format\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws configure\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Suggested default output format:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>json\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check whether AWS credentials work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws sts get-caller-identity\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If this returns your AWS account\/user\/role info, your AWS CLI credentials are working.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7. Install Docker<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Docker is needed for the best local testing experience. AWS SAM can use Docker to provide a local environment similar to AWS Lambda. Docker is required for local testing and for <code>sam build --use-container<\/code>. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/install-docker.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Check Docker:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker --version\ndocker ps\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If <code>docker ps<\/code> fails, Docker may not be running.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8. Install AWS SAM CLI<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Linux<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Example official installer flow:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unzip aws-sam-cli-linux-x86_64.zip -d sam-installation\nsudo .\/sam-installation\/install\nsam --version\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AWS provides separate installers for Linux <code>x86_64<\/code> and <code>arm64<\/code>. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/install-sam-cli.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">macOS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For macOS, AWS provides <code>.pkg<\/code> installers for Intel and Apple Silicon. AWS notes that the old AWS-managed Homebrew installer <code>aws\/tap\/aws-sam-cli<\/code> is no longer maintained by AWS. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/install-sam-cli.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>which sam\nsam --version\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Windows<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Install the Windows MSI package, then open a new PowerShell or Command Prompt and run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam --version\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AWS documents Windows installation using MSI files. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/install-sam-cli.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">9. Verify the full setup<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws --version\nsam --version\ndocker --version\naws sts get-caller-identity\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected result:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>aws --version<\/code> shows AWS CLI version<\/li>\n\n\n\n<li><code>sam --version<\/code> shows SAM CLI version<\/li>\n\n\n\n<li><code>docker --version<\/code> shows Docker version<\/li>\n\n\n\n<li><code>aws sts get-caller-identity<\/code> returns AWS account identity<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">10. Basic AWS SAM project structure<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">When you run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam init\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">SAM creates a project directory. AWS says <code>sam init<\/code> creates a SAM template, organized folder structure, and Lambda function configuration. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/using-sam-cli-init.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Typical structure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam-app\/\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 events\/\n\u2502   \u2514\u2500\u2500 event.json\n\u251c\u2500\u2500 hello_world\/\n\u2502   \u251c\u2500\u2500 app.py\n\u2502   \u2514\u2500\u2500 requirements.txt\n\u251c\u2500\u2500 tests\/\n\u251c\u2500\u2500 template.yaml\n\u2514\u2500\u2500 samconfig.toml\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Important files:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>File\/folder<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td><code>template.yaml<\/code><\/td><td>Main SAM infrastructure template<\/td><\/tr><tr><td><code>hello_world\/<\/code><\/td><td>Lambda function source code<\/td><\/tr><tr><td><code>events\/<\/code><\/td><td>Sample event JSON files for local testing<\/td><\/tr><tr><td><code>tests\/<\/code><\/td><td>Unit tests<\/td><\/tr><tr><td><code>samconfig.toml<\/code><\/td><td>Saved SAM CLI configuration<\/td><\/tr><tr><td><code>.aws-sam\/<\/code><\/td><td>Build output directory created by <code>sam build<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">11. Create your first SAM application<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam init\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You will get an interactive wizard. Choose something like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Template source: AWS Quick Start Templates\nApplication template: Hello World Example\nRuntime: Python \/ Node.js \/ Java \/ .NET \/ Go\nPackage type: Zip\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then enter the project:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd sam-app\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">12. Understand <code>template.yaml<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A basic SAM template looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>AWSTemplateFormatVersion: '2010-09-09'\nTransform: AWS::Serverless-2016-10-31\nDescription: Basic AWS SAM application\n\nGlobals:\n  Function:\n    Timeout: 10\n    MemorySize: 128\n    Runtime: python3.12\n\nResources:\n  HelloWorldFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      CodeUri: hello_world\/\n      Handler: app.lambda_handler\n      Events:\n        HelloApi:\n          Type: Api\n          Properties:\n            Path: \/hello\n            Method: get\n\nOutputs:\n  HelloWorldApi:\n    Description: API Gateway endpoint URL\n    Value: !Sub \"https:\/\/${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com\/Prod\/hello\/\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Key parts:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Section<\/th><th>Meaning<\/th><\/tr><\/thead><tbody><tr><td><code>Transform<\/code><\/td><td>Required SAM transform declaration<\/td><\/tr><tr><td><code>Globals<\/code><\/td><td>Shared configuration inherited by resources<\/td><\/tr><tr><td><code>Resources<\/code><\/td><td>AWS resources to create<\/td><\/tr><tr><td><code>AWS::Serverless::Function<\/code><\/td><td>SAM shorthand for Lambda function and event mapping<\/td><\/tr><tr><td><code>Events<\/code><\/td><td>Triggers for the Lambda function<\/td><\/tr><tr><td><code>Outputs<\/code><\/td><td>Values printed after deployment<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">SAM templates closely follow CloudFormation templates, but add SAM-specific sections such as the required transform and <code>Globals<\/code>. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/sam-specification-template-anatomy.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">13. Basic Lambda function code<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Example Python Lambda handler:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import json\n\ndef lambda_handler(event, context):\n    return {\n        \"statusCode\": 200,\n        \"headers\": {\n            \"Content-Type\": \"application\/json\"\n        },\n        \"body\": json.dumps({\n            \"message\": \"Hello from AWS SAM CLI!\"\n        })\n    }\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The handler name in <code>template.yaml<\/code> must match:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Handler: app.lambda_handler\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That means:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>file: app.py\nfunction: lambda_handler\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Tiny mismatch here = classic Lambda faceplant. Ask me how every developer learns this. Painfully.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">14. Build the application<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam build\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This prepares the application for local testing or deployment. AWS describes <code>sam build<\/code> as preparing an application for later developer workflow steps such as local testing or cloud deployment. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/sam-cli-command-reference-sam-build.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After build, SAM creates:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.aws-sam\/\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You usually do not edit <code>.aws-sam<\/code> manually.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use container-based build:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam build --use-container\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use this when you want dependencies built inside a Lambda-like environment.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">15. Invoke Lambda locally<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use a sample event file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam local invoke HelloWorldFunction --event events\/event.json\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Or invoke with an empty event:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam local invoke HelloWorldFunction\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Generate a test event:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam local generate-event apigateway aws-proxy &gt; events\/api-event.json\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then invoke:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam local invoke HelloWorldFunction --event events\/api-event.json\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">16. Run API Gateway locally<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Start local API:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam local start-api\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then call it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/127.0.0.1:3000\/hello\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use custom port:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam local start-api --port 4000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/127.0.0.1:4000\/hello\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AWS SAM local testing lets you test before uploading to AWS, which helps catch issues earlier and avoid unnecessary deployment\/debugging cost. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/serverless-test-and-debug.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">17. Validate the SAM template<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam validate\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For stricter lint-style validation:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam validate --lint\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use this before deployment, especially in CI\/CD.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">18. Deploy for the first time<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use guided deployment:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy --guided\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AWS recommends <code>sam deploy --guided<\/code> for the first deployment because it prompts for deployment settings and saves them into <code>samconfig.toml<\/code>. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/using-sam-cli-deploy.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Typical prompts:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Stack Name: sam-app\nAWS Region: us-east-1\nConfirm changes before deploy: Y\nAllow SAM CLI IAM role creation: Y\nDisable rollback: N\nSave arguments to configuration file: Y\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After this, future deployments are usually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam build\nsam deploy\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">19. What happens during deployment?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">When you deploy:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>SAM packages your Lambda code.<\/li>\n\n\n\n<li>SAM uploads artifacts to S3 or ECR.<\/li>\n\n\n\n<li>SAM creates a CloudFormation change set.<\/li>\n\n\n\n<li>CloudFormation creates or updates your AWS resources.<\/li>\n\n\n\n<li>SAM prints stack outputs.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">AWS documents that zip-based Lambda artifacts go to S3, image-based functions go to ECR, and the app is deployed as a CloudFormation stack. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/using-sam-cli-deploy.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">20. Test the deployed API<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">After deployment, SAM prints outputs. You may see something like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>HelloWorldApi = https:\/\/abc123.execute-api.us-east-1.amazonaws.com\/Prod\/hello\/\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Test:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl https:\/\/abc123.execute-api.us-east-1.amazonaws.com\/Prod\/hello\/\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">21. View logs<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Basic logs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam logs\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Logs for a specific function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam logs -n HelloWorldFunction\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Tail logs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam logs -n HelloWorldFunction --tail\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Include start time:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam logs -n HelloWorldFunction --start-time \"10min ago\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">22. Delete the application<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">To remove deployed resources:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam delete\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This deletes the CloudFormation stack and related resources that SAM can clean up.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">23. The most important everyday workflow<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">For most developers:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam init\ncd sam-app\nsam build\nsam local start-api\nsam deploy --guided\nsam logs --tail\nsam delete\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For ongoing development:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam build\nsam local invoke HelloWorldFunction\nsam deploy\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Or for faster cloud development:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam sync --watch\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AWS recommends <code>sam sync<\/code> for development environments, while production should use <code>sam deploy<\/code> or CI\/CD. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/using-sam-cli-sync.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">24. <code>samconfig.toml<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><code>samconfig.toml<\/code> stores project-level SAM CLI settings.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>version = 0.1<\/code><\/pre>\n\n\n<p>[default.global.parameters]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">stack_name = &#8220;sam-app&#8221;<\/p>\n\n\n<p>[default.build.parameters]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">cached = true parallel = true<\/p>\n\n\n<p>[default.deploy.parameters]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">capabilities = &#8220;CAPABILITY_IAM&#8221; confirm_changeset = true resolve_s3 = true region = &#8220;us-east-1&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">SAM config files are usually named <code>samconfig<\/code>, live at the project root near <code>template.yaml<\/code>, and commonly use TOML, though YAML\/YML is also supported. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/serverless-sam-cli-config.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use a different environment:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy --config-env dev\nsam deploy --config-env prod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example multi-environment config:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>version = 0.1<\/code><\/pre>\n\n\n<p>[dev.deploy.parameters]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">stack_name = &#8220;myapp-dev&#8221; region = &#8220;us-east-1&#8221; capabilities = &#8220;CAPABILITY_IAM&#8221; resolve_s3 = true<\/p>\n\n\n<p>[prod.deploy.parameters]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">stack_name = &#8220;myapp-prod&#8221; region = &#8220;us-east-1&#8221; capabilities = &#8220;CAPABILITY_IAM&#8221; resolve_s3 = true confirm_changeset = true<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Deploy dev:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy --config-env dev\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Deploy prod:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy --config-env prod\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">25. Add environment variables<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">In <code>template.yaml<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Globals:\n  Function:\n    Runtime: python3.12\n    Timeout: 10\n    Environment:\n      Variables:\n        STAGE: dev\n        LOG_LEVEL: info\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Inside Python:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\n\nstage = os.environ.get(\"STAGE\", \"local\")\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For local testing, create <code>env.json<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"HelloWorldFunction\": {\n    \"STAGE\": \"local\",\n    \"LOG_LEVEL\": \"debug\"\n  }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam local invoke HelloWorldFunction --env-vars env.json\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">26. Add API Gateway routes<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Example with two routes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Resources:\n  GetUsersFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      CodeUri: users\/\n      Handler: app.get_users\n      Runtime: python3.12\n      Events:\n        GetUsersApi:\n          Type: Api\n          Properties:\n            Path: \/users\n            Method: get\n\n  CreateUserFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      CodeUri: users\/\n      Handler: app.create_user\n      Runtime: python3.12\n      Events:\n        CreateUserApi:\n          Type: Api\n          Properties:\n            Path: \/users\n            Method: post\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Local test:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam build\nsam local start-api\ncurl http:\/\/127.0.0.1:3000\/users\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">POST test:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -X POST http:\/\/127.0.0.1:3000\/users \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\"name\":\"Rajesh\"}'\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">27. Add DynamoDB<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Example table:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Resources:\n  UsersTable:\n    Type: AWS::DynamoDB::Table\n    Properties:\n      TableName: !Sub \"${AWS::StackName}-users\"\n      BillingMode: PAY_PER_REQUEST\n      AttributeDefinitions:\n        - AttributeName: userId\n          AttributeType: S\n      KeySchema:\n        - AttributeName: userId\n          KeyType: HASH\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Give Lambda permission:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  CreateUserFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      CodeUri: users\/\n      Handler: app.create_user\n      Runtime: python3.12\n      Environment:\n        Variables:\n          TABLE_NAME: !Ref UsersTable\n      Policies:\n        - DynamoDBCrudPolicy:\n            TableName: !Ref UsersTable\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">SAM supports policy templates and connectors to simplify permissions between resources. AWS recommends connectors and policy templates where supported because they reduce the amount of IAM expertise needed. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/sam-permissions.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">28. Add SQS event trigger<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>Resources:\n  OrdersQueue:\n    Type: AWS::SQS::Queue\n\n  ProcessOrderFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      CodeUri: orders\/\n      Handler: app.lambda_handler\n      Runtime: python3.12\n      Events:\n        OrdersQueueEvent:\n          Type: SQS\n          Properties:\n            Queue: !GetAtt OrdersQueue.Arn\n            BatchSize: 10\n      Policies:\n        - SQSPollerPolicy:\n            QueueName: !GetAtt OrdersQueue.QueueName\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">29. Add scheduled EventBridge trigger<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>Resources:\n  DailyJobFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      CodeUri: jobs\/\n      Handler: app.lambda_handler\n      Runtime: python3.12\n      Events:\n        DailySchedule:\n          Type: Schedule\n          Properties:\n            Schedule: rate(1 day)\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">30. Lambda layers<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Layer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Resources:\n  CommonLayer:\n    Type: AWS::Serverless::LayerVersion\n    Properties:\n      LayerName: common-utils\n      Description: Shared Python utilities\n      ContentUri: layers\/common\/\n      CompatibleRuntimes:\n        - python3.12\n\n  MyFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      CodeUri: app\/\n      Handler: app.lambda_handler\n      Runtime: python3.12\n      Layers:\n        - !Ref CommonLayer\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Typical layer folder:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>layers\/\n\u2514\u2500\u2500 common\/\n    \u2514\u2500\u2500 python\/\n        \u2514\u2500\u2500 my_utils.py\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">31. Container image Lambda with SAM<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of zip package:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Resources:\n  ImageFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      PackageType: Image\n      Timeout: 30\n    Metadata:\n      Dockerfile: Dockerfile\n      DockerContext: .\/image-function\n      DockerTag: python3.12-v1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Build:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam build\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Deploy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy --guided\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">SAM deploy uploads zip artifacts to S3 and image artifacts to ECR as needed. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/using-sam-cli-deploy.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">32. Faster development with <code>sam sync<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">First deploy normally:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam build\nsam deploy --guided\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam sync --watch\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This watches local changes and syncs them to AWS. AWS says <code>sam sync --watch<\/code> builds, deploys, watches local changes, and syncs changes through the quickest available method. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/using-sam-cli-sync.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use this for development stacks only:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam sync --stack-name myapp-dev --watch\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">One-time sync:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam sync --no-watch\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">33. Remote testing<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Invoke deployed function in AWS:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam remote invoke HelloWorldFunction --stack-name sam-app\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With event file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam remote invoke HelloWorldFunction \\\n  --stack-name sam-app \\\n  --event-file events\/event.json\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AWS documents <code>sam remote invoke<\/code> for interacting with Lambda functions already deployed in the AWS Cloud. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/using-sam-cli-remote-invoke.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">34. Shareable remote test events<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">List remote test events:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam remote test-event list HelloWorldFunction --stack-name sam-app\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Save local event to AWS:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam remote test-event put HelloWorldFunction \\\n  --stack-name sam-app \\\n  --name demo-event \\\n  --file events\/event.json\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Invoke using saved event:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam remote invoke HelloWorldFunction \\\n  --stack-name sam-app \\\n  --test-event-name demo-event\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AWS documents <code>sam remote test-event<\/code> subcommands for <code>delete<\/code>, <code>get<\/code>, <code>list<\/code>, and <code>put<\/code>. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/using-sam-cli-remote-test-event.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">35. CI\/CD with SAM pipeline<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Bootstrap deployment resources:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam pipeline bootstrap\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Generate pipeline config:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam pipeline init\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AWS says <code>sam pipeline bootstrap<\/code> sets up infrastructure resources needed for CI\/CD deployment, and <code>sam pipeline init<\/code> generates pipeline configuration for your CI\/CD system. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/sam-cli-command-reference-sam-pipeline-bootstrap.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Typical flow:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam pipeline bootstrap\nsam pipeline init\ngit add .\ngit commit -m \"Add SAM pipeline\"\ngit push\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">36. Monitoring and troubleshooting<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">CloudWatch logs<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam logs -n HelloWorldFunction --stack-name sam-app --tail\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">X-Ray traces<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam traces\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Validate template<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam validate --lint\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Confirm deployed resources<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam list resources --stack-name sam-app\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Confirm stack outputs<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam list stack-outputs --stack-name sam-app\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">37. All major AWS SAM CLI commands<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The official SAM CLI command reference currently includes these commands and subcommand groups. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/serverless-sam-cli-command-reference.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Command<\/th><th>Purpose<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td><code>sam init<\/code><\/td><td>Create new SAM project<\/td><td><code>sam init<\/code><\/td><\/tr><tr><td><code>sam build<\/code><\/td><td>Build app artifacts<\/td><td><code>sam build<\/code><\/td><\/tr><tr><td><code>sam validate<\/code><\/td><td>Validate SAM template<\/td><td><code>sam validate --lint<\/code><\/td><\/tr><tr><td><code>sam local generate-event<\/code><\/td><td>Generate sample event payloads<\/td><td><code>sam local generate-event s3 put<\/code><\/td><\/tr><tr><td><code>sam local invoke<\/code><\/td><td>Invoke Lambda locally<\/td><td><code>sam local invoke MyFunction<\/code><\/td><\/tr><tr><td><code>sam local start-api<\/code><\/td><td>Run local API Gateway-style server<\/td><td><code>sam local start-api<\/code><\/td><\/tr><tr><td><code>sam local start-lambda<\/code><\/td><td>Run local Lambda endpoint for AWS CLI\/SDK testing<\/td><td><code>sam local start-lambda<\/code><\/td><\/tr><tr><td><code>sam local callback<\/code><\/td><td>Work with local durable-function callbacks<\/td><td><code>sam local callback --help<\/code><\/td><\/tr><tr><td><code>sam local execution<\/code><\/td><td>Work with local durable-function executions<\/td><td><code>sam local execution --help<\/code><\/td><\/tr><tr><td><code>sam deploy<\/code><\/td><td>Deploy app using CloudFormation<\/td><td><code>sam deploy --guided<\/code><\/td><\/tr><tr><td><code>sam package<\/code><\/td><td>Package app artifacts manually<\/td><td><code>sam package<\/code><\/td><\/tr><tr><td><code>sam sync<\/code><\/td><td>Sync local changes to AWS dev stack<\/td><td><code>sam sync --watch<\/code><\/td><\/tr><tr><td><code>sam logs<\/code><\/td><td>Fetch\/tail CloudWatch logs<\/td><td><code>sam logs --tail<\/code><\/td><\/tr><tr><td><code>sam traces<\/code><\/td><td>Fetch AWS X-Ray traces<\/td><td><code>sam traces<\/code><\/td><\/tr><tr><td><code>sam list<\/code><\/td><td>List stack resources\/endpoints\/outputs<\/td><td><code>sam list resources<\/code><\/td><\/tr><tr><td><code>sam remote invoke<\/code><\/td><td>Invoke deployed cloud resource<\/td><td><code>sam remote invoke MyFunction<\/code><\/td><\/tr><tr><td><code>sam remote test-event<\/code><\/td><td>Manage shareable Lambda test events<\/td><td><code>sam remote test-event list MyFunction<\/code><\/td><\/tr><tr><td><code>sam remote callback<\/code><\/td><td>Manage callbacks for remote durable executions<\/td><td><code>sam remote callback --help<\/code><\/td><\/tr><tr><td><code>sam remote execution<\/code><\/td><td>Inspect\/manage remote durable executions<\/td><td><code>sam remote execution --help<\/code><\/td><\/tr><tr><td><code>sam pipeline bootstrap<\/code><\/td><td>Create CI\/CD deployment resources<\/td><td><code>sam pipeline bootstrap<\/code><\/td><\/tr><tr><td><code>sam pipeline init<\/code><\/td><td>Generate CI\/CD pipeline config<\/td><td><code>sam pipeline init<\/code><\/td><\/tr><tr><td><code>sam publish<\/code><\/td><td>Publish app to Serverless Application Repository<\/td><td><code>sam publish<\/code><\/td><\/tr><tr><td><code>sam delete<\/code><\/td><td>Delete deployed SAM app<\/td><td><code>sam delete<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Useful global commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam --version\nsam --help\nsam &lt;command&gt; --help\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Examples:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy --help\nsam local invoke --help\nsam sync --help\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">38. Practical command cheat sheet<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Create app<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam init\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Build<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam build\nsam build --cached\nsam build --parallel\nsam build --use-container\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Test locally<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam local invoke FunctionName\nsam local invoke FunctionName --event events\/event.json\nsam local start-api\nsam local start-api --port 4000\nsam local generate-event apigateway aws-proxy\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Validate<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam validate\nsam validate --lint\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Deploy<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy --guided\nsam deploy\nsam deploy --config-env dev\nsam deploy --stack-name my-stack --region us-east-1\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Sync<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam sync --watch\nsam sync --no-watch\nsam sync --stack-name myapp-dev --watch\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Logs<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam logs\nsam logs -n FunctionName\nsam logs -n FunctionName --tail\nsam logs -n FunctionName --start-time \"10min ago\"\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Remote invoke<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam remote invoke FunctionName --stack-name my-stack\nsam remote invoke FunctionName --stack-name my-stack --event-file events\/event.json\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">List<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam list resources --stack-name my-stack\nsam list endpoints --stack-name my-stack\nsam list stack-outputs --stack-name my-stack\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Pipeline<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam pipeline bootstrap\nsam pipeline init\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Cleanup<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam delete\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">39. Best practices<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">1. Always build before deploy<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam build\nsam deploy\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AWS specifically notes that <code>sam deploy<\/code> deploys artifacts from <code>.aws-sam<\/code>, so after changing original files you should run <code>sam build<\/code> before deploying. (<a href=\"https:\/\/docs.aws.amazon.com\/serverless-application-model\/latest\/developerguide\/using-sam-cli-deploy.html\">AWS Documentation<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Use <code>sam deploy --guided<\/code> first<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">First time:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy --guided\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After that:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">3. Use <code>sam sync --watch<\/code> only for development<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Good:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam sync --watch\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Not ideal for production. For production, prefer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">or CI\/CD.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Use least-privilege IAM<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Avoid giving every function broad permissions like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Policies:\n  - AdministratorAccess\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Prefer scoped policies:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Policies:\n  - DynamoDBReadPolicy:\n      TableName: !Ref UsersTable\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">5. Separate environments<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use separate stacks:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>myapp-dev\nmyapp-staging\nmyapp-prod\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">6. Keep secrets out of templates<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Do not hardcode passwords\/API keys in <code>template.yaml<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Prefer:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>AWS Secrets Manager<\/li>\n\n\n\n<li>AWS Systems Manager Parameter Store<\/li>\n\n\n\n<li>Environment variables referencing secure values<\/li>\n\n\n\n<li>IAM roles<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">7. Add outputs<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Always output useful deployed URLs\/resources:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Outputs:\n  ApiUrl:\n    Value: !Sub \"https:\/\/${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com\/Prod\/\"\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">8. Use <code>sam validate --lint<\/code> in CI<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam validate --lint\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">9. Delete unused stacks<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam delete\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This avoids surprise AWS charges.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">40. Beginner project: API Gateway + Lambda<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Create project<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam init\ncd sam-app\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Build<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam build\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Run locally<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam local start-api\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Test<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/127.0.0.1:3000\/hello\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Deploy<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy --guided\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 6: View logs<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam logs -n HelloWorldFunction --tail\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 7: Cleanup<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sam delete\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">41. Intermediate project: API Gateway + Lambda + DynamoDB<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Architecture:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Client\n  \u2193\nAPI Gateway\n  \u2193\nLambda\n  \u2193\nDynamoDB\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Template idea:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Resources:\n  UsersTable:\n    Type: AWS::DynamoDB::Table\n    Properties:\n      BillingMode: PAY_PER_REQUEST\n      AttributeDefinitions:\n        - AttributeName: userId\n          AttributeType: S\n      KeySchema:\n        - AttributeName: userId\n          KeyType: HASH\n\n  CreateUserFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      CodeUri: users\/\n      Handler: app.create_user\n      Runtime: python3.12\n      Environment:\n        Variables:\n          TABLE_NAME: !Ref UsersTable\n      Policies:\n        - DynamoDBCrudPolicy:\n            TableName: !Ref UsersTable\n      Events:\n        CreateUserApi:\n          Type: Api\n          Properties:\n            Path: \/users\n            Method: post\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Deploy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam build\nsam deploy --guided\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">42. Advanced project: Async queue worker<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Architecture:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>API Gateway\n  \u2193\nSubmitOrderFunction\n  \u2193\nSQS Queue\n  \u2193\nProcessOrderFunction\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This pattern is good for long-running or retryable work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Key benefits:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>API responds quickly<\/li>\n\n\n\n<li>SQS buffers work<\/li>\n\n\n\n<li>Lambda processes asynchronously<\/li>\n\n\n\n<li>Failed messages can go to a dead-letter queue<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">43. Common errors and fixes<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Error: Docker is not running<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fix:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker ps\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Start Docker Desktop or Docker daemon.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Error: Unable to locate credentials<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fix:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws configure\naws sts get-caller-identity\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Error: Handler not found<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Check:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Handler: app.lambda_handler\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Must match:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app.py\nlambda_handler()\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Error: Runtime mismatch<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If template says:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Runtime: python3.12\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Make sure local build has compatible Python, or use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam build --use-container\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Error: IAM role creation not allowed<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Deploy with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy --guided\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When prompted:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Allow SAM CLI IAM role creation: Y\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The deployment may require:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CAPABILITY_IAM\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Error: Stack already exists<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use a different stack name:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam deploy --guided\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">or delete the old one:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam delete\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">44. Recommended learning path<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Follow this order:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Learn Lambda basics.<\/li>\n\n\n\n<li>Learn API Gateway basics.<\/li>\n\n\n\n<li>Install AWS CLI, Docker, and SAM CLI.<\/li>\n\n\n\n<li>Run <code>sam init<\/code>.<\/li>\n\n\n\n<li>Understand <code>template.yaml<\/code>.<\/li>\n\n\n\n<li>Run <code>sam build<\/code>.<\/li>\n\n\n\n<li>Run <code>sam local invoke<\/code>.<\/li>\n\n\n\n<li>Run <code>sam local start-api<\/code>.<\/li>\n\n\n\n<li>Deploy with <code>sam deploy --guided<\/code>.<\/li>\n\n\n\n<li>Read logs with <code>sam logs<\/code>.<\/li>\n\n\n\n<li>Add DynamoDB.<\/li>\n\n\n\n<li>Add SQS\/EventBridge triggers.<\/li>\n\n\n\n<li>Use multiple environments.<\/li>\n\n\n\n<li>Use <code>sam sync --watch<\/code>.<\/li>\n\n\n\n<li>Add CI\/CD with <code>sam pipeline<\/code>.<\/li>\n\n\n\n<li>Practice cleanup with <code>sam delete<\/code>.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">45. Final mental model<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Think of AWS SAM CLI like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>template.yaml       = What AWS resources should exist\nfunction code       = What your Lambda does\nsam build           = Prepare code and dependencies\nsam local invoke    = Test Lambda locally\nsam local start-api = Test API locally\nsam deploy          = Create\/update AWS resources\nsam logs            = Debug deployed Lambda\nsam sync            = Fast dev loop against AWS\nsam delete          = Clean up\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The normal professional workflow is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sam init\nsam build\nsam local invoke\nsam local start-api\nsam deploy --guided\nsam logs --tail\nsam sync --watch\nsam delete\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s the core of AWS SAM CLI: <strong>local development, infrastructure as code, repeatable deployment, and serverless debugging without living inside the AWS Console all day.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>AWS SAM CLI is a command-line tool used to create, build, test, debug, package, deploy, monitor, sync, and delete serverless applications on AWS. SAM stands for Serverless&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1016","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1016","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=1016"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1016\/revisions"}],"predecessor-version":[{"id":1017,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1016\/revisions\/1017"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=1016"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=1016"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=1016"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}