Containers

AWS Proton: A first look

When talking to engineering teams, especially at the enterprise size, we often see them organized into dev teams and a platform team. The dev teams are typically tasked with creating and maintaining services, and the platform team is tasked with building tooling to make it easier for the dev teams to deploy their services. That tooling will often “bake in” known good practices around build pipelines, observability, scaling, and security.

Today we are introducing AWS Proton: a service designed for the platform engineering teams who want to offer their own self-service interface that provides opinionated methods for running serverless and container-based applications on AWS.

Let’s take a closer look, using a very common use case: a service team that provides a frontend, or provides an API service via a running container. With AWS Proton, the service team no longer needs to learn a new Infrastructure as Code (IaC) language, or understand container orchestration, build pipelines, or autoscaling logic. They can focus on writing code. The platform team can define all of the business requirements around running that code, and offer that up in a package the service team can provision.

To get started, I’ve cloned our example template repo. A few of the commands use our account ID, so I’ll start by setting that as a variable in my environment:

cd ~/environment/
account_id=$(aws sts get-caller-identity --output text --query Account)

While AWS Proton is in preview, you’ll have to manually configure the AWS CLI by adding an additional model:

aws s3 cp s3://aws-proton-preview-public-files/model/proton-2020-07-20.normal.json .
aws s3 cp s3://aws-proton-preview-public-files/model/waiters2.json .
aws configure add-model --service-model file://proton-2020-07-20.normal.json --service-name proton-preview
mv waiters2.json ~/.aws/models/proton-preview/2020-07-20/waiters-2.json
rm proton-2020-07-20.normal.json

Next we want to create an S3 bucket to store our templates:

aws s3api create-bucket --bucket "proton-cli-templates-${account_id}" --region us-east-1

Since we’ll be offering a “Load Balanced Fargate Service,” we can change directory to that part of the example template repository (substitute the location where you cloned the repository):

cd ~/environment/aws-proton-sample-templates/loadbalanced-fargate-svc/

Proton builds infrastructure using the Identity and Access Management (IAM) role you provide it, so it can easily be customized to your needs. For our example, we’re going to use the sample role and policy provided. The first command creates a role named ProtonServiceRole. The second command attaches the AWS managed AdministratorAccess policy to the ProtonServiceRole. The third command allows the Proton service to use the ProtonServiceRole when provisioning infrastructure.

aws iam create-role --role-name ProtonServiceRole --assume-role-policy-document file://./policies/proton-service-assume-policy.json

aws iam attach-role-policy --role-name ProtonServiceRole --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

aws proton-preview \
  --endpoint-url https://proton.us-east-2.amazonaws.com \
  --region us-east-2 \
  update-account-roles \
  --account-role-details "pipelineServiceRoleArn=arn:aws:iam::${account_id}:role/ProtonServiceRole"

Now that AWS Proton has permission to provision infrastructure, let’s define our templates!

There are two main types of templates: environment and service. An environment is a set of shared resources and policies that apply to all services deployed to it. A service defines how we want our application to run within a given environment.

We’ll start by defining an environment template:

aws proton-preview \
  --endpoint-url https://proton.us-east-2.amazonaws.com \
  --region us-east-2 \
  create-environment-template \
  --template-name "proton-example-dev-env" \
  --display-name "ProtonExampleDevVPC" \
  --description "Proton Example Dev VPC with Public Access and ECS Cluster"

We then tag the template with a major version:

aws proton-preview \
  --endpoint-url https://proton.us-east-2.amazonaws.com \
  --region us-east-2 \
  create-environment-template-major-version \
  --template-name "proton-example-dev-env" \
  --description "Version 1"

Ordinarily, this would be where we iterate on the CloudFormation template, but for the demo, we can just tar up the example and upload it to our S3 bucket:

tar -zcvf env-template.tar.gz environment/ && aws s3 cp env-template.tar.gz s3://proton-cli-templates-${account_id}/env-template.tar.gz && rm env-template.tar.gz

Now, we inform Proton that we have a new version of our environment template available and wait for it to complete registration. Pay close attention to the minor version in the output of the registration command, and ensure that’s the minor version you’re waiting for in the second command:

aws proton-preview \
  --endpoint-url https://proton.us-east-2.amazonaws.com \
  --region us-east-2 \
  create-environment-template-minor-version \
  --template-name "proton-example-dev-env" \
  --description "Proton Example Dev Environment Version 1" \
  --major-version-id "1" \
  --source-s3-bucket proton-cli-templates-${account_id} \
  --source-s3-key env-template.tar.gz

