Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

terraform to conditionally create ECR repository if not exists

I am using terraform to deploy my resources. I have a terraform code to create a ECR repository here:

resource "aws_ecr_repository" "main" {
  name                 = var.repo_name
  image_tag_mutability = var.image_tag_mutability
  image_scanning_configuration {
    scan_on_push = true
  }
}

The above code works fine. However, if the ECR repository already exists in AWS, it throws the error.

For the solution, I wanted to use the terraform data statement to query if the repository exists:

data "aws_ecr_repository" "repository" {
name = var.repo_name
}

resource "aws_ecr_repository" "main" {
  name                 = data.aws_ecr_repository.repository.name
  image_tag_mutability = var.image_tag_mutability
  image_scanning_configuration {
    scan_on_push = true
  }
}

It's throwing error like this:

Error: ECR Repository (digital-service) not found

Any suggestions are appreciated.

like image 247
Deependra Dangal Avatar asked Oct 14 '25 05:10

Deependra Dangal


1 Answers

For future references, you can check and create resources conditionally using the external resource data, in my case i need to createone repo for development images in one repository and i was using docker provider to build and push the image to that ecr

main.tf

terraform {
  required_version = ">= 1.3.0"

  # Set the required provider
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "2.15.0"
    }
  }
}

# Creating a repository in ECR
resource "aws_ecr_repository" "repository" {
  count        = data.external.check_repo.result.success == "true" ? 0 : 1
  name         = var.repository_name
  force_delete = var.force_delete_repo
}

# Build and Push an image to ECR
resource "docker_registry_image" "image" {
  name                 = length(aws_ecr_repository.repository) > 0 ? "${aws_ecr_repository.repository[0].repository_url}:v${var.image_tag}" : "${data.external.check_repo.result.repository_url}:v${var.image_tag}"
  insecure_skip_verify = true

  build {
    context    = var.docker_context_url
    dockerfile = var.dockerfile_name
    build_args = var.docker_build_args

    auth_config {
      host_name = var.registry_host_name
      user_name = var.registry_user
      password  = var.registry_token
    }
  }
}

data.tf

data "external" "check_repo" {
  program = ["/usr/bin/bash", "${path.module}/script.sh", var.repository_name, var.region]

}

script.sh

#!/bin/bash


result=$(aws ecr describe-repositories --repository-names $1 --region $2 2>&1)
if [ $? -eq 0  ]; then
repository_url=$(echo $result | jq -r '.repositories[0].repositoryUri')
echo -n "{\"success\":\"true\", \"repository_url\":\"$repository_url\", \"name\":\"$1\"}"
else
error_message=$(echo $result | jq -R -s -c '.')
echo -n "{\"success\":\"false\", \"error_message\": $error_message , \"name\":\"$1\"}"
fi

so what we are doing here is checking if the aws_ecr_repository resource have count of 1 which means that the repository does not exist and we are creating it here so we use that resource output, if the repo does exist so the count will be 0 and the we will use the url from the reponse that we got in data.tf external datasource

like image 50
Farhani Walid Avatar answered Oct 17 '25 02:10

Farhani Walid