Skip to content

Deploy to Terraform

Terraform provisions the infrastructure your agent runs on as code, so each deployment is consistent and repeatable across cloud providers. This guide deploys a containerized Strands agent through one Terraform workflow, with a tab for each of four targets:

  • AWS App Runner: a containerized web service that scales automatically
  • AWS Lambda: serverless invocations for event-driven workloads
  • Google Cloud Run: managed serverless containers
  • Azure Container Instances: a single container with a public endpoint

Pick your target in the tabs below and follow the same steps end to end. The agent behind each target is the one you already built: only the packaging around it changes.

Cloud deployment requires your containerized agent to be available in a container registry. The following assumes you have completed the Docker deployment guide and pushed your image to the appropriate registry:

Docker Tutorial Project Structure:

Project Structure (Python):

my-python-app/
├── agent.py # FastAPI application (from Docker tutorial)
├── Dockerfile # Container configuration (from Docker tutorial)
├── pyproject.toml # Created by uv init
├── uv.lock # Created automatically by uv

Project Structure (TypeScript):

my-typescript-app/
├── index.ts # Express application (from Docker tutorial)
├── Dockerfile # Container configuration (from Docker tutorial)
├── package.json # Created by npm init
├── tsconfig.json # TypeScript configuration
├── package-lock.json # Created automatically by npm

Deploy-specific Docker configurations

Image Requirements:

  • Standard Docker images supported

Container Registry Requirements:

Docker Deployment Guide Modifications:

  • No special base image required (standard Docker images work)
  • Ensure your app listens on port 8080 (or configure port in terraform)
  • Build with: docker build --platform linux/amd64 -t my-agent .

Create a terraform directory, then add three files to it: main.tf defines the infrastructure, variables.tf declares the inputs, and outputs.tf exposes the deployed URL.

Terminal window
mkdir terraform
cd terraform

Create main.tf

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
resource "aws_iam_role" "apprunner_ecr_access_role" {
name = "apprunner-ecr-access-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "build.apprunner.amazonaws.com"
}
}
]
})
}
resource "aws_iam_role_policy_attachment" "apprunner_ecr_access_policy" {
role = aws_iam_role.apprunner_ecr_access_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSAppRunnerServicePolicyForECRAccess"
}
resource "aws_apprunner_service" "agent" {
service_name = "strands-agent"
source_configuration {
image_repository {
image_identifier = var.agent_image
image_configuration {
port = "8080"
runtime_environment_variables = {
OPENAI_API_KEY = var.openai_api_key
}
}
image_repository_type = "ECR"
}
auto_deployments_enabled = false
authentication_configuration {
access_role_arn = aws_iam_role.apprunner_ecr_access_role.arn
}
}
instance_configuration {
cpu = "0.25 vCPU"
memory = "0.5 GB"
}
}

Create variables.tf

variable "aws_region" {
description = "AWS region"
type = string
default = "us-east-1"
}
variable "agent_image" {
description = "Container image for Strands agent"
type = string
}
variable "openai_api_key" {
description = "OpenAI API key"
type = string
sensitive = true
}

Create outputs.tf

output "agent_url" {
description = "AWS App Runner service URL"
value = aws_apprunner_service.agent.service_url
}

Create terraform/terraform.tfvars with the values for your chosen provider:

agent_image = "your-account.dkr.ecr.us-east-1.amazonaws.com/my-image:latest"
openai_api_key = "<your-openai-api-key>"

This example uses OpenAI, but any supported model provider can be configured. See the Strands documentation for all supported model providers.

Note: Bedrock model provider credentials are passed automatically through App Runner’s IAM role, so you don’t specify them in Terraform.

Terminal window
# Initialize Terraform
terraform init
# Review the deployment plan
terraform plan
# Deploy the infrastructure
terraform apply
# Get the endpoints
terraform output

Test the endpoints using the output URLs:

Terminal window
# Health check
curl http://<your-service-url>/ping
# Test agent invocation
curl -X POST http://<your-service-url>/invocations \
-H "Content-Type: application/json" \
-d '{"input": {"prompt": "What is artificial intelligence?"}}'

When you change your code, rebuild the image and reapply:

Terminal window
# Rebuild and push image
docker build -t <your-registry>/my-image:latest .
docker push <your-registry>/my-image:latest
# Update infrastructure
terraform apply

Remove the infrastructure when you’re done:

Terminal window
terraform destroy