aws proton-preview \
  --endpoint-url https://proton.us-east-2.amazonaws.com \
  --region us-east-2 \
  wait environment-template-registration-complete \
  --template-name "proton-example-dev-env" \
  --major-version-id "1" \
  --minor-version-id "0"

We could iterate on our CloudFormation template and could register versions, incrementing the minor-version-id each time. Once we’re happy and want to make the code available to others, we Publish it:

aws proton-preview \
  --endpoint-url https://proton.us-east-2.amazonaws.com \
  --region us-east-2 \
  update-environment-template-minor-version \
  --template-name "proton-example-dev-env" \
  --major-version-id "1" \
  --minor-version-id "0" \
  --status "PUBLISHED"

This takes care of creating and publishing the template to build our infrastructure. Now, let’s go through the same process to offer a service template (with abbreviated steps this time):

aws proton-preview \
  --endpoint-url https://proton.us-east-2.amazonaws.com \
  --region us-east-2 \
  create-service-template \
  --template-name "lb-fargate-service" \
  --display-name "LoadbalancedFargateService" \
  --description "Fargate Service with an Application Load Balancer"

aws proton-preview \
  --endpoint-url https://proton.us-east-2.amazonaws.com \
  --region us-east-2 \
  create-service-template-major-version \
  --template-name "lb-fargate-service" \
  --description "Version 1" \
  --compatible-environment-template-major-version-arns arn:aws:proton:us-east-2:${account_id}:environment-template/proton-example-dev-env:1

tar -zcvf svc-template.tar.gz service/ && aws s3 cp svc-template.tar.gz s3://proton-cli-templates-${account_id}/svc-template.tar.gz && rm svc-template.tar.gz

aws proton-preview \
  --endpoint-url https://proton.us-east-2.amazonaws.com \
  --region us-east-2 \
  create-service-template-minor-version \
  --template-name "lb-fargate-service" \
  --description "Version 1" \
  --major-version-id "1" \
  --source-s3-bucket proton-cli-templates-${account_id} \
  --source-s3-key svc-template.tar.gz

aws proton-preview \
  --endpoint-url https://proton.us-east-2.amazonaws.com \
  --region us-east-2 \
  wait service-template-registration-complete \
  --template-name "lb-fargate-service" \
  --major-version-id "1" \
  --minor-version-id "0"

aws proton-preview \
  --endpoint-url https://proton.us-east-2.amazonaws.com \
  --region us-east-2 \
  update-service-template-minor-version \
  --template-name "lb-fargate-service" \
  --major-version-id "1" \
  --minor-version-id "0" \
  --status "PUBLISHED"

Great! This demonstrates how a platform team might offer self-service infrastructure provisioning and service deployment to service teams, but what does that look like for the service teams that want to use the platform team’s offerings?

Let’s explore the AWS Proton console here.

If we begin in the Templates section, we see the Environment template we created above to allow self-service infrastructure provisioning:

Under Service templates, we see the template created to allow self-service application provisioning and deployment.

As a service team, we can now move to the Environments section and build our first application environment. Just choose Create Environment and then choose the template we created earlier.

We can fill in some basic info that will help us distinguish this environment from others in the account. In this example, we are creating a development environment for our application.

The example template has inputs to allow customizing the subnet CIDR addresses, so we will create custom CIDR addresses for our application.

Click Create to build the application environment. This provisions all of the infrastructure in the Environment template, including VPC, subnets, gateways, ECS cluster, security groups, etc.

Once our environment is built, we can provision our application. We start by choosing Services / Create Service and selecting our LoadbalancedFargateService template and clicking Configure.

We can fill in the settings for the Service and Service Repository. The Service settings define how to name and describe the app. The Service Repository settings will be used to construct the CI/CD pipeline.

Next, we define a Service Instance and customize the values for the input parameters from our template. This defines exactly how our service should be executed.

Click Create to deploy your initial service. This will use the template created by the platform team to provision a Load Balancer, Target Group, ECS Task Definition, CloudWatch Logs Stream, Target Tracking Autoscaling for our Application, ECR Repository, CodePipeline project, and anything else defined by our platform team in the service template.

That’s it! With this demo, we show how a platform team can define infrastructure and services using templates. The platform team can ensure all the important requirements around scaling, monitoring, and availability are met by owning the templates.

Service teams can self-service provision infrastructure and deploy their services using these infrastructure templates, just by filling in a few values, without worrying about how to build and manage complex infrastructure.

AWS Proton is available in public preview starting today! As you use it, please check out our roadmap and open issues here.