Skip to main content

Prerequisites#

AWS Account & CLI

Export your AWS Account and Region for future use

Before you run any of the CloudFormation or ECR commands, export two env‑vars so you don’t have to repeat your account/region everywhere:

IAM Permissions#

Before you can deploy any of the CloudFormation stacks below, you’ll want a single, least‑privilege managed policy that your CI/CD user or role can assume.

Save the following policy document as permissions.json:

permissions.json

Create the IAM policy#

This will return the new policy’s ARN, e.g.:

Attach it to your deploy principal#

a) If you use an IAM User:

b) If you use an IAM Role (e.g. CodeBuild or CI/CD):


Once attached, that user or role will have exactly the rights needed to stand up all of the VPCs, ECS/Fargate clusters, ECR repos, Secrets Manager secrets, ALBs, CloudWatch Logs, IAM roles, and CloudFormation stacks in this guide

Set up ECR (Elastic Container Registry) Repositories for Phoenix and your application#

Before deploying Phoenix and your application into ECS/Fargate, you need to host your container images in Amazon Elastic Container Registry (ECR). Here’s a quick rundown:

1. Create ECR repositories#

Run these once:

Each command returns the repo URI:


2. Authenticate Docker to ECR#

This writes your Docker credentials so you can push and pull.


3. Push Phoenix and your apps (backend, frontend, db)#

If you’ve built locally:

Create VPCs and Subnets#

Save the following CloudFormation template as phoenix-network.yml:

phoenix-network.yml

This template:

  1. Creates a VPC (10.0.0.0/16 for example) with DNS support

  2. Provisions two public subnets (one per AZ) for your Internet‑facing components (ALBs, NAT gateway)

  3. Provisions two private subnets (one per AZ) for your ECS tasks (Phoenix, agents, backend services)

  4. Deploys a NAT Gateway in the first public subnet so private tasks can reach out (for secrets, Docker registries, external APIs)

  5. Exports the VPC ID and the comma‑separated Public/Private Subnet IDs for easy consumption by downstream stacks

Deploy with:#

Make sure to change AZ1 and AZ2 to match your region.

You can now access your VPC and public + private subnet IDs at AWS -> CloudFormation -> Stacks -> phoenix-network -> Outputs.

Extending for multiple components#

If you plan to run multiple services (e.g. a separate frontend, backend, worker pool), consider:

  • Additional subnets You might carve out extra AZ‑distributed subnets (e.g. “app‑subnets”, “db‑subnets”) with their own route tables and security rules.

  • Security groups per tier

    • ALB SG: allows inbound HTTP(S) from 0.0.0.0/0

    • App SG: allows inbound from the ALB SG on your HTTP port

    • DB SG: allows inbound only from your App SG on your database port

Deploy Phoenix (with Authentication)#

Save the following CloudFormation template as phoenix-auth.yml:

phoenix-auth.yml

You are now ready to deploy Phoenix to AWS.

Deploy the phoenix-auth.yml stack Consume the network stack’s outputs (VPC‑ID, PublicSubnetIds, PrivateSubnetIds) along with your new ECR URI:

Fetch your Phoenix URL

Log in and create your System API key

  • In your browser, go to $PHOENIX_URL.
  • Sign in as admin@localhost / admin.
  • Set a new admin password.
  • Go to Settings → API Keys and Create System Key.
  • Copy the new key (you’ll need it in the next step).

IMPORTANT: Security‑group ingress is wide open (0.0.0.0/0 on port 80). You should tighten it if you know your CIDR or are behind a corporate proxy.

Store Phoenix API Key + other API Keys#

Once you have your Phoenix System API key, bundle it (and any other service keys) into AWS Secrets Manager:

You can now reference these secrets in your downstream CloudFormation templates (e.g. in your application stacks) via the PhoenixArn, OpenAIArn, etc., parameters.

Deploying your App that ships Spans to Phoenix#

Save the following CloudFormation template as app.yml:

app.yml

This CloudFormation stack (app.yml) launches:

  • An ECS Cluster
  • An IAM Task Execution Role & Task Role (to pull images, read secrets)
  • A Security Group that allows outbound Internet access
  • A Log Group for container logs
  • An ECS Task Definition (family: app)
  • An ECS Service (Fargate) running one copy of the “app” container

The app container will:

  1. Read your OTLP endpoint and Phoenix API key from Secrets Manager
  2. Read your other API keys from Secrets Manager
  3. Emit spans to your Phoenix deployment

IMPORTANT: This template assumes only one secret is being used (OpenAI API Key). Make sure to add ARNs for additional secrets wherever the template is marked ADD OTHER ARNS FOR OTHER SECRETS HERE (once under Parameters, once under the ReadSecrets policy) and expose those secrets to the container where it is marked ADD OTHER SECRETS HERE.

Template parameters

ParameterDescriptionExample
AgentImageUriECR URI (with tag) of your agent container123456789012.dkr.ecr.us-west-2.amazonaws.com/agent:latest
PhoenixHostDNS name (no scheme) of your Phoenix UI load‑balancerphoenix-auth-ALB-abc123.us-west-2.elb.amazonaws.com
VpcIdYour VPC IDvpc-0abc123def456ghi7
PrivateSubnetIdsComma‑separated private subnets for your ECS taskssubnet-ccc333,subnet-ddd444
OpenAIArnARN of Secrets Manager secret holding {"OPENAI_API_KEY": "…"}arn:aws:secretsmanager:us-west-2:920904165384:secret:openai-key
PhoenixArnARN of secret holding {"PHOENIX_API_KEY": "…"}arn:aws:secretsmanager:us-west-2:920904165384:secret:phoenix-key

Example deploy command (add additional ARNs for more secrets):

Once complete, ECS will spin up your agent task, and you can verify in the console:

Now your traces should flow from the agent into your Phoenix project!

(Optional) Extending for Additional Components (Frontend, DB, etc.)#

Once you have Phoenix + your agent/LLM task up and running, you can easily add more services to the same VPC:

  1. Create new ECR repos for your frontend, backend, DB‑migrations job, worker service, etc.

  2. Add new TaskDefinitions / Services to your app.yml (or split each into its own CFN stack):

  3. Subnet segmentation If you want stricter isolation, you can carve out “app‑subnets” vs “db‑subnets”, each with its own route table and SG rules. Just update phoenix-network.yml to output those extra subnet IDs.

  4. Security groups per tier

    • ALB SG → allows 0.0.0.0/0 on 80/443

    • App SG → allows inbound from ALB SG on 80

    • DB SG → allows inbound from App SG on 5432 (Postgres) or 3306 (MySQL)

With these patterns you can grow from one simple “agent-only” service into a multi‑tier architecture, all launched and managed via CloudFormation.