public useTaskDefinition()

in lib/consul-mesh-extension.ts [269:444]


    public useTaskDefinition(taskDefinition: ecs.TaskDefinition) {

        const serviceContainer = this.parentService.serviceDescription.get('service-container') as Container;

        if(serviceContainer == undefined){
            throw new Error(`Cannot find service-container`);
        }

        new Policy(this.scope, `task-role-${this.parentService.id}`, {
            roles: [taskDefinition.taskRole],
            statements: [
                new PolicyStatement({
                    actions: ['ec2:DescribeInstances'],
                    resources: ['*'],
                    conditions: {
                        StringEquals: {
                            "aws:RequestedRegion": cdk.Stack.of(this.parentService).region
                        }
                    }
                }),
            ],
        });

        //Add volumes to the task definition
        taskDefinition.addVolume({
            name: "consul-data"
        });
        taskDefinition.addVolume({
            name: "consul-config"
        });
        taskDefinition.addVolume({
            name: "consul_binary"
        });

        //Consul agent config starts here
        const consulClient = taskDefinition.addContainer('consul-client', {
            image: ecs.ContainerImage.fromRegistry(this.consulClientImage),
            essential: false,
            memoryLimitMiB: 256,
            portMappings: [
                {
                    containerPort: 8301,
                    protocol: ecs.Protocol.TCP
                },
                {
                    containerPort: 8301,
                    protocol: ecs.Protocol.UDP
                },
                {
                    containerPort: 8500,
                    protocol: ecs.Protocol.TCP
                }
            ],
            logging: new ecs.AwsLogDriver({ streamPrefix: 'consul-client' }),
            entryPoint: ["/bin/sh", "-ec"],
            command: this.buildConsulClientCommand
        });

        consulClient.addMountPoints(
            {
                containerPath: "/consul/data",
                sourceVolume: "consul-data",
                readOnly: false
            },
            {
                containerPath: "/consul/config",
                sourceVolume: "consul-config",
                readOnly: false
            },
            {
                containerPath: "/bin/consul-inject",
                sourceVolume: "consul_binary",
                readOnly: false
            }
        );

        if(this.healthCheck && this.consulChecks){
            throw new Error('Cannot define both Consul Native Checks and ECS Health Checks');
        }

        this.healthSyncContainerName = this.consulChecks ? "" : this.healthCheck ? serviceContainer.container?.containerName : "";

        //Mesh init config starts here
        this.meshInit = taskDefinition.addContainer('consul-ecs-mesh-init', {
            image: ecs.ContainerImage.fromRegistry(this.consulEcsImage),
            memoryLimitMiB: 256,
            command: ["mesh-init",
                "-envoy-bootstrap-dir=/consul/data",
                "-port=" + serviceContainer.trafficPort,
                "-upstreams=" + this.buildUpstreamString,
                "-health-sync-containers=" + this.healthSyncContainerName,
                "-checks=" + (JSON.stringify(this.consulChecks) ?? ""),
                "-service-name=" + this.serviceDiscoveryName],
            logging: new ecs.AwsLogDriver({ streamPrefix: 'consul-ecs-mesh-init' }),
            essential: false
        });

        this.meshInit.addMountPoints({
            containerPath: "/consul/data",
            sourceVolume: "consul-data",
            readOnly: false
        },
            {
                containerPath: "/bin/consul-inject",
                sourceVolume: "consul_binary",
                readOnly: true
            });


        //Proxy config starts here
        this.container = taskDefinition.addContainer('sidecar-proxy', {
            image: ecs.ContainerImage.fromRegistry(this.envoyProxyImage),
            memoryLimitMiB: 256,
            entryPoint: ["/consul/data/consul-ecs", "envoy-entrypoint"],
            command: ["/bin/sh", "-c", "envoy --config-path /consul/data/envoy-bootstrap.json"],
            logging: new ecs.AwsLogDriver({ streamPrefix: 'envoy' }),
            portMappings: [{
                containerPort: 20000,
                protocol: ecs.Protocol.TCP
            }],
            healthCheck: {
                command: ["nc", "-z", "127.0.0.1", "20000"],
                interval: cdk.Duration.seconds(30),
                timeout: cdk.Duration.seconds(5),
                retries: 3,
            },
            essential: false
        });

        this.container.addUlimits(
            {
                name: ecs.UlimitName.NOFILE,
                // Note: 2^20 (1048576) is the maximum.
                // Going higher would need sysctl settings: https://github.com/aws/containers-roadmap/issues/460.
                // AWS API will accept invalid values, and you will see a CannotStartContainerError at runtime.
                softLimit: 1048576,
                hardLimit: 1048576
            }
        );

        this.container.addContainerDependencies(
            {
                container: this.meshInit,
                condition: ecs.ContainerDependencyCondition.SUCCESS
            }
        );

        this.container.addMountPoints(
            {
                containerPath: "/consul/data",
                sourceVolume: "consul-data",
                readOnly: false
            }
        );

        if (this.healthSyncContainerName) {
            const consulECSHealthSync = taskDefinition.addContainer('consul-ecs-health-sync', {
                image: ecs.ContainerImage.fromRegistry(this.consulEcsImage),
                memoryLimitMiB: 256,
                command: ["health-sync",
                    "-health-sync-containers=" + this.healthSyncContainerName,
                    "-service-name=" + this.serviceDiscoveryName],
                logging: new ecs.AwsLogDriver({ streamPrefix: 'consul-ecs-health-sync' }),
                essential: false,
                secrets: this.aclSecretArn ? { "CONSUL_HTTP_TOKEN": ecs.Secret.fromSecretsManager(secretsmanager.Secret.fromSecretAttributes(this.scope, 'ImportedACLSecret' + this.parentService.id, {
                    secretCompleteArn: this.aclSecretArn,
                  })) } : undefined
            });

            consulECSHealthSync.addContainerDependencies({
                container: this.meshInit,
                condition: ecs.ContainerDependencyCondition.SUCCESS
            });
            
        }
    }