# Deploy to AWS Fargate

This guide walks you through deploying your TAC application to AWS Fargate using CloudFormation. The deployment creates an ECS Fargate cluster behind an Application Load Balancer (ALB) with all required networking and IAM configuration.

## Architecture overview

The deployment creates the following AWS resources:

* **ECS Fargate** — Container runtime for your TAC server
* **Application Load Balancer** — Stable DNS endpoint with health checks and WebSocket support
* **VPC** — Network isolation (10.0.0.0/16) with multi-AZ public subnets
* **Security Groups** — Firewall rules for ALB and ECS
* **CloudWatch Logs** — Application logs with 7-day retention
* **IAM Roles** — Permissions for Bedrock access

## Prerequisites

Before you begin, make sure you have:

* AWS CLI configured with appropriate credentials
* Docker installed
* An [Amazon ECR repository](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html) to store your Docker image
* An HTTPS endpoint (choose one):
  * **ngrok** — For testing and development
  * **CloudFront** — For production with AWS-provided HTTPS domain
  * **Route53 + ACM** — For production with custom domain
* A working TAC application with your chosen connector ([Strands](/docs/conversations/agent-connect/integrations/aws#strands-connector), [Bedrock Agent](/docs/conversations/agent-connect/integrations/aws#bedrock-agent-connector), or [AgentCore](/docs/conversations/agent-connect/integrations/aws#bedrock-agentcore-connector))

> \[!NOTE]
>
> For AgentCore deployments, you must first deploy your agent to the AgentCore runtime before deploying the TAC server. See [Deploy agent to AgentCore](#deploy-agent-to-agentcore-agentcore-only) below.

## Deploy agent to AgentCore (AgentCore only)

If you're using the AgentCore connector, deploy your agent to the AgentCore runtime first.

### Install the AgentCore CLI

```bash
pip install bedrock-agentcore-starter-toolkit
```

### Configure and deploy

```bash
# Configure your agent
agentcore configure --entrypoint agent.py --name simpleagent --non-interactive

# Deploy to AgentCore
agentcore launch
```

Save the **Agent ARN** from the output — you'll need it when deploying the TAC server.

```text
Agent ARN: arn:aws:bedrock-agentcore:us-east-1:123456789012:runtime/simpleagent-XXX
```

### Test the deployed agent

```bash
agentcore invoke '{"prompt": "Hello"}'
```

## Build and publish the Docker image

Clone the TAC AWS repository to get the deployment files:

```bash
git clone https://github.com/twilio/twilio-agent-connect-aws.git
cd twilio-agent-connect-aws
```

### Build dependency wheels

Navigate to your deployment directory and build the wheel files:

## Strands

```bash
cd deploy/strands_aws_fargate
./build-wheels.sh
```

## Bedrock Agent

```bash
cd deploy/bedrock_aws_fargate
./build-wheels.sh
```

## AgentCore

```bash
cd deploy/agentcore_aws_fargate
./build-wheels.sh
```

### Build the Docker image

## Strands

```bash
docker build -t tac-strands-server:latest -f Dockerfile .
```

## Bedrock Agent

```bash
docker build -t tac-bedrock-server:latest -f Dockerfile .
```

## AgentCore

```bash
docker build -t tac-agentcore-server:latest -f Dockerfile .
```

### Push to Amazon ECR

Tag and push your image to ECR:

## Strands

```bash
# Authenticate with ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com

# Tag the image
docker tag tac-strands-server:latest YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/tac-strands-server:latest

# Push to ECR
docker push YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/tac-strands-server:latest
```

## Bedrock Agent

```bash
# Authenticate with ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com

# Tag the image
docker tag tac-bedrock-server:latest YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/tac-bedrock-server:latest

# Push to ECR
docker push YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/tac-bedrock-server:latest
```

## AgentCore

```bash
# Authenticate with ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com

# Tag the image
docker tag tac-agentcore-server:latest YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/tac-agentcore-server:latest

# Push to ECR
docker push YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/tac-agentcore-server:latest
```

Replace `YOUR_ACCOUNT_ID` with your AWS account ID.

## Deploy the CloudFormation stack

Deploy the infrastructure using CloudFormation:

## Strands

```bash
aws cloudformation deploy \
  --template-file cloudformation.yaml \
  --stack-name TACStack \
  --parameter-overrides \
    ImageURI=YOUR_ECR_URI:latest \
    TwilioAccountSid=YOUR_ACCOUNT_SID \
    TwilioAuthToken=YOUR_AUTH_TOKEN \
    TwilioApiKey=YOUR_API_KEY \
    TwilioApiSecret=YOUR_API_SECRET \
    TwilioPhoneNumber=YOUR_PHONE_NUMBER \
    TwilioConversationConfigurationId=YOUR_CONVERSATION_CONFIGURATION_ID \
    TwilioVoicePublicDomain=YOUR_HTTPS_DOMAIN \
  --capabilities CAPABILITY_IAM \
  --region us-east-1
```

## Bedrock Agent

```bash
aws cloudformation deploy \
  --template-file cloudformation.yaml \
  --stack-name TACBedrockStack \
  --parameter-overrides \
    ImageURI=YOUR_ECR_URI:latest \
    TwilioAccountSid=YOUR_ACCOUNT_SID \
    TwilioAuthToken=YOUR_AUTH_TOKEN \
    TwilioApiKey=YOUR_API_KEY \
    TwilioApiSecret=YOUR_API_SECRET \
    TwilioPhoneNumber=YOUR_PHONE_NUMBER \
    TwilioConversationConfigurationId=YOUR_CONVERSATION_CONFIGURATION_ID \
    TwilioVoicePublicDomain=YOUR_HTTPS_DOMAIN \
    BedrockAgentId=YOUR_BEDROCK_AGENT_ID \
    BedrockAgentAliasId=TSTALIASID \
  --capabilities CAPABILITY_IAM \
  --region us-east-1
```

**Find your Bedrock Agent credentials:**

* **Agent ID**: **AWS Console** > **Bedrock** > **Agents** > Select your agent
* **Agent Alias ID**: **AWS Console** > **Bedrock** > **Agents** > Select your agent > **Aliases** (default: `TSTALIASID`)

## AgentCore

```bash
aws cloudformation deploy \
  --template-file cloudformation.yaml \
  --stack-name TACAgentCoreStack \
  --parameter-overrides \
    ImageURI=YOUR_ECR_URI:latest \
    TwilioAccountSid=YOUR_ACCOUNT_SID \
    TwilioAuthToken=YOUR_AUTH_TOKEN \
    TwilioApiKey=YOUR_API_KEY \
    TwilioApiSecret=YOUR_API_SECRET \
    TwilioPhoneNumber=YOUR_PHONE_NUMBER \
    TwilioConversationConfigurationId=YOUR_CONVERSATION_CONFIGURATION_ID \
    TwilioVoicePublicDomain=YOUR_HTTPS_DOMAIN \
    BedrockAgentCoreAgentArn=YOUR_AGENT_ARN \
  --capabilities CAPABILITY_IAM \
  --region us-east-1
```

Use the **Agent ARN** from the [Deploy agent to AgentCore](#deploy-agent-to-agentcore-agentcore-only) step.

**Find your Twilio credentials:**

* **Auth Token & API Keys**: **Twilio Console** > **Account** > **API Keys & Tokens**
* **Conversation Configuration ID**: **Twilio Console** > **Conversation Orchestrator** > **Conversation Configurations**

## Get the ALB DNS name

After the stack deploys, retrieve the load balancer DNS name:

## Strands

```bash
aws cloudformation describe-stacks \
  --stack-name TACStack \
  --query 'Stacks[0].Outputs[?OutputKey==`LoadBalancerDNS`].OutputValue' \
  --output text \
  --region us-east-1
```

## Bedrock Agent

```bash
aws cloudformation describe-stacks \
  --stack-name TACBedrockStack \
  --query 'Stacks[0].Outputs[?OutputKey==`LoadBalancerDNS`].OutputValue' \
  --output text \
  --region us-east-1
```

## AgentCore

```bash
aws cloudformation describe-stacks \
  --stack-name TACAgentCoreStack \
  --query 'Stacks[0].Outputs[?OutputKey==`LoadBalancerDNS`].OutputValue' \
  --output text \
  --region us-east-1
```

The output looks similar to `TAC-ALB-xxx.us-east-1.elb.amazonaws.com`.

## Connect HTTPS endpoint to ALB

Point your HTTPS endpoint to the ALB DNS name.

**Using ngrok (development):**

```bash
ngrok http TAC-ALB-xxx.us-east-1.elb.amazonaws.com:80 --domain=your-domain.ngrok.app
```

**Using CloudFront or Route53 (production):**

Configure your CloudFront distribution or Route53 DNS record to point to the ALB DNS name.

## Configure Twilio webhooks

### Voice

1. Go to **Twilio Console** > **Phone Numbers** > **Active Numbers**.
2. Select your phone number.
3. Set **Voice URL** to `https://your-https-domain.com/twiml` (`POST`).

### SMS

1. Go to **Twilio Console** > **Conversation Orchestrator**.
2. Select your Conversation Service.
3. Set **Webhook URL** to `https://your-https-domain.com/webhook` (`POST`).

## Test your deployment

Call or text your Twilio phone number to verify the deployment works. Check CloudWatch Logs if you encounter issues:

## Strands

```bash
aws logs tail /ecs/tac-server-alb --follow --region us-east-1
```

## Bedrock Agent

```bash
aws logs tail /ecs/tac-bedrock-server --follow --region us-east-1
```

## AgentCore

```bash
aws logs tail /ecs/tac-agentcore-server --follow --region us-east-1
```

## Next steps

* [AWS connectors](/docs/conversations/agent-connect/integrations/aws): Learn about the available connectors.
* [Troubleshooting](/docs/conversations/agent-connect/troubleshooting): Debug common issues.
* [Escalate to a human agent](/docs/conversations/agent-connect/escalate-to-human-agent): Transfer conversations to a human agent.
