Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add aws_ecs_container_definition data source #7230

Merged
merged 2 commits into from
Jul 22, 2016
Merged

Add aws_ecs_container_definition data source #7230

merged 2 commits into from
Jul 22, 2016

Conversation

nicolai86
Copy link
Contributor

@nicolai86 nicolai86 commented Jun 19, 2016

this datasource allows terraform to work with externally modified state, e.g.
when you're using an ECS service which is continously updated by your CI via the
AWS CLI.

Right now you'd have to wrap terraform into a shell script which looks up the
current image digest, so running terraform won't change the updated service:

profile="${AWS_DEFAULT_PROFILE:-default}"
region=eu-west-1

service_name="ecs-service"
task_definition=$(aws --profile "$profile" ecs describe-task-definition --region "$region" --task-definition "$service_name")
current_tag=$(echo $task_definition | jq -r '.taskDefinition.containerDefinitions' | jq -r "map(.image | select(contains(\"my/image\"))) | first" | awk '{split($0,a,":"); printf a[2]}')

terraform apply \
  -var="current_tag=$current_tag" 

using the aws_ecs_container_definition data source you can now leverage
terraform, removing the wrapper entirely:

resource "template_file" "mongo" {
  template = <<DEFINITION
[
  {
    "cpu": 128,
    "essential": true,
    "image": "mongo:${tag}",
    "memory": 128,
    "name": "mongodb"
  }
]
DEFINITION

  vars = {
    tag   = "${data.aws_ecs_container_definition.mongo.image_digest}"
  }
}

resource "aws_ecs_cluster" "default" {
  name = "terraformecstest1"
}

resource "aws_ecs_task_definition" "mongo" {
  family = "mongodb"
  container_definitions = "${template_file.mongo.rendered}"
}

resource "aws_ecs_service" "mongo" {
  name = "mongodb"
  cluster = "${aws_ecs_cluster.default.id}"
  task_definition = "${aws_ecs_task_definition.mongo.arn}"
  desired_count = 1
}

data "aws_ecs_container_definition" "mongo" {
  task_definition = "mongodb"
  container_name = "mongodb"
}

This works for task definitions containing multiple container definitions, too, since a aws_container_definition data source only tracks one container inside a task_definition.

this datasource allows terraform to work with externally modified state, e.g.
when you're using an ECS service which is continously updated by your CI via the
AWS CLI.

right now you'd have to wrap terraform into a shell script which looks up the
current image digest, so running terraform won't change the updated service.

using the aws_ecs_container_definition data source you can now leverage
terraform, removing the wrapper entirely.

# aws\_ecs\_container\_definition

The Availability Zones data source allows access to the list of AWS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @nicolai86,

Please can you change this part of the docs :)

P.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You always find my doc copy pasta. love it. thank you @stack72 ❤️

@stack72 stack72 added the waiting-response An issue/pull request is waiting for a response from the community label Jul 21, 2016
@nicolai86
Copy link
Contributor Author

@stack72 done!

@stack72 stack72 self-assigned this Jul 21, 2016
@stack72 stack72 merged commit 97c5283 into hashicorp:master Jul 22, 2016
@stack72
Copy link
Contributor

stack72 commented Jul 22, 2016

Hi @nicolai86

This looks good :) Thanks for the work here!

Paul

@apparentlymart apparentlymart removed the waiting-response An issue/pull request is waiting for a response from the community label Jul 24, 2016
@nareshov
Copy link

nareshov commented Aug 11, 2016

This seems to cause a dependency cycle error in my case:

data "template_file" "flower" {
    template = "${file("${path.module}/flower.json")}"

    vars = {
#        docker-image              = "${var.docker_image}"
        docker-image              = "${data.aws_ecs_container_definition.flower.image}"
        broker-url                = "${var.broker_url}"
        oauth2_proxy_docker_image = "${var.oauth2_proxy_docker_image}"
        oauth2_proxy_env_vars     = "${var.oauth2_proxy_env_vars}"
    }
}

resource "aws_ecs_task_definition" "flower" {
    family                = "${var.project_name}-${var.environment_name}-flower"
    container_definitions = "${data.template_file.flower.rendered}"
}

data "aws_ecs_container_definition" "flower" {
    task_definition = "${aws_ecs_task_definition.flower.id}"
    container_name  = "flower"
}


output "taskdef.arn" {
    value = "${aws_ecs_task_definition.flower.arn}"
}

flower.json:

[
  {
    "name"        : "flower",
    "hostname"    : "flower",
    "image"       : "${docker-image}",
    "cpu"         : 128,
    "memory"      : 256,
    "entryPoint"  : [],
    "essential"   : true,
    "volumesFrom" : [],
    "mountPoints" : [],
    "environment" : [
      {
        "name"  : "FLOWER_LOGGING",
        "value" : "INFO"
      }
    ],
    "command": [
      "--broker",
      "${broker-url}"
    ]
  }
...

The error I get is:

$ terraform plan
Error configuring: 1 error(s) occurred:

* Cycle: data.aws_ecs_container_definition.flower, data.template_file.flower, aws_ecs_task_definition.flower

Am I missing something?

EDIT:
forgot to mention:

$ terraform  -version
Terraform v0.7.0

Noticed the support for this in https://github.com/hashicorp/terraform/blob/master/CHANGELOG.md#070-august-2-2016

@nicolai86 nicolai86 deleted the feature/data-source-ecs branch August 11, 2016 11:46
@nicolai86
Copy link
Contributor Author

@nareshov the task definition id is set to the family attribute, so this should work for you:

resource "aws_ecs_task_definition" "flower" {
    family                = "${var.project_name}-${var.environment_name}-flower"
    container_definitions = "${data.template_file.flower.rendered}"
}

data "aws_ecs_container_definition" "flower" {
    task_definition = "${var.project_name}-${var.environment_name}-flower"
    container_name  = "flower"
}

@nicolai86
Copy link
Contributor Author

the example above is actually missing that part, I'll correct it

@dene14
Copy link

dene14 commented Aug 31, 2016

How's that useful if service definition still refers to aws_ecs_task_definition, and every time you do CI deploy it changes task_definition revision referenced in the service, applying terraform later will switch service back to previous version?

@nicolai86
Copy link
Contributor Author

My use case was to get the current image digest; I think you can easily include current revision here as well, change should be minimal

@dene14
Copy link

dene14 commented Aug 31, 2016

Terraform saves task definition reference in service definition in state file as [family:state], so it's more about aws_ecs_service resource...

@nicolai86
Copy link
Contributor Author

Point taken. Luckily, this data source is only for the containers WITHIN a task definition

@inversion
Copy link

I'm having trouble using the exported environment attribute. @nicolai86 have you tried interpolating it? From the code it does not look like it is exported in the [{name: value}, ...] format that ECS uses in task definitions so we could need to map it from {name: value, ...} to [{name: value}, ...].

@nicolai86
Copy link
Contributor Author

@inversion my use case was reading it easily, which is why I convert it to a map; not sure how you'd lookup values from an array of objects in HCL. Do you have an example for that?

@ghost
Copy link

ghost commented Apr 20, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants