CipherStash Docs

Deploying to AWS ECS

Step-by-step guide for deploying CipherStash Proxy to AWS ECS with Fargate

Deploying CipherStash Proxy to AWS ECS

Prerequisites

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.docker

Note 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:latest

Create 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.json

Note 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.json

Inline 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.json

Managed 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/AmazonECSTaskExecutionRolePolicy

Create 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.json

Create 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-proxy

Create 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-proxy

Notes 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.

On this page