I'm trying to use the newish EFS mounts in an EC2 ECS cluster and the resources are refusing to include the extra parameters even if I try to use the raw resources.
import * as ec2 from "@aws-cdk/aws-ec2";
import * as ecs from "@aws-cdk/aws-ecs";
import * as efs from "@aws-cdk/aws-efs";
import * as elbv2 from "@aws-cdk/aws-elasticloadbalancingv2";
import * as logs from "@aws-cdk/aws-logs";
import * as cdk from "@aws-cdk/core";
export interface WebserverProps {
filesystem: efs.IEfsFileSystem;
}
export class Webserver extends cdk.Construct {
public constructor(scope: cdk.Construct, id: string, props: WebserverProps) {
super(scope, id);
// https://github.com/aws/containers-roadmap/issues/53 - EFS + Fargate
const taskDefinition = new ecs.TaskDefinition(this, "TaskDefinition", {
compatibility: ecs.Compatibility.EC2,
});
// Patch in the EFS support.
const rawTask = taskDefinition.node.findChild("Resource") as ecs.CfnTaskDefinition;
rawTask.volumes = [
{
name: "invision",
efsVolumeConfiguration: {
fileSystemId: props.filesystem.fileSystemId,
rootDirectory: "/",
},
} as ecs.CfnTaskDefinition.VolumeProperty,
];
}
}
None, the resource just refuses to include the efsVolumeConfiguration options.
This is :bug: Bug Report
I am afraid efsVolumeConfiguration is not supported in cloudformation yet.
Pending on this issue https://github.com/aws/containers-roadmap/issues/825
Ah, I guess that would explain why it's not in CDK yet either then. I followed a few links from that one and saw it's recently been released to EC2 ECS and Fargate as general release now though so good to see some progress on this. Thanks for the update.
Anyone found a good workaround for this? I'm afraid a custom resource might involve redoing the whole ECS creation using the AWS API.
For now I'm using EC2 ECS, mounting the EFS partitions manually on boot via user data and using bind mounts in the task description.
If you're using EC2 ECS you can just get docker to mount your File System:
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Volumes:
- Name: jenkins_home
DockerVolumeConfiguration:
Driver: local
DriverOpts:
type: nfs
device: !Sub "${ClusterFileSystem}.efs.${AWS::Region}.amazonaws.com:/"
o: !Sub "addr=${ClusterFileSystem}.efs.${AWS::Region}.amazonaws.com,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2"
Labels:
foo: bar
Scope: shared
# Autoprovision: true
Family: jenkins-frontend
ContainerDefinitions:
- Name: jenkins-frontend
Essential: true
Image: jenkins/jenkins:lts
MemoryReservation: 512
Environment:
- Name: JENKINS_OPTS
Value: --prefix=/jenkins
PortMappings:
- ContainerPort: 8080
MountPoints:
- containerPath: /var/jenkins_home/
sourceVolume: jenkins_home
I managed to devise a fairly consistent workaround to handle EFS volume configurations (as well as EFS access points and filesystem policies) while I wait for CFN+CDK support.
Full repo with the examples is https://github.com/aws-samples/amazon-efs-integrations/ if you want to give it a try separately before trying this workaround on your real code.
Basically, I let the ApplicationLoadBalanced(Ec2|Fargate)Service construct from ECS Patterns create the initial task definition, then I use an AwsCustomResource construct to execute a registerTaskDefinition call against that same task definition and pass it the actual task definition configuration I need in order to configure my EFS volume mounts. This ends up creating a new revision, which I then use a CDK escape hatch to apply to the ECS service. This does result in a longer first-time deployment (since CDK will wait for the ECS service to stabilize before goes and changes everything), but subsequent deployments are fine.
The reason this all works is because, while there's no CFN support yet for EFS volume configurations in ECS, there is support for it in the SDK, which does not reject a task definition using efsVolumeConfiguration like the CDK TaskDefinition derivatives would.
I like this approach over the other workarounds I've seen because (a) it lets me do everything in CDK with no additional commands or manual console instructions required, (b) it lets me take advantage of all the conveniences that the ApplicationLoadBalanced(Ec2|Fargate)Service constructs provide, and (c) once CDK support for these capabilities is enabled, it should make refactoring very easy since all of the task definition configuration is already there alongside where I initially create the service.
Hope this helps somebody!
Now you can add mount point much easier:
task = FargateTaskDefinition(self, "Task",...)
container = task.add_container("container", ...)
container_volume_mount_point = ecs.MountPoint(
read_only=False,
container_path="/bitnami/wordpress",
source_volume=efs_volume.name
)
container.add_mount_points(container_volume_mount_point)
Most helpful comment
I managed to devise a fairly consistent workaround to handle EFS volume configurations (as well as EFS access points and filesystem policies) while I wait for CFN+CDK support.
Full repo with the examples is https://github.com/aws-samples/amazon-efs-integrations/ if you want to give it a try separately before trying this workaround on your real code.
Basically, I let the
ApplicationLoadBalanced(Ec2|Fargate)Serviceconstruct from ECS Patterns create the initial task definition, then I use anAwsCustomResourceconstruct to execute aregisterTaskDefinitioncall against that same task definition and pass it the actual task definition configuration I need in order to configure my EFS volume mounts. This ends up creating a new revision, which I then use a CDK escape hatch to apply to the ECS service. This does result in a longer first-time deployment (since CDK will wait for the ECS service to stabilize before goes and changes everything), but subsequent deployments are fine.The reason this all works is because, while there's no CFN support yet for EFS volume configurations in ECS, there is support for it in the SDK, which does not reject a task definition using
efsVolumeConfigurationlike the CDKTaskDefinitionderivatives would.I like this approach over the other workarounds I've seen because (a) it lets me do everything in CDK with no additional commands or manual console instructions required, (b) it lets me take advantage of all the conveniences that the
ApplicationLoadBalanced(Ec2|Fargate)Serviceconstructs provide, and (c) once CDK support for these capabilities is enabled, it should make refactoring very easy since all of the task definition configuration is already there alongside where I initially create the service.Hope this helps somebody!