Skip to content

AWS Deployment

This guide details how to deploy the PII Eraser AWS CloudFormation reference implementation. The reference implementation supports both ECS Fargate (serverless) and EC2 (high performance) launch types and features a load balancer, autoscaler, and can either create its own VPC or deploy into an existing VPC.

Stack Overview

This reference implementation deploys PII Eraser into a secure, high-availability architecture designed for production workloads. It leverages Amazon ECS (Elastic Container Service) to orchestrate the application, ensuring it can scale automatically based on traffic demand.

The architecture is designed with a "security-first" approach:

  • Network Isolation: The application containers are deployed into private subnets across two Availability Zones (AZs). They are not directly accessible from the public internet.
  • Traffic Management: An Internal Application Load Balancer (ALB) handles incoming traffic, distributing requests across healthy instances.
  • Auto Scaling: The stack includes an Application Auto Scaling policy that monitors CPU utilization. It automatically adds containers during high-load events and removes them during idle periods to save costs.
  • Outbound Access: A NAT Gateway is provisioned in the public subnets to allow for the container image to be pulled without allowing inbound connections.

Removing the NAT Gateway for Airgapped/Private Link Deployments

This reference implementation creates a NAT Gateway to pull the container image. If your environment is strictly airgapped and you mirror the image to a private internal ECR, you can remove the NAT Gateway and Route Table entries from vpc.yaml and rely on AWS PrivateLink (VPC Endpoints) for ECR and CloudWatch Logs.

Security Architecture

The reference implementation follows a defense-in-depth approach designed to satisfy strict enterprise DevSecOps and vendor risk assessment requirements. For a comprehensive discussion of PII Eraser's security model, see Security.

Network Isolation & Anti-Exfiltration

Because PII Eraser is fully self-hosted within your own AWS environment, your text data never leaves your VPC. The reference implementation enforces this at the network layer:

  • Internal-Only Ingress: The Application Load Balancer uses the internal scheme. Containers receive no public IP address and are deployed into private subnets that cannot be reached from the public internet. PII Eraser is only accessible from within your private corporate network or VPN. Note: By default, the AlbSecurityGroup in common.yaml allows inbound HTTP traffic from 10.0.0.0/8. For production deployments, you should restrict this CidrIp value to strictly match your specific VPC CIDR block or designated corporate VPN IP range.
  • Strict Egress Filtering: The container's Security Group overrides the AWS default "allow all" outbound rule. Outbound traffic is explicitly restricted to TCP port 443 (HTTPS), permitting only communication with required AWS services (ECR for image pulls, CloudWatch for logging, and metering services). Unauthorized data exfiltration is blocked at the network layer.

Note on Internal TLS

This reference implementation uses HTTP between the client and the internal ALB. All traffic remains within the VPC and is never exposed to the public internet. For organizations whose security policies require encryption of all traffic regardless of network boundary (defense-in-depth / zero-trust), add TLS termination at the ALB using a certificate from your internal CA or ACM Private CA.

Container Hardening

  • Immutable Filesystem: ReadonlyRootFilesystem is set to true on the task definition, preventing an attacker from writing malicious executables or modifying application binaries at runtime. A temporary in-memory volume is mounted at /tmp for the minimal scratch space the application requires.
  • All Linux Capabilities Dropped: The container runs with Drop: ALL for Linux capabilities, removing all kernel-level privileges — including those granted by default in standard Docker configurations — and minimizing container breakout risk.
  • IMDS Credential Blocking (EC2): The EC2 launch template configures ECS_AWSVPC_BLOCK_IMDS=true, which prevents a compromised container from reaching the EC2 Instance Metadata Service and accessing the underlying host's IAM role credentials.

Least-Privilege IAM

