0

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?

3
  • Have you checked the ECR repository after receiving this error to verify that the image actually exists in the repository? Commented Oct 31, 2022 at 12:20
  • @MarkB the image doesn't exist in the repo- I thought the terraform would create the repo, build the image and then stick it in there? That's what the docker commands are for right... unless I've written it wrong Commented Oct 31, 2022 at 12:39
  • If the image doesn't exist in the repo, then there is an error happening in the null provisioner. You need to look at the output from the script in that provisioner and see what is happening. Commented Oct 31, 2022 at 12:42

1 Answer 1

4

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 .. .

Sign up to request clarification or add additional context in comments.

6 Comments

Per the Terraform Heredoc documentation: developer.hashicorp.com/terraform/language/expressions/strings The Heredoc syntax is << followed by "A delimiter word of your own choosing". EOF is just as valid as EOT or anything else. Also, adding the - makes Terraform preserve the indentation, which is actually not what you want here. <<EOF is perfectly valid, and I would say actually more valid in this case than <<-EOT.
Are you saying it works fine when you change <<EOF to <<-EOT?
@MarkB Here you can see the full output running the code above on Windows with Powershell interpreter: pastebin.com/C509GTFG
What I'm saying is setting the correct interpreter and changing the delimiter to <<-EOT makes the provisioner work as expected.
What happens if you only set the interpreter, and leave the delimiter to <<EOF? What I'm saying is that <<EOF should absolutely work, if that is the only difference.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.