Reputation: 101
I am developing series of lambdas that are using docker images. The first step is to create them and registering in AWS ECR (not sure if everything I am doing is ok, so any advice is welcomed :-) ):
terraform {
...
required_providers {
docker = {
source = "kreuzwerker/docker"
version = ">= 2.12"
}
}
}
resource aws_ecr_repository lambda_repo {
name = "lambda"
}
resource docker_registry_image lambda_image {
name = "<account_id>.dkr.ecr.<region>.amazonaws.com/lambda:latest"
build {
context = "./code/lambda"
}
depends_on = [
aws_ecr_repository.lambda_repo
]
keep_remotely = true
}
resource aws_lambda_function lambda {
...
image_uri = "<account_id>.dkr.ecr.<region>.amazonaws.com/lambda:latest"
source_code_hash = docker_registry_image.lambda_image.sha256_digest
...
}
So with this code:
The problem I have is how to "force" docker_registry_image > lambda_image to rebuild the image and update the "lambda:latest" when the Dockerfile or app.py (the main code that is added in the file) has changed. Also I am not sure if this is the way to build the images.
Thanks!!
Upvotes: 6
Views: 1491
Reputation: 51
I was stuck with the exact same problem, and was disappointed to find your question hadn't been answered. I struggled a good bit, but I just clicked late tonight and got mine working.
The problem is incorrect thinking based on bad Docker habits (guilty of the same here!):
latest
is a bad habit: it's based on tag mutability, which isn't how docker was designed, and pulling latest
is non-deterministic, anyway - you never know what you're going to get. Usually, latest
will pull the most recent version on a docker pull
.Here is the better way to think about this:
docker_registry_image
and the kreusewerker/docker
provider are based on tag immutability.docker_registry_image
gets "replaced" in Terraform state (you'll see that in the Terraform plan when you try it), but the
effect in your ECR repository is to add a new image with a the next
sequential tag number, not to replace the actual image as one
usually thinks with Terraform.image_tag
:variable "image_tag" {
default = 1
}
docker_registry_image
so that it uses the image_tag
variable (also touching up the docker_registry_image
name so you're not doing to much error-prone string building):resource docker_registry_image lambda_image {
name = "${aws_ecr_repository.lambda_repo.repository_url}:${var.image_tag}"
build {
context = "./code/lambda"
}
...
}
aws_lambda_function
. Change the image_uri
to the name of the docker_registry_image
so that those two are never out of sync:resource aws_lambda_function lambda {
image_uri = docker_registry_image.lambda_image.name
source_code_hash = docker_registry_image.lambda_image.sha256_digest
}
image_tag
variable by 1. Then try a terraform plan
and you'll see that the docker_registry_image
and aws_lambda_function
will be replaced. A good exercise, would be to look at your ECR repo and Lambda function in the console while you do this. You'll see the images appearing in your ECR repo, and the Lambda function's image uri being updated with the new image_tag
.Hope this helps. I sure feel a whole lot better tonight!
Upvotes: 5