Slide 1

Slide 1 text

Lambda management with ecspresso and Terraform @ijin Aug 6, 2025 Serverless Meetup Tokyo #21 #serverlesstokyo #serverlessjp

Slide 2

Slide 2 text

AGENDA • About me • Lambda Deployments • App vs Infra • Lambroll con fi gs • Jsonnet

Slide 3

Slide 3 text

Michael H. Oshita (@ijin) • Michael H. Oshita • Japanese American • ~20 Years in Japan • Cloud Architect • JAWS-UG Yokohama & Serverless Community & AI Coding Dojo • https://ijin.github.io/

Slide 4

Slide 4 text

Lambda Various methods of Deployment

Slide 5

Slide 5 text

Deploy with awscli # Create deployment package zip -r function.zip lambda_function.py # Update function code aws lambda update-function-code \ --function-name my-function \ --zip-file fileb://function.zip # Update function configuration aws lambda update-function-configuration \ --function-name my-function \ --runtime python3.13 \ --handler lambda_function.handler \ --role arn:aws:iam::123456789012:role/lambda-role

Slide 6

Slide 6 text

Deploy with serverless framework # serverless.yml service: my-lambda provider: name: aws vpc: securityGroupIds: ['sg-12345'] subnetIds: ['subnet-12345'] environment: DYNAMODB_TABLE: ${env:DYNAMODB_TABLE} logs: restApi: true iam: role: statements: - Effect: Allow Action: - dynamodb:Query - dynamodb:GetItem - dynamodb:PutItem Resource: - arn:aws:dynamodb:*:*:table/users - arn:aws:dynamodb:*:*:table/users/index/* - Effect: Allow Action: logs:CreateLogGroup Resource: arn:aws:logs:*:*:log-group:/aws/lambda/* functions: processor: handler: handler.process logRetentionInDays: 14 sls deploy

Slide 7

Slide 7 text

Deploy with aws sam # template.yaml AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: ProcessorRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole Policies: - PolicyName: DynamoDBAccess PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - dynamodb:Query - dynamodb:GetItem - dynamodb:PutItem Resource: - !Sub 'arn:aws:dynamodb:*:*:table/${DynamoDBTable}' - !Sub 'arn:aws:dynamodb:*:*:table/${DynamoDBTable}/index/*' - Effect: Allow Action: logs:CreateLogGroup Resource: arn:aws:logs:*:*:log-group:/aws/lambda/* ProcessorFunction: Type: AWS::Serverless::Function Properties: CodeUri: src/ Handler: handler.process Role: !GetAtt LambdaExecutionRole.Arn VpcConfig: SecurityGroupIds: - sg-12345 SubnetIds: - subnet-12345 - subnet-67890 Environment: Variables: DYNAMODB_TABLE: !Ref DynamoDBTable DYNAMODB_GSI: !Ref DynamoDBGSI Events: DynamoDBStream: Type: DynamoDB Properties: Stream: !GetAtt ProcessorTable.StreamArn StartingPosition: TRIM_HORIZON BatchSize: 10 sam build && sam deploy

Slide 8

Slide 8 text

Infrastructure as Code

Slide 9

Slide 9 text

Deploy with terraform resource "aws_iam_role" "lambda_role" { .... } resource "aws_iam_role_policy_attachment" "lambda_vpc" { .... } resource "aws_iam_role_policy" "dynamodb_access" { .... } resource "aws_dynamodb_table" "users" { .... } resource "aws_cloudwatch_log_group" "processor_logs" { .... } data "archive_file" "lambda_zip" { type = "zip" source_dir = "${path.module}/src" output_path = "${path.module}/processor.zip" } resource "aws_lambda_function" "processor" { filename = data.archive_file.lambda_zip.output_path function_name = "processor" role = aws_iam_role.lambda_role.arn handler = "handler.process" runtime = “python3.13" source_code_hash = data.archive_file.lambda_zip.output_base64s vpc_config { subnet_ids = ["subnet-12345", "subnet-67890"] security_group_ids = ["sg-12345"] } logging_config { log_format = "Text" log_group = aws_cloudwatch_log_group.processor_logs.name } } terraform apply

Slide 10

Slide 10 text

App vs Infra - Different release velocity - Different lifecycle - Separation of responsibilities - Contain blast radius

Slide 11

Slide 11 text

Infrastructure/Apps Common Infra } } Apps

