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
});
}
}