{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreictmwup4vwbo5e35kcki4niw6njovazoqbr6iucg2mbenbn2ffm2u",
    "uri": "at://did:plc:25rdn5elo5izoxrmtis34zuk/app.bsky.feed.post/3mplv4qpks7b2"
  },
  "coverImage": {
    "$type": "blob",
    "ref": {
      "$link": "bafkreiav37wkk6he2azleyytj23dfwfdpaxkpe3z6xowjz7ruexkbvbmk4"
    },
    "mimeType": "image/webp",
    "size": 57300
  },
  "path": "/aws-builders/prepare-application-artifacts-to-be-deployed-to-aws-build-a-multi-environment-serverless-app-5cj2",
  "publishedAt": "2026-07-01T15:49:12.000Z",
  "site": "https://dev.to",
  "tags": [
    "aws",
    "cloud",
    "certification",
    "developer",
    "An AWS Account",
    "Docker Installed Locally",
    "SAM CLI Installed",
    "Deploying Lambda functions as .zip file archives",
    "Managing Lambda dependencies with layers",
    "What is the AWS Serverless Application Model (AWS SAM)?",
    "What is AWS AppConfig?",
    "Create a Lambda function using a container image",
    "AWS SAM CLI configuration file"
  ],
  "textContent": "**Exam Guide:** Developer - Associate\n**πŸ—οΈ Domain 3:** **_Deployment_**\nπŸ“˜ **Task 1:** _Prepare Application Artifacts To Be Deployed To AWS_\n\n> **Before you can deploy anything to AWS, you need to package it properly. This task covers Lambda deployment packaging (zip vs container), managing dependencies, structuring projects for multi-environment deployment, and using AWS AppConfig for runtime configuration.**\n\n##  πŸ“˜Concepts\n\n###  Lambda Deployment Packaging Options\n\nOption | Max Size | Build Complexity | Cold Start | Best For\n---|---|---|---|---\n**Zip Package** _(inline editor)_ | 3 MB (editor limit) | None | Fastest | Simple functions, no dependencies\n**Zip Package** _(upload)_ | 50 MB compressed / 250 MB uncompressed | Low | Fast | Most Lambda functions\n**Zip + Lambda Layers** | 250 MB total (function + all layers) | Medium | Fast | Shared dependencies across functions\n**Container Image** | 10 GB | Higher | Slower (first invoke) | ML libraries, large dependencies, custom runtimes\n\n> πŸ’‘**If a scenario is about a deployment package exceeding 250 MB, the answer is container images. If it mentions sharing dependencies across multiple functions, the answer is Lambda Layers. Zip is the default for most workloads.**\n\n###  Lambda Layers\n\n**Aspect** | _Detail_\n---|---\n**What They Are** | _Zip archives containing libraries, custom runtimes, or other dependencies_\n**Max Layers Per Function** | _5_\n**Size Limit** |  _250 MB total_ (function code + all layers uncompressed)\n**Versioning** | _Each publish creates an immutable version_\n**Sharing** | _Can be shared across functions, accounts, or made public_\n**Path** | _Contents extracted to`/opt` in the execution environment_\n\n###  Dependency Management Strategies\n\n**Strategy** | _How It Works_ | Pros | Cons\n---|---|---|---\n**Bundle In Zip** | _Install deps into package directory, zip together_ | Simple, self-contained | Larger package, duplicated across functions\n**Lambda Layers** | _Package deps as a layer, attach to functions_ | Shared across functions, smaller deploys | Layer version management, 5-layer limit\n**Container Image** | _Install deps in Dockerfile_ | Full control, large deps supported | Slower cold starts, ECR management\n**sam build** | _SAM resolves deps from requirements.txt automatically_ | Easiest, handles everything | Requires SAM CLI\n\n###  Environment-Specific Configuration Approaches\n\n**Approach** | _When Config Is Resolved_ | Best For\n---|---|---\n**SAM Parameters + samconfig.toml** | _Deploy time_ | Resource names, table names, stage-specific infra\n**Lambda Environment Variables** |  _Deploy time_ (baked into function config) | Simple key-value config per environment\n**SSM Parameter Store** |  _Runtime_ (fetched by function) | Config that changes without redeployment\n**AWS AppConfig** |  _Runtime_ (with gradual rollout) | Feature flags, config that needs validation and rollback\n**Secrets Manager** |  _Runtime_ (fetched by function) | Credentials that rotate\n\n> πŸ’‘ **If the question is _change configuration without redeploying_ , the answer is Parameter Store or AppConfig. If it says _gradual rollout_ or _validate configuration before applying,_ the answer is AppConfig.**\n\n###  AWS AppConfig Overview\n\n**Feature** | _Detail_\n---|---\n**What It Does** | _Deploy configuration changes independently from code, with validation and rollout strategies_\n**Deployment Strategies** | _AllAtOnce, Linear, Exponential_\n**Validators** | _JSON Schema or Lambda function to validate config before deployment_\n**Rollback** | _Automatic rollback if CloudWatch alarm triggers during deployment_\n**Integration** | _Lambda extension for caching, or direct API calls_\n**Cost** | _Free for configuration retrieval. Charges for feature flag evaluations_\n\n###  Project Structure Best Practices\n\nA well-structured SAM project separates handlers, shared code, tests, and configuration:\n\n\n\n    my-app/\n    β”œβ”€β”€ template.yaml              # SAM/CloudFormation template\n    β”œβ”€β”€ samconfig.toml             # Per-environment deployment config\n    β”œβ”€β”€ src/\n    β”‚   β”œβ”€β”€ handlers/              # One file per Lambda function\n    β”‚   β”‚   β”œβ”€β”€ create_order.py\n    β”‚   β”‚   β”œβ”€β”€ get_order.py\n    β”‚   β”‚   └── process_payment.py\n    β”‚   └── shared/                # Shared utilities across handlers\n    β”‚       β”œβ”€β”€ models.py\n    β”‚       └── utils.py\n    β”œβ”€β”€ tests/\n    β”‚   β”œβ”€β”€ unit/                  # Fast, no AWS calls\n    β”‚   β”‚   β”œβ”€β”€ test_create_order.py\n    β”‚   β”‚   └── test_get_order.py\n    β”‚   └── integration/           # Against deployed resources\n    β”‚       └── test_api.py\n    β”œβ”€β”€ events/                    # Sample event payloads for testing\n    β”‚   β”œβ”€β”€ create_order.json\n    β”‚   └── get_order.json\n    └── requirements.txt           # Python dependencies\n\n\n##  πŸ—οΈ Build A Multi-Environment Serverless App\n\nBuild a **Multi-Environment Serverless App** that demonstrates real-world packaging and deployment patterns:\n\n  * A Lambda function packaged with dependencies via zip upload in the console\n  * A container image built and pushed to ECR\n  * AWS AppConfig set up with feature flags and a deployment strategy\n  * A SAM project structured for multi-environment deployment\n  * A `samconfig.toml` configured for dev, staging, and prod\n\n\n\n##  Prerequisites\n\n  * An AWS Account\n  * Docker Installed Locally\n  * SAM CLI Installed\n\n\n\n##  Part I\n\n###  Package a Lambda Function with Dependencies (Zip Upload)\n\n####  Create the Deployment Package Locally\n\nCreate a zip file on your local machine and upload it through the console.\n\n> ⚠️ **Common Windows mistake:** Don't create the zip with Explorer (right-click β†’ Send to β†’ Compressed folder). That wraps everything inside a subfolder, so your handler ends up at `package/lambda_function.py` and Lambda throws `No module named 'lambda_function'`. Rather build the zip in CloudShell.\n\n**Step 01:** Create a project directory and install dependencies\n\n\n\n    mkdir lambda-package && cd lambda-package\n\n    # Create requirements.txt\n    cat > requirements.txt << 'EOF'\n    requests==2.31.0\n    boto3>=1.28.0\n    EOF\n\n    # Install dependencies into a package directory\n    pip install -r requirements.txt -t package/\n\n    # Create your function code\n    cat > package/lambda_function.py << 'EOF'\n    import json\n    import requests\n    import boto3\n\n    def lambda_handler(event, context):\n        \"\"\"\n        Lambda function packaged with external dependencies.\n        The 'requests' library is bundled in the zip package.\n        boto3 is included in the Lambda runtime, but pinning\n        a version in requirements.txt ensures consistency.\n        \"\"\"\n        # Use the bundled 'requests' library\n        response = requests.get('https://httpbin.org/json')\n\n        return {\n            'statusCode': 200,\n            'body': json.dumps({\n                'message': 'Function with bundled dependencies',\n                'externalApiStatus': response.status_code,\n                'requestsVersion': requests.__version__\n            })\n        }\n    EOF\n\n    # Create the zip package\n    cd package && zip -r ../deployment.zip . && cd ..\n\n\n####  **Upload via the Console**\n\n**Step 02:** Open the **Lambda** console β†’ **Create function**\n\n  * **Function name:** `PackagedFunction`\n  * **Runtime:** `Python 3.12`\n\n\n\nClick **Create function**\n\n**Step 03:** In the **Code source** section, click **Update β–Ό** β†’ **Update from a .zip file**\n\n**Step 04:** **Upload** , select your `deployment.zip` file\n\n**Step 05:** Click **Update**\n\n####  **Test the Function**\n\n**Step 06:** Go to the **Test** tab β†’ create a test event with `{}`\n\nClick **Test**\n\n> ⚠️ Verify the response shows the `requests` library version and a successful API call\n>\n> πŸ’‘**The zip upload limit is 50 MB compressed. If your package exceeds this, upload to S3 first and reference the S3 location. The uncompressed limit is 250 MB.`sam build` handles all of this automatically. It installs dependencies, creates the zip, and uploads to S3.**\n\n##  Part II\n\n###  Build And Push A Container Image To ECR\n\n####  **Create an ECR Repository**\n\n**Step 01:** Open the **ECR** console\n\n**Step 02:** Click **Create repository**\n\n  * **Repository name:** `lambda-container-demo`\n  * **Image Tag immutability:** `Mutable`\n  * **β–Ό Image scanning settings -_deprecated_ :** Scan on push β†’ `Enabled`\n\n\n\nClick **Create**\n\n> ⚠️ Click into the repository **Summary** and note the **URI** (e.g., `123456789012.dkr.ecr.us-east-1.amazonaws.com/lambda-container-demo`)\n\n####  **Build and Push the Image Locally**\n\n**Step 03:** Create a `Dockerfile` and function code\n\n\n\n    # Use the official AWS Lambda Python base image\n    FROM public.ecr.aws/lambda/python:3.12\n\n    # Install dependencies\n    COPY requirements.txt .\n    RUN pip install -r requirements.txt\n\n    # Copy function code\n    COPY app.py ${LAMBDA_TASK_ROOT}/\n\n    # Set the handler\n    CMD [\"app.lambda_handler\"]\n\n\n**Step 04:** Create `app.py`\n\n\n\n    # app.py\n    import json\n    import requests\n\n    def lambda_handler(event, context):\n        \"\"\"\n        Lambda function running as a container image.\n        Container images support up to 10 GB β€” useful for\n        ML libraries, large datasets, or custom runtimes.\n        \"\"\"\n        return {\n            'statusCode': 200,\n            'body': json.dumps({\n                'message': 'Hello from a container-based Lambda!',\n                'runtime': 'Container image (Python 3.12)',\n                'maxPackageSize': '10 GB (vs 250 MB for zip)'\n            })\n        }\n\n\n**Step 05:** Build and push\n\n\n\n    # Authenticate Docker with ECR\n    aws ecr get-login-password --region us-east-1 | \\\n      docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com\n\n    # Build the image\n    docker build -t lambda-container-demo .\n\n    # Tag for ECR\n    docker tag lambda-container-demo:latest \\\n      123456789012.dkr.ecr.us-east-1.amazonaws.com/lambda-container-demo:latest\n\n    # Push to ECR\n    docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/lambda-container-demo:latest\n\n\n**Alternatively**\n\n\n\n    # Authenticate Docker with ECR\n    aws ecr get-login-password --region us-east-1 | \\\n      docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com\n\n    # Build the image β€” disable attestations so Lambda accepts the manifest\n    docker buildx build --provenance=false --sbom=false \\\n      -t 123456789012.dkr.ecr.us-east-1.amazonaws.com/lambda-container-demo:latest \\\n      --push .\n\n\n> ⚠️ **Manifest Format Gotcha:** If you build with a plain `docker build` on a recent Docker Desktop, BuildKit adds provenance and SBOM attestations that produce an **OCI image index**. Lambda rejects this with: _\"The image manifest, config or layer media type for the source image ... is not supported.\"_ Lambda only accepts **Docker Image Manifest V2 Schema 2**. The `--provenance=false --sbom=false` flags above force the compatible format. Alternatively, set `DOCKER_BUILDKIT=0` before building to use the legacy builder, which always produces the compatible manifest.\n\nIf you prefer the separate tag-and-push steps (with BuildKit disabled):\n\n\n\n    # PowerShell: $env:DOCKER_BUILDKIT=0   |   CMD: set DOCKER_BUILDKIT=0\n    docker build -t lambda-container-demo .\n    docker tag lambda-container-demo:latest \\\n      123456789012.dkr.ecr.us-east-1.amazonaws.com/lambda-container-demo:latest\n    docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/lambda-container-demo:latest\n\n\n####  **Verify in the Console**\n\n**Step 06:** Go back to the **ECR** console β†’ click into `lambda-container-demo`\n\n> You should see your image with the `latest` tag\n\n####  **Create a Lambda Function from the Container Image**\n\n**Step 07:** Open the **Lambda** console β†’ **Create function**\n\n**Step 08:** Select **Container image**\n\n  * **Function name:** `ContainerLambdaDemo`\n  * **Container image URI:** Click **Browse images** β†’ select `lambda-container-demo` β†’ select the `latest` tag\n\n\n\nClick **Create function**\n\n**Step 09:** Test with an empty event `{}`\n\n> πŸ’‘ **Container-based Lambda functions use ECR for image storage. The image must implement the Lambda Runtime API. AWS provides base images for all supported runtimes (`public.ecr.aws/lambda/python:3.12`). You can also use arbitrary base images with the Runtime Interface Client.**\n\n##  Part III\n\n###  Set Up AWS AppConfig with Feature Flags\n\n####  **Create an AppConfig Application**\n\n**Step 01:** Open the **AppConfig** console\n\n**Step 02:** Click **Get started**\n\n**Step 03:** **Select configuration type**\n\n  * **Configuration options:** `Feature flag`\n  * **Configuration profile name:** `feauture-flags`\n\n\n\nClick **Next**\n\n**Step 04:** **Specify configuration data**\n\n  * **Flag name:** `New Checkout Flow`\n  * **Flag key:** `new-checkout-flow`\n  * **Flag description -_Optional_ :** `Enable the redesigned checkout experience`\n  * **Variants:** `Basic flag`\n  * **Enabled value:** Toggle `**ON**`\n\n\n\nClick **Next**\n\n**Step 05:** **Review and save**\n**Save to application**\n\n  * **Application name:** `orders-service`\n  * **Description:** `Feature flags and configuration for the orders service`\n\n\n\nClick **Save and continue to deploy**\n\n**Step 06:** **Start deployment**\n\n**Environment:** Click `Create environment`\n\n**Step 07:** **Create environment**\n\n  * **Name:** `production`\n  * **Description:** `Production environment`\n\n\n\nClick **Create environment**\n\n####  **Add A Feature Flag**\n\n**Step 08:** Click **Add flag**\n\n  * **Flag name:** `Dark Mode`\n  * **Flag key:** `dark-mode`\n  * **Description:** `Enable dark mode UI`\n  * **Variants:** `Basic flag`\n  * **Enabled value:** Toggle `**OFF**`\n\n\n\nClick **Save new version**\n\n####  **Create a Deployment Strategy**\n\n**Step 09:** **Deployment strategies** β†’ **Create deployment strategy**\n\n  * **Name:** `GradualRollout`\n  * **Description:** `Deploy over 10 minutes with bake time`\n  * **Deployment type:** `Linear β–Ό`\n  * **Step percentage:** `20`\n  * **Deployment time:** `10 minutes`\n  * **Bake time:** `5 minutes`\n\n\n\nClick **Create deployment strategy**\n\n####  **Deploy the Configuration**\n\n**Step 10:** Go to your `orders-service` **application** β†’ `production` **environment**\n\nClick **Start deployment**\n\n**Step 11:** **Start deployment**\n\n  * **Configuration profile:** `feature-flags`\n  * **Hosted configuration version:** `(latest)`\n  * **Deployment strategy:** `GradualRollout`\n\n\n\nClick **Start deployment**\n\n> ⚠️ Watch the deployment progress. It rolls out 20% at a time over 10 minutes\n>\n> πŸ’‘**AppConfig deployment strategies control how fast configuration changes roll out. If a CloudWatch alarm fires during deployment, AppConfig automatically rolls back. This is safer than changing a Parameter Store value directly, which takes effect immediately for all callers.**\n\n##  Part IV\n\n###  Structure a SAM Project for Multi-Environment Deployment\n\n####  **Step 01:** Initialize the Project\n\n\n    sam init --runtime python3.12 --name multi-env-app --app-template hello-world\n    cd multi-env-app\n\n\n####  **Step 02:** Create the Handler Files\n\n> ⚠️ `sam init` creates a `hello_world/` folder, but our template uses a `src/handlers/` structure with two functions. Create these files (delete the generated `hello_world/` folder afterward. It's no longer referenced):\n\n####  **Step 03:** Create `src/handlers/requirements.txt`:\n\n\n    boto3\n\n\n####  **Step 04:** Create `src/handlers/create_order.py`:\n\n\n    import json\n    import os\n    import boto3\n    import uuid\n\n    dynamodb = boto3.resource('dynamodb')\n    table = dynamodb.Table(os.environ['TABLE_NAME'])\n\n    def lambda_handler(event, context):\n        body = json.loads(event.get('body', '{}'))\n        order_id = str(uuid.uuid4())[:8].upper()\n\n        table.put_item(Item={\n            'PK': f'ORDER#{order_id}',\n            'SK': 'METADATA',\n            'customerId': body.get('customerId', 'unknown'),\n            'status': 'created'\n        })\n\n        return {\n            'statusCode': 201,\n            'body': json.dumps({'orderId': f'ORD-{order_id}', 'status': 'created'})\n        }\n\n\n####  **Step 05:** Create `src/handlers/get_order.py`:\n\n\n    import json\n    import os\n    import boto3\n\n    dynamodb = boto3.resource('dynamodb')\n    table = dynamodb.Table(os.environ['TABLE_NAME'])\n\n    def lambda_handler(event, context):\n        order_id = event['pathParameters']['orderId']\n\n        response = table.get_item(Key={'PK': f'ORDER#{order_id}', 'SK': 'METADATA'})\n        item = response.get('Item')\n\n        if not item:\n            return {'statusCode': 404, 'body': json.dumps({'error': 'Order not found'})}\n\n        return {'statusCode': 200, 'body': json.dumps(item, default=str)}\n\n\n> ⚠️ The template's `CodeUri: src/handlers/` and `Handler: create_order.lambda_handler` must point to real files. If `src/handlers/` doesn't exist or is missing `requirements.txt`, `sam build` fails with _\"source ... does not exist\"_ or _\"requirements.txt file not found.\"_ The `CodeUri` is the folder SAM packages; the `Handler` is `filename.function_name` relative to that folder.\n\n####  **Step 06:** Configure the SAM Template with Parameters\n\nReplace the contents of `template.yaml`\n\n\n\n    AWSTemplateFormatVersion: '2010-09-09'\n    Transform: AWS::Serverless-2016-10-31\n    Description: Multi-environment serverless application\n\n    Parameters:\n      Stage:\n        Type: String\n        Default: dev\n        AllowedValues: [dev, staging, prod]\n      TableName:\n        Type: String\n        Default: orders\n\n    Globals:\n      Function:\n        Runtime: python3.12\n        Timeout: 30\n        Environment:\n          Variables:\n            STAGE: !Ref Stage\n            TABLE_NAME: !Sub \"${Stage}-${TableName}\"\n\n    Resources:\n      OrdersTable:\n        Type: AWS::DynamoDB::Table\n        Properties:\n          TableName: !Sub \"${Stage}-${TableName}\"\n          BillingMode: PAY_PER_REQUEST\n          KeySchema:\n            - AttributeName: PK\n              KeyType: HASH\n            - AttributeName: SK\n              KeyType: RANGE\n          AttributeDefinitions:\n            - AttributeName: PK\n              AttributeType: S\n            - AttributeName: SK\n              AttributeType: S\n\n      CreateOrderFunction:\n        Type: AWS::Serverless::Function\n        Properties:\n          CodeUri: src/handlers/\n          Handler: create_order.lambda_handler\n          Policies:\n            - DynamoDBCrudPolicy:\n                TableName: !Ref OrdersTable\n          Events:\n            CreateOrder:\n              Type: Api\n              Properties:\n                Path: /orders\n                Method: post\n\n      GetOrderFunction:\n        Type: AWS::Serverless::Function\n        Properties:\n          CodeUri: src/handlers/\n          Handler: get_order.lambda_handler\n          Policies:\n            - DynamoDBReadPolicy:\n                TableName: !Ref OrdersTable\n          Events:\n            GetOrder:\n              Type: Api\n              Properties:\n                Path: /orders/{orderId}\n                Method: get\n\n    Outputs:\n      ApiUrl:\n        Description: API Gateway endpoint URL\n        Value: !Sub \"https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/${Stage}/\"\n\n\n####  **Step 07:** Configure samconfig.toml for Multiple Environments\n\n\n    # samconfig.toml β€” one section per environment\n    # The version key is REQUIRED β€” SAM CLI won't parse the file without it\n    version = 0.1\n\n    [default.deploy.parameters]\n    stack_name = \"multi-env-app-dev\"\n    resolve_s3 = true\n    capabilities = \"CAPABILITY_IAM\"\n    parameter_overrides = \"Stage=dev\"\n    confirm_changeset = false\n\n    [staging.deploy.parameters]\n    stack_name = \"multi-env-app-staging\"\n    resolve_s3 = true\n    capabilities = \"CAPABILITY_IAM\"\n    parameter_overrides = \"Stage=staging\"\n    confirm_changeset = false\n\n    [prod.deploy.parameters]\n    stack_name = \"multi-env-app-prod\"\n    resolve_s3 = true\n    capabilities = \"CAPABILITY_IAM\"\n    parameter_overrides = \"Stage=prod\"\n    confirm_changeset = true\n\n\n####  **Step 08:** Deploy to Different Environments\n\n\n    # Build once β€” use --use-container to build inside a Lambda-compatible\n    # Docker image (needs Docker running, but no local Python required)\n    sam build --use-container\n\n    # Or, if you have Python 3.12 installed and on your PATH:\n    # sam build\n\n    # Deploy to dev (default config)\n    sam deploy\n\n    # Deploy to staging\n    sam deploy --config-env staging\n\n    # Deploy to prod (will prompt for changeset confirmation)\n    sam deploy --config-env prod\n\n\n> ⚠️ **`sam build` can't find Python?** If you see _\"Binary validation failed for python ... did you have python for runtime: python3.12 on your PATH?\"_ , it means Python 3.12 isn't installed locally (the `WindowsApps\\python.EXE` entries are Microsoft Store stubs, not a real install). Use `sam build --use-container` to build inside a Docker container that already has the correct runtime, or install Python 3.12 from python.org and check \"Add python.exe to PATH\" during setup. CloudShell also has Python 3.12 and SAM pre-installed.\n\nEach deployment creates isolated resources: `dev-orders` table, `staging-orders` table, `prod-orders` table.\n\n> πŸ’‘ **`samconfig.toml` uses config environments (sections like `[staging.deploy.parameters]`) to manage per-environment settings. The `--config-env` flag selects which section to use. Setting `confirm_changeset = true` for production forces you to review changes before applying them.**\n\n##  πŸ—οΈ What You Built | πŸ“˜ Exam Concepts Recap\n\n**What You Built** | _Exam Concept_\n---|---\n**Bundled`requests` into a zip and uploaded via console** | _Zip packaging with dependencies, 50/250 MB limits_\n**Built a Dockerfile and pushed to ECR** | _Container image packaging (up to 10 GB)_\n**Created a Lambda from a container image** | _When to use containers vs zip_\n**Created an AppConfig application and environment** | _Runtime configuration management_\n**Added feature flags with enabled/disabled toggles** | _Feature flag pattern for decoupling release from deploy_\n**Created a Linear deployment strategy with bake time** | _Gradual config rollout with automatic rollback_\n**Used SAM parameters and`!Sub` for resource names** | _Environment-specific infrastructure_\n**Configured`samconfig.toml` for dev/staging/prod** | _Multi-environment deployment with`--config-env`_\n**Set`confirm_changeset = true` for prod** | _Forcing review before production changes_\n\n##  ⚠️ Clean Up Protocol\n\n  1. **Lambda** β†’ Delete `PackagedFunction` and `ContainerLambdaDemo`\n  2. **ECR** β†’ Delete the `lambda-container-demo` repository (and all images)\n  3. **AppConfig** β†’ Delete the deployment, then the configuration profile, environment, and application (in that order)\n  4. **CloudFormation** β†’ Delete any SAM-deployed stacks (`multi-env-app-dev`, etc.)\n  5. **IAM** β†’ Delete Lambda execution roles\n  6. **CloudWatch** β†’ Delete log groups\n  7. **S3** β†’ Delete any SAM deployment buckets (prefixed with `aws-sam-cli-managed-default`)\n\n\n\n##  Key Takeaways\n\n  1. **Zip packages:** 50 MB compressed / 250 MB uncompressed. **Container images:** up to 10 GB. Use containers for large dependencies.\n  2. **Lambda Layers** share dependencies across functions. Up to 5 layers, 250 MB total uncompressed.\n  3. **sam build** resolves dependencies automatically. **sam deploy** packages and deploys. **sam deploy --guided** for first-time setup.\n  4. **AppConfig** deploys configuration independently from code, with validation, gradual rollout, and automatic rollback.\n  5. **samconfig.toml** manages multi-environment deployment configs. Use `--config-env` to select the environment.\n  6. **ECR** stores container images. Use `public.ecr.aws/lambda/` base images for Lambda containers.\n  7. Use **CloudFormation parameters** and `!Sub` for environment-specific resource names.\n  8. **SAM policy templates** (`DynamoDBCrudPolicy`, `S3ReadPolicy`) enforce least privilege without writing full IAM policies.\n\n\n\n##  Additional Resources\n\n  * Deploying Lambda functions as .zip file archives\n  * Managing Lambda dependencies with layers\n  * What is the AWS Serverless Application Model (AWS SAM)?\n  * What is AWS AppConfig?\n  * Create a Lambda function using a container image\n  * AWS SAM CLI configuration file\n\n\n\nπŸ—οΈ",
  "title": "Prepare Application Artifacts To Be Deployed To AWS | πŸ—οΈ Build A Multi-Environment Serverless App"
}