Traefik & AWS ECS

    Attach labels to your ECS containers and let Traefik do the rest!

    Configuring ECS provider

    Enabling the ECS provider:

    File (YAML)

    File (TOML)

    1. [providers.ecs]

    CLI

    1. --providers.ecs=true

    Traefik needs the following policy to read ECS information:

    1. {
    2. "Version": "2012-10-17",
    3. "Statement": [
    4. {
    5. "Sid": "TraefikECSReadAccess",
    6. "Effect": "Allow",
    7. "Action": [
    8. "ecs:ListClusters",
    9. "ecs:DescribeClusters",
    10. "ecs:ListTasks",
    11. "ecs:DescribeTasks",
    12. "ecs:DescribeContainerInstances",
    13. "ecs:DescribeTaskDefinition",
    14. "ec2:DescribeInstances",
    15. "ssm:DescribeInstanceInformation"
    16. ],
    17. "Resource": [
    18. "*"
    19. ]
    20. }
    21. ]
    22. }

    ECS Anywhere

    Please note that the ssm:DescribeInstanceInformation action is required for ECS anywhere instances discovery.

    Optional, Default=false

    Search for services in cluster list.

    • If set to true service discovery is enabled for all clusters.
    • If set to false service discovery is enabled on configured clusters only.

    File (YAML)

    1. providers:
    2. ecs:
    3. # ...

    File (TOML)

    1. [providers.ecs]
    2. autoDiscoverClusters = true
    3. # ...

    CLI

    1. --providers.ecs.autoDiscoverClusters=true
    2. # ...

    ecsAnywhere

    Optional, Default=false

    Enable ECS Anywhere support.

    • If set to true service discovery is enabled for ECS Anywhere instances.
    • If set to false service discovery is disabled for ECS Anywhere instances.

    File (YAML)

    1. ecs:
    2. ecsAnywhere: true
    3. # ...
    1. [providers.ecs]
    2. ecsAnywhere = true
    3. # ...

    CLI

    1. --providers.ecs.ecsAnywhere=true
    2. # ...

    Optional, Default=[“default”]

    Search for services in cluster list. This option is ignored if autoDiscoverClusters is set to true.

    File (YAML)

    1. providers:
    2. ecs:
    3. clusters:
    4. - default
    5. # ...

    File (TOML)

    CLI

    1. --providers.ecs.clusters=default
    2. # ...

    exposedByDefault

    Optional, Default=true

    Expose ECS services by default in Traefik.

    If set to false, services that do not have a traefik.enable=true label are ignored from the resulting routing configuration.

    File (YAML)

    1. providers:
    2. ecs:
    3. exposedByDefault: false
    4. # ...

    File (TOML)

    1. [providers.ecs]
    2. exposedByDefault = false
    3. # ...

    CLI

    1. --providers.ecs.exposedByDefault=false
    2. # ...

    Optional, Default=””

    The constraints option can be set to an expression that Traefik matches against the container labels (task), to determine whether to create any route for that container. If none of the container labels match the expression, no route for that container is created. If the expression is empty, all detected containers are included.

    The expression syntax is based on the Label("key", "value"), and LabelRegex("key", "value") functions, as well as the usual boolean logic, as shown in examples below.

    Constraints Expression Examples

    1. # Includes only containers having a label with key `a.label.name` and value `foo`
    2. constraints = "Label(`a.label.name`, `foo`)"
    1. # Excludes containers having any label with key `a.label.name` and value `foo`
    2. constraints = "!Label(`a.label.name`, `value`)"
    1. # With logical AND.
    2. constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)"
    1. constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)"
    1. # With logical AND and OR, with precedence set by parentheses.
    2. constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))"
    1. # Includes only containers having a label with key `a.label.name` and a value matching the `a.+` regular expression.
    2. constraints = "LabelRegex(`a.label.name`, `a.+`)"

    For additional information, refer to Restrict the Scope of Service Discovery.

    File (TOML)

    1. constraints = "Label(`a.label.name`,`foo`)"
    2. # ...

    CLI

    1. --providers.ecs.constraints=Label(`a.label.name`,`foo`)
    2. # ...

    defaultRule

    Optional, Default=Host(`{{ normalize .Name }}`)

    The defaultRule option defines what routing rule to apply to a container if no rule is defined by a label.

    It must be a valid Go template, and can use . The container service name can be accessed with the Name identifier, and the template has access to all the labels defined on this container.

    File (YAML)

    1. providers:
    2. ecs:
    3. defaultRule: "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"
    4. # ...

    File (TOML)

    1. [providers.ecs]
    2. defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"
    3. # ...

    CLI

    1. --providers.ecs.defaultRule=Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)
    2. # ...

    Optional, Default=15

    Polling interval (in seconds).

    File (YAML)

    1. providers:
    2. ecs:
    3. refreshSeconds: 15
    4. # ...

    File (TOML)

    1. [providers.ecs]
    2. refreshSeconds = 15
    3. # ...

    CLI

    1. --providers.ecs.refreshSeconds=15
    2. # ...

    Credentials

    Optional

    If region is not provided, it is resolved from the EC2 metadata endpoint for EC2 tasks. In a FARGATE context it is resolved from the AWS_REGION environment variable.

    If accessKeyID and secretAccessKey are not provided, credentials are resolved in the following order:

    • Using the environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN.
    • Using shared credentials, determined by AWS_PROFILE and AWS_SHARED_CREDENTIALS_FILE, defaults to default and ~/.aws/credentials.
    • Using EC2 instance role or ECS task role

    File (YAML)

    1. providers:
    2. ecs:
    3. region: us-east-1
    4. accessKeyID: "abc"
    5. secretAccessKey: "123"
    6. # ...
    1. [providers.ecs]
    2. region = "us-east-1"
    3. secretAccessKey = "123"

    CLI