diff --git a/examples/container-image/README.md b/examples/container-image/README.md
index 22e0d071..af9c7e86 100644
--- a/examples/container-image/README.md
+++ b/examples/container-image/README.md
@@ -55,6 +55,8 @@ No inputs.
| Name | Description |
|------|-------------|
+| [docker\_image\_files\_to\_hash](#output\_docker\_image\_files\_to\_hash) | List of files used to hash the docker image tag |
+| [docker\_image\_id](#output\_docker\_image\_id) | The ID of the Docker image |
| [docker\_image\_uri](#output\_docker\_image\_uri) | The ECR Docker image URI used to deploy Lambda Function |
| [lambda\_cloudwatch\_log\_group\_arn](#output\_lambda\_cloudwatch\_log\_group\_arn) | The ARN of the Cloudwatch Log Group |
| [lambda\_function\_arn](#output\_lambda\_function\_arn) | The ARN of the Lambda Function |
diff --git a/examples/container-image/main.tf b/examples/container-image/main.tf
index d19be410..46c1bf77 100644
--- a/examples/container-image/main.tf
+++ b/examples/container-image/main.tf
@@ -4,6 +4,17 @@ data "aws_caller_identity" "this" {}
data "aws_ecr_authorization_token" "token" {}
+locals {
+ source_path = "context"
+ path_include = ["**"]
+ path_exclude = ["**/__pycache__/**"]
+ files_include = setunion([for f in local.path_include : fileset(local.source_path, f)]...)
+ files_exclude = setunion([for f in local.path_exclude : fileset(local.source_path, f)]...)
+ files = sort(setsubtract(local.files_include, local.files_exclude))
+
+ dir_sha = sha1(join("", [for f in local.files : filesha1("${local.source_path}/${f}")]))
+}
+
provider "aws" {
region = "eu-west-1"
@@ -32,9 +43,10 @@ module "lambda_function_from_container_image" {
##################
# Container Image
##################
- image_uri = module.docker_image.image_uri
package_type = "Image"
- architectures = ["x86_64"]
+ architectures = ["arm64"] # ["x86_64"]
+
+ image_uri = module.docker_image.image_uri
}
module "docker_image" {
@@ -59,12 +71,20 @@ module "docker_image" {
]
})
- image_tag = "2.0"
- source_path = "context"
+ use_image_tag = false # If false, sha of the image will be used
+
+ # use_image_tag = true
+ # image_tag = "2.0"
+
+ source_path = local.source_path
+ platform = "linux/amd64"
build_args = {
FOO = "bar"
}
- platform = "linux/amd64"
+
+ triggers = {
+ dir_sha = local.dir_sha
+ }
}
resource "random_pet" "this" {
diff --git a/examples/container-image/outputs.tf b/examples/container-image/outputs.tf
index a71816f8..34755681 100644
--- a/examples/container-image/outputs.tf
+++ b/examples/container-image/outputs.tf
@@ -97,3 +97,13 @@ output "docker_image_uri" {
description = "The ECR Docker image URI used to deploy Lambda Function"
value = module.docker_image.image_uri
}
+
+output "docker_image_id" {
+ description = "The ID of the Docker image"
+ value = module.docker_image.image_id
+}
+
+output "docker_image_files_to_hash" {
+ description = "List of files used to hash the docker image tag"
+ value = local.files
+}
diff --git a/modules/docker-build/README.md b/modules/docker-build/README.md
index 0cf1cc81..44464404 100644
--- a/modules/docker-build/README.md
+++ b/modules/docker-build/README.md
@@ -34,7 +34,10 @@ module "docker_image" {
create_ecr_repo = true
ecr_repo = "my-cool-ecr-repo"
- image_tag = "1.0"
+
+ use_image_tag = true
+ image_tag = "1.0"
+
source_path = "context"
build_args = {
FOO = "bar"
@@ -94,17 +97,22 @@ No modules.
| [ecr\_repo](#input\_ecr\_repo) | Name of ECR repository to use or to create | `string` | `null` | no |
| [ecr\_repo\_lifecycle\_policy](#input\_ecr\_repo\_lifecycle\_policy) | A JSON formatted ECR lifecycle policy to automate the cleaning up of unused images. | `string` | `null` | no |
| [ecr\_repo\_tags](#input\_ecr\_repo\_tags) | A map of tags to assign to ECR repository | `map(string)` | `{}` | no |
+| [force\_remove](#input\_force\_remove) | Whether to remove image forcibly when the resource is destroyed. | `bool` | `false` | no |
| [image\_tag](#input\_image\_tag) | Image tag to use. If not specified current timestamp in format 'YYYYMMDDhhmmss' will be used. This can lead to unnecessary rebuilds. | `string` | `null` | no |
| [image\_tag\_mutability](#input\_image\_tag\_mutability) | The tag mutability setting for the repository. Must be one of: `MUTABLE` or `IMMUTABLE` | `string` | `"MUTABLE"` | no |
+| [keep\_locally](#input\_keep\_locally) | Whether to delete the Docker image locally on destroy operation. | `bool` | `false` | no |
| [keep\_remotely](#input\_keep\_remotely) | Whether to keep Docker image in the remote registry on destroy operation. | `bool` | `false` | no |
| [platform](#input\_platform) | The target architecture platform to build the image for. | `string` | `null` | no |
| [scan\_on\_push](#input\_scan\_on\_push) | Indicates whether images are scanned after being pushed to the repository | `bool` | `false` | no |
| [source\_path](#input\_source\_path) | Path to folder containing application code | `string` | `null` | no |
+| [triggers](#input\_triggers) | A map of arbitrary strings that, when changed, will force the docker\_image resource to be replaced. This can be used to rebuild an image when contents of source code folders change | `map(string)` | `{}` | no |
+| [use\_image\_tag](#input\_use\_image\_tag) | Controls whether to use image tag in ECR repository URI or not. Disable this to deploy latest image using ID (sha256:...) | `bool` | `true` | no |
## Outputs
| Name | Description |
|------|-------------|
+| [image\_id](#output\_image\_id) | The ID of the Docker image |
| [image\_uri](#output\_image\_uri) | The ECR image URI for deploying lambda |
diff --git a/modules/docker-build/main.tf b/modules/docker-build/main.tf
index dc9ad310..b75ae05c 100644
--- a/modules/docker-build/main.tf
+++ b/modules/docker-build/main.tf
@@ -5,8 +5,8 @@ data "aws_caller_identity" "this" {}
locals {
ecr_address = coalesce(var.ecr_address, format("%v.dkr.ecr.%v.amazonaws.com", data.aws_caller_identity.this.account_id, data.aws_region.current.name))
ecr_repo = var.create_ecr_repo ? aws_ecr_repository.this[0].id : var.ecr_repo
- image_tag = coalesce(var.image_tag, formatdate("YYYYMMDDhhmmss", timestamp()))
- ecr_image_name = format("%v/%v:%v", local.ecr_address, local.ecr_repo, local.image_tag)
+ image_tag = var.use_image_tag ? coalesce(var.image_tag, formatdate("YYYYMMDDhhmmss", timestamp())) : null
+ ecr_image_name = var.use_image_tag ? format("%v/%v:%v", local.ecr_address, local.ecr_repo, local.image_tag) : format("%v/%v", local.ecr_address, local.ecr_repo)
}
resource "docker_image" "this" {
@@ -18,12 +18,20 @@ resource "docker_image" "this" {
build_args = var.build_args
platform = var.platform
}
+
+ force_remove = var.force_remove
+ keep_locally = var.keep_locally
+ triggers = var.triggers
}
resource "docker_registry_image" "this" {
name = docker_image.this.name
keep_remotely = var.keep_remotely
+
+ triggers = {
+ image_id = docker_image.this.image_id
+ }
}
resource "aws_ecr_repository" "this" {
diff --git a/modules/docker-build/outputs.tf b/modules/docker-build/outputs.tf
index 05c9063a..5b268b54 100644
--- a/modules/docker-build/outputs.tf
+++ b/modules/docker-build/outputs.tf
@@ -1,4 +1,9 @@
output "image_uri" {
description = "The ECR image URI for deploying lambda"
- value = docker_registry_image.this.name
+ value = var.use_image_tag ? docker_registry_image.this.name : format("%v@%v", docker_registry_image.this.name, docker_registry_image.this.id)
+}
+
+output "image_id" {
+ description = "The ID of the Docker image"
+ value = docker_registry_image.this.id
}
diff --git a/modules/docker-build/variables.tf b/modules/docker-build/variables.tf
index a59548a8..509f35f3 100644
--- a/modules/docker-build/variables.tf
+++ b/modules/docker-build/variables.tf
@@ -10,6 +10,12 @@ variable "create_sam_metadata" {
default = false
}
+variable "use_image_tag" {
+ description = "Controls whether to use image tag in ECR repository URI or not. Disable this to deploy latest image using ID (sha256:...)"
+ type = bool
+ default = true
+}
+
variable "ecr_address" {
description = "Address of ECR repository for cross-account container image pulling (optional). Option `create_ecr_repo` must be `false`"
type = string
@@ -88,3 +94,21 @@ variable "platform" {
type = string
default = null
}
+
+variable "force_remove" {
+ description = "Whether to remove image forcibly when the resource is destroyed."
+ type = bool
+ default = false
+}
+
+variable "keep_locally" {
+ description = "Whether to delete the Docker image locally on destroy operation."
+ type = bool
+ default = false
+}
+
+variable "triggers" {
+ description = "A map of arbitrary strings that, when changed, will force the docker_image resource to be replaced. This can be used to rebuild an image when contents of source code folders change"
+ type = map(string)
+ default = {}
+}
diff --git a/wrappers/docker-build/main.tf b/wrappers/docker-build/main.tf
index 81afa562..0375d4eb 100644
--- a/wrappers/docker-build/main.tf
+++ b/wrappers/docker-build/main.tf
@@ -12,10 +12,14 @@ module "wrapper" {
ecr_repo = try(each.value.ecr_repo, var.defaults.ecr_repo, null)
ecr_repo_lifecycle_policy = try(each.value.ecr_repo_lifecycle_policy, var.defaults.ecr_repo_lifecycle_policy, null)
ecr_repo_tags = try(each.value.ecr_repo_tags, var.defaults.ecr_repo_tags, {})
+ force_remove = try(each.value.force_remove, var.defaults.force_remove, false)
image_tag = try(each.value.image_tag, var.defaults.image_tag, null)
image_tag_mutability = try(each.value.image_tag_mutability, var.defaults.image_tag_mutability, "MUTABLE")
+ keep_locally = try(each.value.keep_locally, var.defaults.keep_locally, false)
keep_remotely = try(each.value.keep_remotely, var.defaults.keep_remotely, false)
platform = try(each.value.platform, var.defaults.platform, null)
scan_on_push = try(each.value.scan_on_push, var.defaults.scan_on_push, false)
source_path = try(each.value.source_path, var.defaults.source_path, null)
+ triggers = try(each.value.triggers, var.defaults.triggers, {})
+ use_image_tag = try(each.value.use_image_tag, var.defaults.use_image_tag, true)
}