Slide 12

Slide 12 text

Apps terraform for apps (modulized) } Lambda code } common env vars }

Slide 13

Slide 13 text

github.com/fujiwara/lambroll Lambroll Simple deploy tool for AWS Lambda

Slide 14

Slide 14 text

lambroll function.jsonnet

Slide 15

Slide 15 text

lambroll function.jsonnet

Slide 16

Slide 16 text

lambroll option.jsonnet

Slide 17

Slide 17 text

lambroll option.jsonnet

Slide 18

Slide 18 text

Jsonnet function.jsonnet

Slide 19

Slide 19 text

Jsonnet function.jsonnet

Slide 20

Slide 20 text

Lambda deployment 1. terragrunt run-all apply 2. lambroll deploy --function function.jsonnet -- src="app" --option=option.jsonnet --env fi le=../ global.env --env fi le=vars/common.env — env fi le=vars/dev.env

Slide 21

Slide 21 text

Jsonnet native functions

Slide 22

Slide 22 text

Jsonnet { cpu: {{ must_env `cpu` }} memory: std.parseInt(‘{{ must_env `memory` }}’) }

Slide 23

Slide 23 text

Jsonnet { cpu: {{ must_env `cpu` }} memory: std.parseInt(‘{{ must_env `memory` }}’) } ❌ Templates only worked for strings…

Slide 24

Slide 24 text

Jsonnet

Slide 25

Slide 25 text

Jsonnet

Slide 26

Slide 26 text

Jsonnet

Slide 27

Slide 27 text

Jsonnet

Slide 28

Slide 28 text

Lambroll con fi gs

Slide 29

Slide 29 text

lambroll deploy…. lambroll deploy --function function.jsonnet --src="app" \ —env fi le=../global.env \ —env fi le=vars/common.env \ —env fi le=vars/${ENV}.env \ —pre fi xed-tfstate=“vpc_=s3://pd-${ENV}-tfstate/${ENV}/vpc/tf.tfstate” \ —pre fi xed-tfstate=“logs_=s3://pd-${ENV}-tfstate/${APP}/logs/tf.tfstate" \ —pre fi xed-tfstate=“ecr_=s3://pd-${ENV}-tfstate/${APP}/ecr/tf.tfstate” \ —pre fi xed-tfstate=“app_resources_=s3://pd-${ENV}-tfstate/${ENV}/ app_resources/terraform.tfstate"

Slide 30

Slide 30 text

lambroll deploy…. lambroll deploy --function function.jsonnet --src="app" \ —env fi le=../global.env \ —env fi le=vars/common.env \ —env fi le=vars/${ENV}.env \ —pre fi xed-tfstate=“vpc_=s3://pd-${ENV}-tfstate/${ENV}/vpc/tf.tfstate” \ —pre fi xed-tfstate=“logs_=s3://pd-${ENV}-tfstate/${APP}/logs/tf.tfstate" \ —pre fi xed-tfstate=“ecr_=s3://pd-${ENV}-tfstate/${APP}/ecr/tf.tfstate” \ —pre fi xed-tfstate=“app_resources_=s3://pd-${ENV}-tfstate/${ENV}/ app_resources/terraform.tfstate" 😳 No equivalent of ecspresso.yml

Slide 31

Slide 31 text

lambroll con fi g

Slide 32

Slide 32 text

lambroll con fi g

Slide 33

Slide 33 text

lambroll con fi g

Slide 34

Slide 34 text

lambroll con fi g

Slide 35

Slide 35 text

Lambroll lambroll deploy🔥

Slide 36

Slide 36 text

Thanks!