5

I have an ECR repository named workflow and in this repository, there is 5 image pushed using GitHub action.

Now I have a terraform workflow that will just use the image from ECR and using this ECR image builds the ECS container definition.

so now I want to fetch the latest image with the tag whatever it would be...

I tried the below thing

data "aws_ecr_repository" "example" {
  name = "workflow"
}

and then

 "image": "${data.aws_ecr_repository.example.repository_url}"

but here I only get the Url for the repo without a tag

so how can I pass here the latest or newest image with the tag?

Mark B
  • 183,023
  • 24
  • 297
  • 295
Rohan jangid
  • 125
  • 3
  • 13
  • 1
    I don't think it's possible (at this time) with Terraform unfortunately. – Mark B Oct 06 '22 at 17:26
  • @MarkB ok or maybe somehow we can get all tags in terraform using a data source and then loop over this. – Rohan jangid Oct 07 '22 at 01:43
  • data "aws_ecr_repository" "example" { name = "workflow" } output "ecr_repo" { value = data.aws_ecr_repository.example.tags } i tried below output block but it prints out the "ecr_repo = tomap({})" this thing how can i get data inside map like tags – Rohan jangid Oct 07 '22 at 02:04
  • You can't. Look at the documentation if you don't believe me. The standard way of handling this is to have your CI/CD process that builds and pushes the image to ECR pass the tag it created as an input variable into your terraform commands. – Mark B Oct 07 '22 at 13:32
  • okay got it for doing this thing inside the terraform itself i used external data source and from there i write a bash script and there i fetched the latest image tag and pass and this works – Rohan jangid Oct 10 '22 at 06:54

3 Answers3

4

It looks like this feature is now available

data "aws_ecr_image" "service_image" {
  repository_name = "my/service"
  most_recent       = true
}
Rob
  • 145
  • 1
  • 13
3

I was looking for the same, look if this documentation suites you https://registry.terraform.io/providers/hashicorp/aws/2.34.0/docs/data-sources/ecr_image

it includes a way to obtain the image:

data "aws_ecr_image" "service_image" {
    repository_name = "my/service"
    image_tag       = "latest"
}

the problem of that is that "image_uri" isnt in the resource. There is an open issue in Github about it: https://github.com/hashicorp/terraform-provider-aws/pull/24526

Meanwhile you can use this format for the url:

"${var.aws_account_id}.dkr.ecr.${var.region}.amazonaws.com/${var.project_name}:${var.latest-Tag}"
1

As terraform is not capable for this thing and you want to use still terraform in you are workplace then you can use terraform as an external data source

resource "aws_ecs_task_definition" "snipe-main" {
container_definitions    = <<TASK_DEFINITION
[
  {
"image":"${data.aws_ecr_repository.example.repository_url}:${data.external.current_image.result["image_tag"]}"
   }
]
TASK_DEFINITION 
}

data "external" "current_image" {
  program = ["bash", "./ecs-task.sh"]
}
output "get_new_tag" {
  value = data.external.current_image.result["image_tag"]
}
cat ECS-task.sh
#!/bin/bash
set -e
imageTag=$(aws ecr describe-images --repository-name <<here your repo name>> --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]')
imageTag=`sed -e 's/^"//' -e 's/"$//' <<<"$imageTag"`
jq -n --arg imageTag "$imageTag" '{"image_tag":$imageTag}'

exit 0
Rohan jangid
  • 125
  • 3
  • 13
  • Very smart solution @rohan-jangid. I have been trying to get the latest image dynamically for a while and this just does that. For those, that are getting an error "jq: command not found", you could just use an echo '{"image_tag":"'$imageTag'"}' since all we are doing is creating a json string. – Sonny N Dec 15 '22 at 01:21
  • @SonnyN thanks if it's helpful for you please mark it as accepted for other, users don't struggle to find a better answer – Rohan jangid Dec 15 '22 at 02:43
  • As an addition, the value the data resource returns is only read on creation of the data resource. Follow up `plan/apply` will return the same value, not a more recent value if available. – David J Eddy Jan 04 '23 at 16:34