Learn / AWS Lambda for backend devs / Deploying with IaC

Lesson 4 of 5 7 min

Deploying with IaC

Why hand-clicking a Lambda function through the console doesn't scale, and how CloudFormation/SAM/Terraform each approach the same deploy problem.

Why not just use the console

Clicking through the Lambda console to create a function works for a one-off experiment. It breaks down for anything real:

  • No history. A console change has no diff, no author, no reason recorded - you can’t tell what changed or why six months later.
  • No review. Nobody looks at a console click before it goes live the way a pull request gets reviewed.
  • Not reproducible. Recreating the exact same setup in a new AWS account, a new region, or a staging environment means manually repeating every click and hoping you remembered all of them correctly.

Infrastructure as Code (IaC) fixes all three: the function’s runtime, memory, timeout, IAM role, and triggers are defined in a file, checked into the same repository as the code it deploys, reviewed the same way code is, and deployed the same way in every environment.

Three common tools, same underlying problem

CloudFormation - AWS’s native IaC service. You write a template (YAML or JSON) describing resources; CloudFormation figures out the create/update/delete plan and applies it as a “stack,” tracking what it owns.

AWS SAM (Serverless Application Model) - a simplified template syntax layered on top of CloudFormation, purpose-built for serverless patterns. AWS::Serverless::Function is much shorter than the raw AWS::Lambda::Function + permissions + event source mapping resources it expands into - SAM’s CLI transforms your template into full CloudFormation at deploy time.

# SAM - short
Resources:
  HelloFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/
      Handler: app.handler
      Runtime: python3.13
      MemorySize: 256
      Timeout: 10
      Events:
        Api:
          Type: Api
          Properties:
            Path: /hello
            Method: get

Terraform - a third-party, multi-cloud tool (HashiCorp) with its own declarative language (HCL) and its own state file tracking what it manages. Useful when your infrastructure spans multiple providers, or your team already standardizes on Terraform elsewhere - it manages AWS Lambda through the same aws_lambda_function resource pattern it uses for everything else.

None of the three is objectively “correct” - CloudFormation/SAM if you’re AWS-only and want native tooling with no extra state to manage; Terraform if you need multi-cloud or your organization has already standardized on it.

Two artifacts, kept in sync

A Lambda deploy has two moving parts: the template (infrastructure/configuration) and the code package (the zip or image). Version them together - a template rollback that leaves the code package at a newer version (or vice versa) is a subtle, hard-to-debug mismatch. Most CI/CD setups for Lambda build and upload the code artifact first, then deploy a template revision that references that specific artifact version, so the two always move as a pair.

Least-privilege IAM, made easy by IaC

The most common security gap in hand-built Lambda setups is a single, broad IAM role attached to every function - “just give it AdministratorAccess so nothing breaks” is a real, common shortcut under deadline pressure. IaC makes the better alternative nearly as easy: define a narrow role per function (or per small group of related functions) directly in the same template, granting only the specific actions and resources that function actually touches (one S3 bucket, one DynamoDB table - not s3:* on *). Because it’s code, it’s also reviewable - a PR that adds "Action": "*" to a function’s role is a visible, flaggable change, not an invisible console click.

Key takeaways

  • Infrastructure as Code (IaC) means your function's configuration - runtime, memory, timeout, IAM role, triggers - lives in version-controlled files, not console clicks, so it's reviewable, repeatable, and reproducible in a new account or region.
  • CloudFormation is AWS's native IaC service; SAM is a thinner, Lambda-focused syntax that compiles down to CloudFormation; Terraform is a third-party, multi-cloud tool that manages AWS (and other providers) through its own state and syntax.
  • A deploy pipeline for Lambda typically has two artifacts: the infrastructure definition (the template) and the code package - keep them versioned together so a rollback of one doesn't silently mismatch the other.
  • Least-privilege IAM roles per function (not one shared broad role for everything) is the single most common security gap in hand-built Lambda deployments - IaC makes it easy to define narrowly and review.

Quick check

3 questions - see how much stuck.

1. What's the core problem Infrastructure as Code solves for Lambda deployments?
2. What's the relationship between AWS SAM and CloudFormation?
3. Why is a single shared, broad IAM role for every Lambda function a common security problem?