Search code examples
pythonamazon-web-servicesterraformdockerfileinfrastructure-as-code

AWS: Error Describing ECR Images When Deploying Lambda in Terraform


I'm trying to deploy a lambda as a container using Terraform. Here is my project structure:

project
├── README.md
├── lambda_functions
│   ├── Dockerfile
│   └── index.py
├── terraform
    └── lambda.tf

I am running terraform init, terraform plan and terraform apply from the terraform folder.

variable "region" {
  default = "eu-west-2"
}

data "aws_caller_identity" "current" {}

locals {
  prefix              = "mycompany"
  account_id          = data.aws_caller_identity.current.account_id
  ecr_repository_name = "${local.prefix}-demo-lambda-container"
  ecr_image_tag       = "latest"
}

resource "aws_ecr_repository" "repo" {
  name = local.ecr_repository_name
}

resource "null_resource" "ecr_image" {
  triggers = {
    python_file = md5(file("${path.module}/lambda_functions/lambda_function.py"))
    docker_file = md5(file("${path.module}/lambda_functions/Dockerfile"))
  }

  provisioner "local-exec" {
    command = <<EOF
           aws ecr get-login-password --region ${var.region} | docker login --username AWS --password-stdin ${local.account_id}.dkr.ecr.${var.region}.amazonaws.com
           cd ${path.module}/lambda_functions
           docker build -t ${aws_ecr_repository.repo.repository_url}:${local.ecr_image_tag} .
           docker push ${aws_ecr_repository.repo.repository_url}:${local.ecr_image_tag}
       EOF
  }
}

data "aws_ecr_image" "lambda_image" {
  depends_on = [
    null_resource.ecr_image
  ]
  repository_name = local.ecr_repository_name
  image_tag       = local.ecr_image_tag
}

When I use terraform apply I get this error:

Error: Error describing ECR images: ImageNotFoundException: The image with imageId {imageDigest:'null', imageTag:'latest'} does not exist within the repository with name 'capsphere-demo-lambda-container' in the registry with id 'XXXXXX'

I've tried changing the ${path.module} to .. or also using the absolute path to no luck. Any idea what the issue could be?


Solution

  • You may want to specify the interpreter explicitly. In case you are on Windows, cmd will be used by default, which will stop execution after ecr get-login-password.

    Also, you would can specify the workind directory for the script, so you don't need to do a change directory.

    resource "null_resource" "ecr_image" {
      triggers = {
        python_file = md5(file("../lambda_functions/lambda_function.py"))
        docker_file = md5(file("../lambda_functions/Dockerfile"))
      }
    
      provisioner "local-exec" {
        command = <<EOF
               aws ecr get-login-password --region ${var.region} | docker login --username AWS --password-stdin ${local.account_id}.dkr.ecr.${var.region}.amazonaws.com
               docker build -t ${aws_ecr_repository.repo.repository_url}:${local.ecr_image_tag} .
               docker push ${aws_ecr_repository.repo.repository_url}:${local.ecr_image_tag}
           EOF
        # interpreter = ["pwsh", "-Command"] # For Windows 
        interpreter = ["bash", "-c"] # For Linux/MacOS
        working_dir = "../lambda_functions"
      }
    }
    

    Regarding path.module, you don't really need it here, it will point to current directory (.). In case you are running terraform apply from the terraform folder, you will have to go one level up, which can be accomplished with .. .