AWS Elastic Container Service
You can use Phase to securely supply secrets to your AWS Elastic Container Service (ECS) Tasks.
Prerequisites
- An AWS account with full access to:
- Elastic Container Service (ECS)
- Identity and Access Management (IAM)
- EC2 Services
- Sign up for the Phase Console and create an App.
- Obtain a
PHASE_SERVICE_TOKENfor your application, that has access to the environment you are trying to fetch secrets from. - Your Phase Application ID (found in your application settings under the App section UUID)
Init Container
This method uses the Phase CLI Docker image as an init container in your ECS task. The init container fetches secrets and stores them in a shared ephemeral volume, making them accessible to your application container through a secrets file.
If your application only supports environment variables for accessing secrets, you can run export $(cat /tmp/secrets | xargs) in your application container before the CMD. This command reads secrets from the filesystem and sets them as environment variables before starting your application. However, we recommend configuring your application to read secrets directly from the filesystem for enhanced security.
How It Works
- ECS pulls and runs the
phasehq/clicontainer - The Phase CLI authenticates using your provided credentials (
PHASE_HOSTandPHASE_SERVICE_TOKEN) - The CLI retrieves secrets from your specified Phase application and environment
- Secrets are written to a shared volume as key-value pairs
- Your application container loads the secrets
Task Definition
Here's a complete ECS task definition implementing this approach:
{
"family": "phase-ecs-secrets-example",
"containerDefinitions": [
{
"name": "secrets-init",
"image": "phasehq/cli:1.18.6", // 👈 Specify Phase CLI version
"cpu": 0,
"essential": true,
"entryPoint": [
"/bin/sh",
"-c"
],
"command": [
"phase secrets export --app-id 00000000-0000-0000-0000-000000000000 --env production > /tmp/secrets"
// Specify your Phase application ID ☝️, environment and output path
],
"environment": [
{
"name": "PHASE_HOST", // Optional - Specify PHASE_HOST URL for self-hosted instances
"value": "https://console.phase.dev"
},
{
"name": "PHASE_SERVICE_TOKEN", // Your Phase Service Account Token
"value": "pss_service:v2:..."
}
],
"mountPoints": [
{
"sourceVolume": "secrets-store",
"containerPath": "/tmp",
"readOnly": false
}
]
},
{
"name": "app",
"image": "mendhak/http-https-echo:35",
"cpu": 0,
"portMappings": [
{
"containerPort": 8080,
"hostPort": 8080,
"protocol": "tcp"
},
{
"containerPort": 8443,
"hostPort": 8443,
"protocol": "tcp"
}
],
"essential": true,
"entryPoint": [
"/bin/sh",
"-c"
],
"command": [
"export $(cat /tmp/secrets | xargs) && docker-entrypoint.sh node ./index.js"
// ☝️ Read secrets from file, set as environment variables, and start the app
],
"environment": [
{
"name": "ECHO_INCLUDE_ENV_VARS",
"value": "1"
}
],
"mountPoints": [
{
"sourceVolume": "secrets-store",
"containerPath": "/tmp",
"readOnly": true
}
],
"dependsOn": [
{
"containerName": "secrets-init",
"condition": "COMPLETE"
}
]
}
],
"executionRoleArn": "arn:aws:iam::012345678910:role/ecsTaskExecutionRole",
// ☝️ Replace with your ECS task execution ARN
"networkMode": "awsvpc",
"volumes": [
{
"name": "secrets-store"
}
],
"requiresCompatibilities": [
"FARGATE"
],
"cpu": "1024",
"memory": "3072",
"ephemeralStorage": {
"sizeInGiB": 21
}
}
Configuration
- Name
--app-id- Type
- required
- Description
Your Phase application ID. Replace
00000000-0000-0000-0000-000000000000with your actual application ID from the Phase console.
- Name
--env- Type
- optional
- Description
The Phase application secrets environment to deploy from. Defaults to
development.
- Name
--format- Type
- optional
- Description
The output format for secrets. Available options:
json,csv,yaml,xml,toml,hcl,ini,java_properties. Defaults todotenv.
- Name
PHASE_SERVICE_TOKEN- Type
- required
- Description
Your Phase service token. Update this environment variable with a valid service token from your Phase account.
- Name
PHASE_HOST- Type
- optional
- Description
The Phase host URL. Only modify this if you're using a self-hosted Phase instance. Defaults to
https://console.phase.dev.
- Name
executionRoleArn- Type
- required
- Description
AWS IAM execution role ARN. Update this to match your ECS execution role.
Important Considerations
-
Service Token Management: Currently, the Phase Account Service Token must be supplied in the task definition. Service tokens require manual provisioning and rotation to maintain security best practices. This requirement will be addressed soon with the addition of AWS IAM authentication as a native authentication method for Phase, eliminating the need for manual token management.
-
Special Characters: Be cautious with special characters in secret keys or values, as they can cause export failures. For example:
/bin/sh: export: line 0: SECRET_KEY?: bad variable name