Containers

AWS Fargate platform versions primer

AWS Fargate is a managed service to run containers. This is an AWS managed service that allows users to launch containers without having to worry about the infrastructure underneath. In another blog post, we explored in detail the new features and the changes we introduced with AWS Fargate platform version 1.4.0. Let’s step back and talk more holistically about Fargate platform versions.

As you know, the whole purpose of containers and container runtimes (such as Containerd) is to decouple the container image (what the user brings) from the operating system said image is going to be launched on (what AWS Fargate provides). This, however, is not a clean separation and these two layers can potentially leak some of the abstractions.

An abstraction layer that leaks is not a novel event in this industry. This has been less of a problem with hypervisors and VMs that serve the same decoupling purpose at a layer below. That said, even though the interfaces between these two layers were well established and less prone to leak into each other, there have been situations where one layer had to be aware of changes in the other. Just think, for example, about the migration from standard EC2 instances to Nitro-based EC2 instances and the ramification this had on AMIs. For example, in order to use Nitro-based instance types the AMI must include specific network drivers as detailed in the documentation.

Because of the above, we wanted stronger controls over the interfaces that we were exposing to containers running on AWS Fargate. This is where Fargate platform versions came into play. By selecting a specific platform version and sticking with it, developers can make sure the underlying infrastructure and supporting software doesn’t change thus maintaining high fidelity across their stacks and reducing the risk of changing the abstractions.

With platform version 1.3.0, we have introduced a considerable number of new features since we launched almost a year ago. While we do not expect the changes in platform version 1.4.0 to be breaking, we decided that they were so substantial that a new platform version would have given a better run-way for users and low risk to adopt it if they could go back to platform version 1.3.0.

Fargate platform versions consumption basics

Before we dive deeper into how the platform versions lifecycle works, let’s review some of the basics.

As alluded above, platform versions are used to introduce major new features for AWS Fargate. For example, PV 1.1.0 introduced the task metadata endpoint. Since features are usually introduced by new software deployed and managed by AWS in the Fargate service, they are tied to new software releases. This software is baked into AMIs and it includes the agent(s) we install, the container runtime we use and everything else that, collectively, is used to deliver the AWS Fargate service for a developer to consume transparently.

Consuming AWS Fargate via ECS

When you launch a new ECS task with the Fargate launch type, either with the run-task command or with a create-service command, you have the option of selecting a platform version. It can either be a specific number (as of today this could be 1.0.0, 1.1.0, 1.2.0, 1.3.0, or 1.4.0) or it could be LATEST in which case the latest PV will be picked (more on this later). For a complete list of all PVs available, you can check the Fargate documentation.

For example, this is a run-task call with the FARGATE launch type where the LATEST platform version is being used:

aws ecs run-task --cluster <clustername> \
                 --task-definition <taskdefinition>:<version> \
                 --launch-type FARGATE \
                 --platform-version LATEST 
                 --network-configuration "awsvpcConfiguration={subnets=[<subnet1>,<subnet2>],securityGroups=[<securitygroup>],assignPublicIp=ENABLED}"

Note that, similarly, when you create an ECS service (using create-service) and your ECS task uses LATEST, this will be resolved to the latest platform version available at the time of the create-service command.

Under the current model, if subsequently new versions are released and the LATEST tag move to newer versions, that service will continue to deploy tasks with a Fargate platform identical to the platform that was used at the time of the create-service command when LATEST was originally resolved. To change the platform version for your service, you have to use the update-service command. Let’s make a practical example:

  • Last year you launched a new ECS service backed by Fargate and specified LATEST as the platform version
  • LATEST, at that time, resolved to 1.2.0 because that was the latest platform version available. Fargate tasks with platform version 1.2.0 were deployed
  • We launched 1.3.0 since and we moved the LATEST tag to this version
  • After we launched 1.3.0, you attempt to scale out your service (which still uses LATEST). In this case, version 1.2.0 is still used because that was the latest version that was resolved when the service was initialized
  • If you were to update your service (e.g. with the ECS service update API or AWS console workflow), the LATEST tag would be re-resolved and 1.3.0 would be used for all tasks being re-deployed.

In addition to introducing new platform versions, we are regularly updating these platform versions. While we have not made it very explicit in the documentation (and this blog post is an effort to clarify that), we are making small revisions, or “updates” if you will, which are not being tracked by a public facing version number bump. Instead, the way these updates are surfaced to the user is through a note, under a specific platform version, that says “Beginning on <date>, any new Fargate task that is launched supports <new feature>.”

For example, if you look at the list of the currently available platform versions in the documentation you will note that platform version 1.3.0 has introduced some changes over time. These are often CVEs we need to fix and/or features we are adding that are not worth the creation of an entirely new release. From a Fargate platform version consumption perspective, the only thing to be aware of is that, when you land on a given version (either because explicitly required or because resolved by LATEST) the last available patch of that specific platform version is always being used. There isn’t a mechanism available to request that a specific revision within the platform version you have requested. We have learned that this is not a problem for customers, which is signaling that the decoupling promise of the container runtime is being honored.

