Deploying to AWS ECS
Step-by-step guide for deploying CipherStash Proxy to AWS ECS with Fargate
Deploying CipherStash Proxy to AWS ECS
Prerequisites
- AWS Account: An active AWS account
- AWS CLI: Installed and configured with appropriate permissions (install guide)
- Docker: Installed if you need to push the image to ECR
- CipherStash Proxy config: Refer to the Proxy config reference
- AWS RDS instance: A PostgreSQL RDS instance in the same VPC as your ECS cluster
Sign up to CipherStash
Create a CipherStash account and generate credentials:
# Install the CipherStash CLI
## macOS
brew install cipherstash/tap/stash
## Linux
## Download from https://github.com/cipherstash/cli-releases/releases/latest
# Setup your CipherStash configuration
stash setup --proxy
# Outputs credentials to .env.proxy.dockerNote down the credentials — you will need these in later steps.
Prepare your Docker image
Docker images are available from:
If using Docker Hub, push the image to Amazon ECR:
# Ensure you have set these environment variables:
# export AWS_ACCOUNT_ID=111222333444
# export AWS_REGION=ap-southeast-2
set -u
aws ecr create-repository --repository-name cipherstash-proxy
aws ecr get-login-password | docker login \
--username AWS \
--password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
docker tag cipherstash/proxy:latest \
$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/cipherstash-proxy:latest
docker push \
$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/cipherstash-proxy:latestCreate secrets
Using the credentials from Step 1, create cipherstash-proxy-secrets.json:
{
"CS_WORKSPACE_ID": "...",
"CS_CLIENT_ID": "...",
"CS_DEFAULT_KEYSET_ID": "...",
"CS_CLIENT_KEY": "...",
"CS_CLIENT_ACCESS_KEY": "...",
"CS_DATABASE__PASSWORD": "..."
}The value of CS_DATABASE__PASSWORD is the password of your PostgreSQL RDS instance.
Create the secret in Secrets Manager:
aws secretsmanager create-secret \
--name cipherstash-proxy \
--secret-string file://cipherstash-proxy-secrets.jsonNote the ARN of the secret — you will need it for the task definition.
Set up IAM roles and permissions
Trust policy
Create ecs-tasks-trust-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}Create the IAM role:
aws iam create-role \
--role-name ecsTaskExecutionRole \
--assume-role-policy-document file://ecs-tasks-trust-policy.jsonInline policy
Create cipherstash-proxy-ecs-policy.json, substituting the ARN of your Secrets Manager secret:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"kms:Decrypt"
],
"Resource": [
"ARN_OF_SECRETSMANAGER_SECRET"
]
}
]
}Attach the inline policy:
aws iam put-role-policy \
--role-name ecsTaskExecutionRole \
--policy-name CipherStashProxyECSPolicy \
--policy-document file://cipherstash-proxy-ecs-policy.jsonManaged policy
Attach the ECS task execution managed policy:
aws iam attach-role-policy \
--role-name ecsTaskExecutionRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicyCreate an ECS task definition
Create cipherstash-proxy-task-def.json, replacing placeholders with values from previous steps:
{
"family": "cipherstash-proxy",
"networkMode": "awsvpc",
"executionRoleArn": "ARN_OF_ROLE",
"cpu": "256",
"memory": "512",
"containerDefinitions": [
{
"name": "cipherstash-proxy",
"image": "IMAGE_FROM_STEP_2",
"essential": true,
"portMappings": [
{ "containerPort": 6432, "hostPort": 6432 },
{ "containerPort": 9930, "hostPort": 9930 }
],
"environment": [
{ "name": "CS_DATABASE__USERNAME", "value": "RDS_USERNAME" },
{ "name": "CS_DATABASE__NAME", "value": "RDS_DATABASE_NAME" },
{ "name": "CS_DATABASE__HOST", "value": "RDS_HOSTNAME" },
{ "name": "CS_DATABASE__PORT", "value": "RDS_PORT" },
{ "name": "CS_PROMETHEUS__ENABLED", "value": "true" },
{ "name": "CS_DATABASE__INSTALL_EQL", "value": "true" }
],
"secrets": [
{ "name": "CS_WORKSPACE_ID", "valueFrom": "SECRET_ARN:CS_WORKSPACE_ID::" },
{ "name": "CS_CLIENT_ID", "valueFrom": "SECRET_ARN:CS_CLIENT_ID::" },
{ "name": "CS_DEFAULT_KEYSET_ID", "valueFrom": "SECRET_ARN:CS_DEFAULT_KEYSET_ID::" },
{ "name": "CS_CLIENT_KEY", "valueFrom": "SECRET_ARN:CS_CLIENT_KEY::" },
{ "name": "CS_CLIENT_ACCESS_KEY", "valueFrom": "SECRET_ARN:CS_CLIENT_ACCESS_KEY::" },
{ "name": "CS_DATABASE__PASSWORD", "valueFrom": "SECRET_ARN:CS_DATABASE__PASSWORD::" }
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "cipherstash-proxy",
"awslogs-region": "AWS_REGION",
"awslogs-stream-prefix": "cipherstash-proxy"
}
}
}
],
"requiresCompatibilities": ["FARGATE"],
"runtimePlatform": {
"operatingSystemFamily": "LINUX",
"cpuArchitecture": "ARM64"
}
}Register the task definition:
aws ecs register-task-definition \
--cli-input-json file://cipherstash-proxy-task-def.jsonCreate an ECS cluster and service
Create the cluster and log group:
aws ecs create-cluster --cluster-name ecs-app
aws logs create-log-group --log-group-name cipherstash-proxyCreate an ECS service (ensure you have the subnet and security group of your RDS instance):
# Ensure you have set these environment variables:
# export SUBNETS=subnet-xxx
# export SECURITY_GROUP=sg-xxx
aws ecs create-service \
--cluster ecs-app \
--service-name CipherStashProxy \
--task-definition cipherstash-proxy \
--desired-count 1 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[$SUBNETS],securityGroups=[$SECURITY_GROUP],assignPublicIp=ENABLED}"Verify the deployment
Check the service and task status:
# List services running in the cluster
aws ecs list-services --cluster ecs-app
# Show details of CipherStashProxy service
aws ecs describe-services --cluster ecs-app --services CipherStashProxy
# Tail the logs
aws logs tail --since 6h --follow cipherstash-proxyNotes and considerations
- Security: Make sure sensitive data such as keys and passwords are managed securely, preferably using AWS Secrets Manager or Parameter Store.
- Networking: Configure network settings properly to allow your ECS tasks to communicate with other services.
- Scaling and management: Monitor the service and adjust scaling as necessary.