Amazon Elastic Container Service
Overview
DataGrail recommends deploying the Request Manager Agent in Amazon Elastic Container Service (ECS). Deploying an ECS service will result in most of the details of load balancing, SSL termination, and service uptime being managed in a simple and standard manner. This toolchain provides simple and robust management of your deployment. To get an overview of ECS, check out Amazon's documentation.
Sourcing the Agent Image
The Request Manager Agent Docker image is hosted in DataGrail's Elastic Container Registry. Once access is granted, use this path for retrieving the image:
338780525468.dkr.ecr.us-west-2.amazonaws.com/datagrail-rm-agent:v0.8.11
If you would like to, you may clone this image into your own Docker repository, or use it directly from our repository upon service startup.
Network Communication Requirements
The Agent service does not support internal SSL termination, so configuring a load balancer or another form of SSL termination is required. TLS 1.2+ is required to provide secure communication between services.
Ingress will be made to the Agent over port 443 and will arrive from our VPC IP: 52.36.177.91
. Inbound requests from any other source should be rejected.
The Agent will make network requests to:
- Systems you have configured
- Storage Bucket for storing results
- Secret Manager for retrieving credentials
- DataGrail at
https://<customer-name>.datagrail.io
Environment Variables
Agent Configuration
The Request Manager Agent's primary configuration is sourced from an environment variable named DATAGRAIL_AGENT_CONFIG
which defines the connections available for the Agent and the credentials used for authenticating with DataGrail.
Example DATAGRAIL_AGENT_CONFIG
{
"connections": [
{
"name": "Metrics DB",
"uuid": "272c0934-0a06-4b11-8ec9-7755499001a3",
"capabilities": ["privacy/access","privacy/delete"],
"mode": "live",
"connector_type": "Redshift",
"queries": {
"access": ["call dsr('access', %(email)s)"],
"delete": ["call dsr('delete', %(email)s)"]
},
"credentials_location": "arn:aws:secretsmanager:us-west-2:000123456789:secret:redshift-cvh7s2"
}
],
"customer_domain": "acme.datagrail.io",
"datagrail_agent_credentials_location": "arn:aws:secretsmanager:us-west-2:000123456789:secret:datagrail-agent-sjc7s3",
"datagrail_credentials_location": "arn:aws:secretsmanager:us-west-2:000123456789:secret:datagrail-bs83nh",
"platform": {
"credentials_manager": {
"provider": "AWSSecretsManager"
},
"storage_manager": {
"provider": "AWSS3",
"options": {
"bucket": "acme-datagrail-reports"
}
}
}
}
Access Keys
As a best practice, use temporary security credentials (such as IAM roles) instead of creating long-term credentials like access keys.
In general, we recommend giving the Agent service permissions through IAM roles if you are operating in an AWS environment. However, you may also specify account credentials as environment variables directly.
The access keys require the permissions from the Policy section.
Example Access Keys Variables
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
AWS_REGION=us-west-2
Quick Setup Guide
The following sections contain the core steps to creating an ECS Agent service. Please note that depending on your AWS environment's pre-existing configuration, you may need to take additional steps to configure your VPC, subnets, etc. Those are not covered in this document but we are happy to provide you with any assistance we can offer.
Create Task Policy and Role
To give the ECS service permission to make API requests to AWS services, you will need to define a task IAM policy and role.
Policy
- In the AWS console, navigate to Identity and Access Management.
- Under Access management, select Policies and then Create policy.
- In the Policy editor, select JSON on the right-hand side.
- At a minimum, the Agent should be allowed to perform the s3:PutObject and secretsmanager:GetSecretValue actions on a set of defined resources. Use the below example policy and update it with the ARNs of your resources.
Example Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3PutObject",
"Action": "s3:PutObject",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::<datagrail_s3_bucket_name>/*",
"arn:aws:s3:::<datagrail_s3_bucket_name>"
]
},
{
"Sid": "SecretsManagerGetSecretValue",
"Action": "secretsmanager:GetSecretValue",
"Effect": "Allow",
"Resource": [
"arn:aws:secretsmanager:<region>:<account_id>:secret:<datagrail_secret_name>",
"arn:aws:secretsmanager:<region>:<account_id>:secret:<datagrail_agent_secret_name>",
"arn:aws:secretsmanager:<region>:<account_id>:secret:<connector_1_secret_name>",
"arn:aws:secretsmanager:<region>:<account_id>:secret:<connector_2_secret_name>",
"<more_connector_arns...>"
]
}
]
}
- Once done creating the policy, click Next.
- Create a name for the policy and optionally a description.
- Confirm that the permissions in the Permissions defined in this policy are accurate and add any optional tags.
- Click Create policy.
Role
- Navigate back to the IAM home screen.
- Under Access management, select Roles and then Create role.
- Under Trusted entity type, select AWS service.
- Under Use case, choose Elastic Container Service as the service, and Elastic Container Service Task as the use case and click Next.
- In the Permissions policies section, search for the policy that you have just created and select it.
- Under Role details, give the role a name and optionally update the description.
- Click Create role.
Create ECS Cluster
Optional if the Agent service will be deployed in an existing cluster.
- Navigate to Elastic Container Service, making sure you are in your desired AWS region.
- In the left-hand menu, select Clusters and then Create cluster.
- Under Cluster configuration, give the cluster a Name.
- Under Infrastructure, select AWS Fargate (serverless).
- Click Create.
Create Task Definition
To create an ECS service, you will need to define a Task Definition which contains details of the Agent container's environment, configuration, and system resources.
- In the AWS console, navigate to Elastic Container Service, making sure to select your desired AWS region.
- In the left-hand menu, select Task definitions, then Create new task definition, and Create new task definition with JSON.
Creating a task definition with JSON will allow you to define the container's environment variables, configuration, and resources in a single JSON object. In the below example, make sure that you update the taskRoleArn
, executionRoleArn
, the awslogs-region
with the appropriate region, and image
parameters with your own ARNs, and the value
of the DATAGRAIL_AGENT_CONFIG
variable with the contents created in the Environment Variables section.Example Task Definition
{
"taskRoleArn": "arn:aws:iam::012345678912:role/DataGrailAgentTakeRole",
"executionRoleArn": "arn:aws:iam::012345678912:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"essential": true,
"name": "datagrail-rm-agent",
"image": "338780525468.dkr.ecr.us-west-2.amazonaws.com/datagrail-rm-agent:v0.8.11",
"portMappings": [
{
"hostPort": 80,
"protocol": "tcp",
"containerPort": 80
}
],
"command": [
"supervisord",
"-n",
"-c",
"/etc/rm.conf"
],
"cpu": 0,
"environment": [
{
"name": "DATAGRAIL_AGENT_CONFIG",
"value": ""
}
],
"mountPoints": [],
"workingDirectory": "/app",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/datagrail-rm-agent",
"awslogs-region": "us-west-2",
"awslogs-stream-prefix": "/ecs"
}
},
"healthCheck": {
"retries": 3,
"command": [
"CMD-SHELL",
"curl -f http://localhost/docs || exit 1"
],
"timeout": 5,
"interval": 30,
"startPeriod": 1
}
}
],
"family": "datagrail-rm-agent",
"requiresCompatibilities": [
"FARGATE"
],
"runtimePlatform": {
"operatingSystemFamily": "LINUX"
},
"networkMode": "awsvpc",
"cpu": "1024",
"memory": "2048"
}
Create Security Groups
The Agent service requires security groups for both the load balancer and service to act as a virtual firewall to control inbound and outbound traffic.
- Navigate to EC2 and select Security Groups under Network & Security in the left-hand menu.
Load Balancer Security Group
- Click Create security group.
- In the Basic details section,
- Give the security group a Name indicating that it is for the load balancer (e.g. "datagrail-rm-agent-load-balancer-sg"). This is important to later identify the security group to use when creating the load balancer.
- Add a Description of the security group (e.g. "Allow HTTPS ingress to DataGrail and TCP egress to DataGrail Agent service").
- Select the VPC that the load balancer will be created in.
- In the Inbound Rules section,
- Click Add rule.
- In the Type dropdown, select HTTPS.
- In the Source dropdown, select Custom.
- Add 52.36.177.91/32 (DataGrail's IP) as the only allowed CIDR block.
The next step is temporary. An outbound rule will be created later to allow egress from the load balancer to the service security group after it has been created.
- Under Outbound rules, delete the default rule.
- Click Create security group.
Service Security Group
- Navigate back to Security Groups and click Create security group.
- In Basic details,
- Give the security group a Name, indicating that it is for the service (e.g. "datagrail-rm-agent-service-sg"). This is important to later identify the security group to use when creating the service.
- Add a Description (e.g. "Allow ingress to application load balancer").
- Select the VPC that the service will be created in.
- In Inbound Rules,
- Click Add rule.
- In the Type dropdown, select Custom TCP.
- Under Port range, enter 80.
- In the Destination dropdown, select Custom, and select the security group created in the Load Balancer Security Group section under Security Groups.
- Under Outbound Rule, leave the default All traffic rule.
- Click Create security group.
Now that the service security group has been created, an outbound rule to the application load balancer security group can be added.
- Navigate back to security groups and select the security group created in the Load Balancer Security Group.
- Under Actions in the top-right, select Edit outbound rules.
- Click Add rule.
- In the Type dropdown, select Custom TCP.
- Under Port Range, enter 80.
- In the Destination dropdown, select Custom, and select the security group created in the Service Security Group section under Security Groups.
Create Target Group
The target group defines where the load balancer routes requests and performs health checks on the targets.
- Navigate to EC2 and select Target Groups under Load Balancing in the left-hand menu.
- Click Create target group.
- In the Basic configuration section,
- Under Choose a target type, select IP addresses.
- Under Target group name, give the target group a name indicating that it is for the Agent service load balancer (e.g. "datagrail-rm-agent-target-group")
- Under Protocol : Port, select HTTP in the Protocol dropdown, and enter 80 in the Port field.
- Under IP address type, select IPv4.
- Under VPC, select the VPC where the Agent service will be deployed.
- Under Protocol version, select HTTP1.
- In the Health checks section,
- Under the Health check protocol dropdown, select HTTP.
- Under the Health check path field, enter /docs.
- Click Next.
- On the Register targets, do not modify any settings and click Create target group. The Agent service will be registered during its creation.
Create Application Load Balancer
- Navigate to EC2, and select Load Balancers under Load Balancing in the left-hand menu.
- Click Create load balancer.
- Under Load balancer types, select Create under Application Load Balancer.
- Under Basic configuration,
- Enter a Load balancer name.
- Under Scheme, select Internet-facing.
- Under IP address type, select IPv4.
- Under Network mapping,
- Select the VPC, select the VPC where the Agent service will be deployed.
- Under Mappings, select at least two Availability Zone and one public subnet per zone
- Under Security groups, remove the default group and select the security group you created in the Load Balancer Security Group section.
- Under Listeners and routing,
- In the Protocol dropdown, select HTTPS.
- In the Port field, enter 443.
- Set the Default action to Forward to the target group that you created in the Create Target Group section.
- Under Security policy,
- In the Security category dropdown, select All security policies.
- In the Policy name dropdown, select ELBSecurityPolicy-TLS13-1-2-2021-06.
- Review the Summary to make sure everything looks correct.
- Click Create load balancer
Create ECS Service
- Navigate to Elastic Container Service and select Clusters in the left-hand menu.
- Select the cluster in which you will be deploying the Agent.
- In the Services tab, select Create.
- Under the Environment section in the Create wizard, modify the Compute configuration.
- Under Compute options, select Launch type.
- In the Launch type dropdown, select FARGATE.
- In the Platform version dropdown, select LATEST.
- Under the Deployment configuration section,
- Under Application type, select Service.
- Under Task definition, select the task definition you created in the Create Task Definition section and select the latest Revision.
- Under Service name, give the service a name (e.g. "datagrail-rm-agent-service").
- Under Service type, select Replica.
- Under Desired tasks, enter 1.
- Leave all default values under Deployment options and Deployment failure detection.
- Under the Networking section,
- Select the VPC that you will be deploying the Agent in.
- Under Subnets, select a private subnet to place the Agent in.
- Under Security group, select Use and existing security group.
- Remove the default security group and select the security group created in the Service Security Group section.
- Under the Load balancing section,
- In the Load balancer type dropdown, select Application Load Balancer.
- The Container dropdown will prepopulate with the single container defined in the task definition.
- Under Application Load Balancer, select Use and existing load balancer.
- In the Load balancer dropdown, select the load balancer that you created in the Create Application Load Balancer section.
- In the Health check grace period field, enter 15.
- Under Listener, select Use an existing listener and select 443:HTTPS in the Listener dropdown.
- Under Target group, select Use an existing target group, and select the target group created in the Create Target Group section in the Target group name dropdown.
- Select Create.
You should then see the service appear on the management page of the cluster under the Services section. Click on the service and then on the Tasks tab in the service. If tasks are not in a Running state within a few minutes, you can inspect the stopped tasks to look for any errors or failures.
Create Alias Record for Application Load Balancer in Route 53
- Navigate to Route 53 and click on Hosted zones in the left-hand menu.
- Select the hosted zone where you will be deploying the Agent and click Create record.
- In the Record name field, enter the subdomain that you would like to use (e.g. "datagrail-rm-agent").
- In the Record type dropdown, select A.
- Toggle the Alias button ON.
- Under Route traffic to,
- Select Alias to Application and Classic Load Balancer in the Choose endpoint dropdown.
- Select the region where the load balancer was deployed in the Choose Region dropdown.
- Select the load balancer in the Choose load balancer dropdown.
- Keep Routing policy set to Simple routing and Evaluate target health set to Yes
- Click Create records.
Your Agent service will now be reachable at your subdomain!
Disclaimer: The information contained in this message does not constitute as legal advice. We would advise seeking professional counsel before acting on or interpreting any material.