Aws-cdk: LoadBalancedFargateService does not expose environment variables

Created on 5 Dec 2018  路  6Comments  路  Source: aws/aws-cdk

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.

@aws-cdaws-ecs feature-request

Most helpful comment

@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.

All 6 comments

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.

Was this page helpful?
0 / 5 - 0 ratings