When using the higher level LoadBalancedFargateService construct to create a load balanced Fargate service, it's not possible to configure the container at runtime with environment variables.
cc @SoManyHs
@PaulMaddox Are you looking to use ECS Secrets, or was there particular workflow you use/expect for setting container environment variables?
@PaulMaddox There is also Private Registry Auth, which is used specifically for creds to pull/push images. Let me know what your use case is!
Hi @SoManyHs - to start with, i was starting with just trying to set basic environment variables, but suspect customers would also want to use ECS Secrets longer term.
I would expect the API to mirror the way environment variables and secrets are provided in task definitions. For example:
// Create a nginx service
const nginxService = new ecs.LoadBalancedFargateService(this, 'NginxService', {
cluster: cluster,
image: ecs.ContainerImage.fromDockerHub('nginx:latest'),
environment: [ { name: "TEST_ENV", value: "test value" } ],
secrets: [ { name: "TEST_SECRET", valueFrom: "arn:aws:ssm:region:aws_account_id:parameter/parameter_name" } ],
})
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html
As a side note @rix0rrr / @eladb, i'm struggling to overcome this with parameter overrides in the meantime. It would be great to have a workaround in this issue as a couple of people have reached out to me asking for one (inc. @mikeapted).
Things i've tried and their result (but have failed due to my lack of understanding of property overrides probably...):
// Create a nginx service
const nginxService = new ecs.LoadBalancedFargateService(this, 'NginxService', {
cluster: cluster,
image: ecs.ContainerImage.fromDockerHub('nginx:latest'),
})
const task = nginxService.node.findChild('TaskDef') as ecs.CfnTaskDefinition
const container = task.node.findChild('web') as ecs.CfnTaskDefinition.ContainerDefinitionProperty;
container.environment = [{ name: 'TEST_ENV', value: 'TEST_VALUE' }]
task.propertyOverrides.containerDefinitions = [container]
Results in TypeError: Cannot set property 'containerDefinitions' of undefined
const task = nginxService.node.findChild('TaskDef') as ecs.CfnTaskDefinition
const containers = task.propertyOverrides.containerDefinitions as Array<ecs.CfnTaskDefinition.ContainerDefinitionProperty>
for (let container of containers) {
...
}
Also results in TypeError: Cannot read property 'containerDefinitions' of undefined
I feel i'm missing something obvious, but not sure what.
@PaulMaddox the reason the code above doesn't work is because the TaskDef child is not a CfnTaskDefinition (L1), it's a FargateTaskDefinition (L2). Furthermore, since ContainerDefinition is not an L1 resource (but rather part of another L1 resource), you can't really assign it to containerDefinitions.
Anyway, here's a way to achieve this:
const taskDef = nginxService.node
.findAll()
.find(x => x instanceof ecs.CfnTaskDefinition) as ecs.CfnTaskDefinition;
taskDef.addPropertyOverride('ContainerDefinitions.0.Environment', [
{ name: 'TEST_ENV', value: 'TEST_VALUE' }
]);
Not very elegant, and relies on the fact that the container definition you wish to override is the first in the array, but should work.
Most helpful comment
@PaulMaddox the reason the code above doesn't work is because the
TaskDefchild is not aCfnTaskDefinition(L1), it's aFargateTaskDefinition(L2). Furthermore, sinceContainerDefinitionis not an L1 resource (but rather part of another L1 resource), you can't really assign it tocontainerDefinitions.Anyway, here's a way to achieve this:
Not very elegant, and relies on the fact that the container definition you wish to override is the first in the array, but should work.