Deploying OPA on AWS ECS
Amazon ECS (Elastic Container Service) is a managed platform for running containerized applications. Software already packaged as containers, like OPA, is easy to run on ECS. ECS takes care of scaling, networking, and infrastructure, allowing you to focus on building and integrating your applications.
ECS is great for hosting a centralized OPA, Policy Decisions Point (PDP) service to be accessed by Policy Enforcement Points (PEPs, e.g. business apps and services) running elsewhere in your environment. ECS also supports running OPA as a daemon or additional container alongside your other application containers too but this pattern is not covered here.
This guide will explain the steps and key considerations for deploying an OPA service using ECS.
Supplying Configuration to OPA
While the default OPA configuration is simple, OPA has many different options and settings. Like many other tools, OPA is commonly configured using a file mounted into its container at a known path. There are many ways to configure OPA on ECS:
- Loading a config file from S3 and using environment variable substitution for secret values from KMS.
- Using AWS AppConfig
and the
aws-appconfig-agent
sidecar container to load the config file at start up. - Using command line flags to set values and not using a config file at all.
Since the preferred option is largely dependent on your organization's approach to secrets management, we leave this exercise to the reader. The following guide uses command line configuration with secrets loaded from KMS, to keep the example simple to follow.
Selecting or Creating an ECS Cluster
An ECS cluster is a logical grouping of Amazon Elastic Container Service (ECS) resources used to run and manage Docker containers using AWS Fargate.
All applications running in ECS are part of an ECS cluster. When creating a cluster for OPA, it's recommended to use the Fargate infrastructure type - rather than EC2. Please see our EC2 Guide if you'd like to run OPA on EC2.
Within our cluster, we will be running OPA using the following architecture:
Creating a Secret and IAM Role for your OPA Task
OPA needs to download policy and configuration from DAS at startup, requiring an API token for access. Although the token has limited permissions, it should be securely stored. In this section, we’ll create a secret in AWS Secrets Manager, an IAM policy to access the secret, and an IAM role with that policy for the ECS task to use.
Create a secret with the following keys:
TOKEN
: The DAS API token from the Install page in the DAS System settings.SYSTEM_ID
: The DAS System ID.TENANT
: The DAS tenant name, e.g.example
inhttps://example.svc.styra.com
Once you have created the secret, note it's ARN here set it in the later steps: .
Next, create a IAM policy with the following rules to allow the OPA task to access the secret:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "secretsmanager:GetSecretValue", "Resource": " } ] }
Now you can create a new Role referencing this policy to use as the
taskRoleArn
for the rest of the guide. When you have created the role, note
the ARN here to populate the later steps: .
Creating an OPA Task Definition
An ECS task definition is a blueprint that describes how containers should run in AWS ECS, specifying details like container images, commands and resource requirements. In this section, we will build a task definition for use on ECS to run OPA.
Before continuing, please ensure you have set the following:
- Service Name: (This is the name for the service as it will appear in ECS)
- Secret ARN: (if you have not already set or created the secret, please do so before continuing)
- Region:
- OPA Version: , e.g.
X.Y.Z
notlatest
orvX.Y.Z
. Review the OPA images for a list of available versions.
{ "family": "", "containerDefinitions": [ { "name": "opa", "image": "openpolicyagent/opa:", "cpu": 0, "portMappings": [ { "name": "opa-8181-tcp", "containerPort": 8181, "hostPort": 8181, "protocol": "tcp" } ], "essential": true, "command": [ "run", "--server", "--set", ""discovery.name=discovery"", "--set", ""discovery.prefix=/systems/${SYSTEM_ID}"", "--set", ""discovery.service=styra"", "--set", ""labels.system-id=${SYSTEM_ID}"", "--set", ""labels.system-type=custom"", "--set", ""services[0].credentials.bearer.token=${TOKEN}"", "--set", ""services[0].name=styra"", "--set", ""services[0].url=https://${TENANT}.svc.styra.com/v1"", "--set", ""services[0].credentials.bearer.token=${TOKEN}"", "--set", ""services[0].name=styra-bundles"", "--set", ""services[0].url=https://${TENANT}.svc.styra.com/v1/bundles"" ], "environment": [], "mountPoints": [], "volumesFrom": [], "secrets": [ { "name": "SYSTEM_ID", "valueFrom": ":SYSTEM_ID::" }, { "name": "TENANT", "valueFrom": ":TENANT::" }, { "name": "TOKEN", "valueFrom": ":TOKEN::" } ], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/", "mode": "non-blocking", "awslogs-create-group": "true", "max-buffer-size": "25m", "awslogs-region": "", "awslogs-stream-prefix": "ecs" } }, "systemControls": [] } ], "taskRoleArn": "", "networkMode": "awsvpc", "volumes": [], "placementConstraints": [], "requiresCompatibilities": [ "FARGATE" ], "cpu": "1024", "memory": "2048", "runtimePlatform": { "cpuArchitecture": "X86_64", "operatingSystemFamily": "LINUX" } }
Deploying OPA on the Cluster
Once you have a task definition in place, you can deploy it to your ECS cluster.
- Create a new service in the cluster where you'd like to deploy OPA.
- Use a
Service
as theApplication type
, OPA will be a long running service. - Select as the
Family
of task definitions.
Once the service is created, ECS will start a task using the task definition and you should see the OPA reporting status to DAS shortly after.
Accessing the OPA service
There are many options to access the OPA service running on ECS from your PEPs. The right option for your use case will depend on the location of OPA's callers in your infrastructure - among other factors like security and performance. A brief overview of some options is provided below.
- Application Load Balancer (ALB): Well suited to OPA's REST API HTTP traffic, ALB operates at Layer 7 and supports advanced routing features. Use an ALB when you need to route requests to OPA based on URL paths or host headers or require integration with AWS services like AWS WAF.
- Network Load Balancer (NLB): Best suited for high performance OPA use cases where response times are critical. Read more about NLB integration with ECS.
- Service Discovery with AWS Cloud Map: Allows internal clients within the same VPC to access the OPA service using DNS names. Opt for this when your OPA clients are inside your AWS network, and you want to avoid exposing services to the internet.
Further Reading
- SDKs for building PEP applications in your language of choice.