The reference implementation uses split IAM roles to limit the blast radius of a potential compromise. Every role and policy created by the CloudFormation templates serves a strict, limited purpose:

  • EcsTaskExecutionRole: Assumed by the ECS infrastructure. Uses the AmazonECSTaskExecutionRolePolicy to allow the underlying ECS agent to pull the PII Eraser container images from ECR and write application logs to Amazon CloudWatch. The container itself never assumes this role.
  • EcsTaskRole: The role assumed by the running PII Eraser container at runtime. Uses the AWSMarketplaceMeteringRegisterUsage policy to allow the container to register usage metrics. It is restricted to this single permission, granting absolutely no access to S3, DynamoDB, or your internal data.
  • TestLambdaRole: Assumed by the pii-prod-tester utility function. Uses AWSLambdaBasicExecutionRole and AWSLambdaVPCAccessExecutionRole to allow the test function to execute, write logs to CloudWatch, and create the necessary Elastic Network Interfaces (ENIs) to communicate securely within your private VPC subnets.
  • Ec2InstanceRole & Profile (EC2 Deployments Only): Assumed by the underlying EC2 host instances. Uses AmazonEC2ContainerServiceforEC2Role to allow the host to securely register with the ECS cluster, and AmazonSSMManagedInstanceCore to enable secure, SSH-free instance management via AWS Systems Manager.
  • AutoScalingTarget: The templates utilize the AWS service-linked role AWSServiceRoleForApplicationAutoScaling_ECSService. This permits the AWS Auto Scaling service to monitor CloudWatch CPU metrics and automatically adjust the DesiredCount of your ECS service.

Reference Implementation Components

The deployment is modularized into several scripts and CloudFormation template files:

File Description
deploy.sh Start Here. An interactive CLI script that packages the templates, and deploys the stack to your AWS account.
update.sh An interactive CLI script to update certain parameters such as config.yaml.
cleanup.sh CLI script to delete the stack.
create_network_for_testing.sh A CLI script that creates an existing VPC with the required subnets that the stack can be deployed into.
manage_service.py A Python utility to programmatically pause the service (scale to zero) or wake it up, ideal for batch processing workflows and to save costs when not in active use.
main.yaml The main orchestrator. It conditionally calls the nested stacks (Network, Common, and Compute) based on your inputs.
vpc.yaml Provisions the network layer. It creates the Virtual Private Cloud (VPC), Public/Private subnets, Route Tables, and the NAT Gateway.
common.yaml Shared infrastructure resources, including the ECS Cluster, IAM Roles (permissions), Security Groups, and the Load Balancer.
fargate.yaml Defines the service for Serverless execution. Used when you want AWS to manage the underlying infrastructure.
ec2.yaml Defines the service for EC2 execution. Used when you need specific high-performance instances (e.g., c8a or c8i with AVX-512 VNNI or AMX support) for maximum throughput.

Prerequisites

  1. AWS CLI installed and configured with appropriate permissions.
  2. Deployment Permissions: The AWS IAM User or Role running the deployment scripts must have sufficient permissions to provision infrastructure. Specifically, they need rights to create:
    • Network Resources: VPCs, Subnets, Route Tables, NAT Gateways, and Security Groups.
    • Compute & Traffic: ECS Clusters, ECS Services, Application Load Balancers, Target Groups, and Auto Scaling Groups.
    • IAM Roles (CAPABILITY_IAM): Because this stack automatically provisions the least-privilege runtime roles described in the Security Architecture, the deploying user must have permissions to create IAM roles (iam:CreateRole, iam:AttachRolePolicy) and pass those roles to ECS, EC2, and Lambda (iam:PassRole).
  3. Deployment Scripts: Clone the GitHub repository containing the deploy.sh and update.sh scripts.
  4. [Optional] Existing VPC: If you wish to deploy into an existing VPC, the VPC needs to have at least two subnets.
    • The subnets might need NAT Gateway access depending on how you pull the container.
    • If running strictly airgapped, ensure VPC Endpoints for ECR, S3, and CloudWatch Logs are present.

Deployment Steps

1. Prepare config.yaml

If you wish to use a custom configuration (e.g., specific allow_list items), place your config.yaml file into the reference implementation directory. The deploy.sh and update.sh scripts automatically handle the injection of the config.yaml file into the container by Base64 encoding the file and passing it as a parameter to the CloudFormation stack, which in turn passes it to the containers via the CONFIG_B64 environment variable.