So if we consider the example above, the first time we initialized the service and platform version 1.2.0 was used we would have deployed the latest patch for platform version 1.2.0. When we later scaled out the service, we kept using version 1.2.0 but most likely the latest patch for that platform will have changed. So the tasks in your service would be using the same platform version with slightly different patch versions. When/if existing tasks get re-cycled they all get the latest patch version for the platform version they are intended to use.

Consuming AWS Fargate via EKS

At re:Invent 2019, we launched a new integration between AWS Fargate and Amazon EKS. Now EKS customers can consume the Fargate service in a way that is similar to how ECS customers have consumed Fargate.

The way this integration works is explained at the high level in this blog post. Because EKS support for AWS Fargate was released at re:Invent 2019, it was directly launched on platform version 1.4.0. The EKS team had early access to this platform version that we are now making generally available with this announcement.

Note that EKS itself has a notion of a platform version, which is a mechanism that is used to track the various cluster features and configurations. EKS platform versions go above and beyond tracking the Kubernetes version and include enhancements and additional features support.

We want to keep the EKS/Fargate user experience abstracted from the visibility of the native Fargate platform versions and potentially only surfaced to the user as part of the EKS platform versions.

The evolution of Fargate platform versions

As we have mentioned, since Fargate was introduced in 2017 we have made available five platform versions: 1.0.0, 1.1.0, 1.2.0, 1.3.0, and 1.4.0. None of these releases have been deprecated and are still currently all available for customers to consume (although the vast majority of all tasks are running on 1.3.0). In addition to this, we have usually promptly changed the LATEST flag to point to the release we had just made available. This approach has worked well for us and our users so far.

With the announcement of platform version 1.4.0, we are tuning this model in order to better protect our users and, ultimately, mitigate further any compatibility risk that may surface.

The changes we will be introducing will cover a couple of axes. Let’s investigate these changes in some details.

A less aggressive move to the LATEST flag

Starting with the introduction of this platform version (1.4.0), we will hold on moving the LATEST tag. We want to provide a runway for users that use LATEST as an additional precaution. This means that if you are deploying today using the tag LATEST to identify a Fargate platform version, the system will keep referencing platform version 1.3.0 for now (albeit, technically, the latest platform version available today is 1.4.0).

These users could either start experimenting with 1.4.0 by explicitly deploying to it or wait until we move the tag LATEST to point to platform version 1.4.0. [Updated on 6/17/2020] We plan to make this change in the May 2020 time frame We plan to make this change at some point in Q3/2020, thus giving customers [Updated on 6/17/2020] about a month a few months to test 1.4.0 before it gets tagged as LATEST. Expect a formal announcement for this change.

This is intended to give users a window of time to test 1.4.0 without being forced to use it if they use the tag LATEST. We do not anticipate disruption but we decided to be conservative.

AWS Fargate platform versions lifecycle

While we are here, we want to provide some forward-looking statements about what we are planning to introduce down the road. We intend to introduce a smooth deprecation process for old Fargate platform versions in a non-disruptive way. This is required, for example, because platform versions 1.0.0 through 1.2.0 are based on Amazon Linux 1 (AL1) and the current plan is that AL1 will be going “End of Life” at the end of 2020. We plan to introduce this process in a way that will not disrupt customer operations.

We will introduce states to characterize each platform version. To make it clearer how the deprecation process works and what the state of each platform version is, we will be introducing new states for each of them. These states will be discoverable programmatically with API enhancements.

The states we will introduce are: Active, Deprecating, Retired, and Recalled. With the only exception of the “Recalled” state, all the others are not intrusive into the running workloads and we believe they will allow for a smooth migration to newer and “Active” Fargate platform versions. We will provide more information about these changes as we get closer to the launch date. Fargate users are obviously encouraged to use the latest platform versions.

Conclusions

In this blog post, we have taken the opportunity to explain the philosophy and why we use platform versions with AWS Fargate. If you are new to AWS Fargate, this is a good starting point to start playing with it and appreciate what it means to run containers without worrying about the infrastructure. If you are an AWS Fargate user or simply you have evaluated it in the past but you determined that there were limitations to satisfy your requirements, please check out the list of new features we have announced with the new Fargate platform version 1.4.0. Chances are that these new features can unlock new use cases for which Fargate could be considered.

Massimo Re Ferre

Massimo Re Ferre

Massimo is a Principal Developer Advocate at AWS. For about 25 years, he specialized on the x86 ecosystem starting with operating systems, virtualization technologies and cloud architectures. He has been working on containers since 2014 and that is Massimo’s current area of focus within the compute service team at AWS . Massimo has a blog at www.it20.info and his Twitter handle is @mreferre.