Security Best Practice

For production environments, the reference implementation can be modified to read the configuration from the AWS Systems Manager (SSM) Parameter Store rather than the CONFIG_B64 environment variable.

2. Prepare Stack Parameters

Open deploy.sh and main.yaml and edit the default values for stack parameters like REGION as desired. Pay special attention to the ContainerCpu and ContainerMemory values. These should be deliberately sized for your workload and instance type to ensure maximum throughput and stability. Please review the Benchmarks & Hardware guide for optimal configurations, and the Other Platforms guide for general sizing recommendations, rather than relying on placeholder values.

3. Run Deployment Script

Run the deploy.sh script to create the stack. The script will ask you for various inputs such as the minimum number of containers the autoscaler should run.

It is advisable to use the script to create a CloudFormation Change Set. This allows you to review exactly what resources will be created before creating the stack. By default, it creates a secure VPC with private subnets for the application and public subnets for the Load Balancer.

4. Testing the Stack

Since PII Eraser is deployed into private subnets (for security), it is not directly accessible from the public internet by default.

To verify connectivity and process test inputs:

  1. Navigate to the AWS Lambda Console.
  2. Find the function named pii-eraser-prod-tester.
  3. Click the orange Test button (The default "Event JSON" is pre-configured for a basic check).
  4. Success: You will see a green box. Expand the "Details" to see the JSON response showing the transformed text.

To test specific PII Eraser features (like redaction or masking), modify the Event JSON in the Lambda console:

  1. In the Test tab, scroll down to the Event JSON text area.
  2. Replace the existing JSON with one of the scenarios below.
  3. Click the orange Test button to send the request to your private container.

Example A: Simple Masking (Default)

This replaces PII with the specified mask character (default is #)

{
  "text": ["Call me at +49 586 249 509 or email [email protected]"],
  "operator": "mask"
}

Example B: Redact Specific Entity Types

This example redacts only the specified entity types, leaving the others untouched.

{
  "text": ["Meeting with Magda at 10 AM in Frankfurt."],
  "operator": "redact",
  "entity_types": ["NAME"]
}

Updating the Stack

Use update.sh to update the following parameters:

  • Container image URI
  • config.yaml
  • Autoscaler minimum and maximum container instance values

Run update.sh and it will prompt for updated parameters. If a value is not entered, the previous value is preserved. The script also encodes the config.yaml file in the current directory and includes it in the update. This is intentional — it ensures the deployed configuration always matches the local file. The script then triggers a rolling deployment to maintain service uptime.

./update.sh

[Optional] Cost Savings: Scale to Zero

PII Eraser supports a "Scale to Zero" model. This is ideal for batch processing workflows where you only pay for PII Eraser and compute infrastructure while processing data.

We provide a Python utility, manage_service.py, to programmatically control the stack. The script can set the desired number of instances and also pauses the autoscaler when stopped.

Option 1: Manual Control (CLI)

You can manually wake up or sleep the service from your terminal:

# Check current status
python manage_service.py status --region <your region>

# WAKE UP: Start 1 container and wait for it to be ready
python manage_service.py start --count 1 --region <your region>

# SLEEP: Scale to 0 (Stop all billing)
python manage_service.py stop --region <your region>

Option 2: Automated Batch Processing (Python)

If you are running a Python script to process a batch of documents, you can import the service manager to automatically handle the infrastructure lifecycle. In particular, the service manager allows you to scale to a certain number of instances, allowing the autoscaler lag to be avoided.

from manage_service import PIIEraserService

# Initialize the manager
eraser = PIIEraserService(stack_name="pii-eraser-stack", region="eu-west-1")

try:
    # 1. Wake up: Scale to desired instance count
    print("🚀 Waking up PII Eraser...")
    eraser.scale(3)

    # 2. Run your batch processing
    process_sensitive_data()

finally:
    # 3. Sleep: Scale to 0 to stop billing
    print("💤 Scaling to zero...")
    eraser.scale(0)