Skip to content

Commit 41d8db7

Browse files
authored
feat: Added support for triggers in docker-build module when hash changes (terraform-aws-modules#510)
1 parent 04e0349 commit 41d8db7

File tree

8 files changed

+90
-9
lines changed

8 files changed

+90
-9
lines changed

examples/container-image/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ No inputs.
5555

5656
| Name | Description |
5757
|------|-------------|
58+
| <a name="output_docker_image_files_to_hash"></a> [docker\_image\_files\_to\_hash](#output\_docker\_image\_files\_to\_hash) | List of files used to hash the docker image tag |
59+
| <a name="output_docker_image_id"></a> [docker\_image\_id](#output\_docker\_image\_id) | The ID of the Docker image |
5860
| <a name="output_docker_image_uri"></a> [docker\_image\_uri](#output\_docker\_image\_uri) | The ECR Docker image URI used to deploy Lambda Function |
5961
| <a name="output_lambda_cloudwatch_log_group_arn"></a> [lambda\_cloudwatch\_log\_group\_arn](#output\_lambda\_cloudwatch\_log\_group\_arn) | The ARN of the Cloudwatch Log Group |
6062
| <a name="output_lambda_function_arn"></a> [lambda\_function\_arn](#output\_lambda\_function\_arn) | The ARN of the Lambda Function |

examples/container-image/main.tf

+25-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ data "aws_caller_identity" "this" {}
44

55
data "aws_ecr_authorization_token" "token" {}
66

7+
locals {
8+
source_path = "context"
9+
path_include = ["**"]
10+
path_exclude = ["**/__pycache__/**"]
11+
files_include = setunion([for f in local.path_include : fileset(local.source_path, f)]...)
12+
files_exclude = setunion([for f in local.path_exclude : fileset(local.source_path, f)]...)
13+
files = sort(setsubtract(local.files_include, local.files_exclude))
14+
15+
dir_sha = sha1(join("", [for f in local.files : filesha1("${local.source_path}/${f}")]))
16+
}
17+
718
provider "aws" {
819
region = "eu-west-1"
920

@@ -32,9 +43,10 @@ module "lambda_function_from_container_image" {
3243
##################
3344
# Container Image
3445
##################
35-
image_uri = module.docker_image.image_uri
3646
package_type = "Image"
37-
architectures = ["x86_64"]
47+
architectures = ["arm64"] # ["x86_64"]
48+
49+
image_uri = module.docker_image.image_uri
3850
}
3951

4052
module "docker_image" {
@@ -59,12 +71,20 @@ module "docker_image" {
5971
]
6072
})
6173

62-
image_tag = "2.0"
63-
source_path = "context"
74+
use_image_tag = false # If false, sha of the image will be used
75+
76+
# use_image_tag = true
77+
# image_tag = "2.0"
78+
79+
source_path = local.source_path
80+
platform = "linux/amd64"
6481
build_args = {
6582
FOO = "bar"
6683
}
67-
platform = "linux/amd64"
84+
85+
triggers = {
86+
dir_sha = local.dir_sha
87+
}
6888
}
6989

7090
resource "random_pet" "this" {

examples/container-image/outputs.tf

+10
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,13 @@ output "docker_image_uri" {
9797
description = "The ECR Docker image URI used to deploy Lambda Function"
9898
value = module.docker_image.image_uri
9999
}
100+
101+
output "docker_image_id" {
102+
description = "The ID of the Docker image"
103+
value = module.docker_image.image_id
104+
}
105+
106+
output "docker_image_files_to_hash" {
107+
description = "List of files used to hash the docker image tag"
108+
value = local.files
109+
}

modules/docker-build/README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ module "docker_image" {
3434
3535
create_ecr_repo = true
3636
ecr_repo = "my-cool-ecr-repo"
37-
image_tag = "1.0"
37+
38+
use_image_tag = true
39+
image_tag = "1.0"
40+
3841
source_path = "context"
3942
build_args = {
4043
FOO = "bar"
@@ -94,17 +97,22 @@ No modules.
9497
| <a name="input_ecr_repo"></a> [ecr\_repo](#input\_ecr\_repo) | Name of ECR repository to use or to create | `string` | `null` | no |
9598
| <a name="input_ecr_repo_lifecycle_policy"></a> [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 |
9699
| <a name="input_ecr_repo_tags"></a> [ecr\_repo\_tags](#input\_ecr\_repo\_tags) | A map of tags to assign to ECR repository | `map(string)` | `{}` | no |
100+
| <a name="input_force_remove"></a> [force\_remove](#input\_force\_remove) | Whether to remove image forcibly when the resource is destroyed. | `bool` | `false` | no |
97101
| <a name="input_image_tag"></a> [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 |
98102
| <a name="input_image_tag_mutability"></a> [image\_tag\_mutability](#input\_image\_tag\_mutability) | The tag mutability setting for the repository. Must be one of: `MUTABLE` or `IMMUTABLE` | `string` | `"MUTABLE"` | no |
103+
| <a name="input_keep_locally"></a> [keep\_locally](#input\_keep\_locally) | Whether to delete the Docker image locally on destroy operation. | `bool` | `false` | no |
99104
| <a name="input_keep_remotely"></a> [keep\_remotely](#input\_keep\_remotely) | Whether to keep Docker image in the remote registry on destroy operation. | `bool` | `false` | no |
100105
| <a name="input_platform"></a> [platform](#input\_platform) | The target architecture platform to build the image for. | `string` | `null` | no |
101106
| <a name="input_scan_on_push"></a> [scan\_on\_push](#input\_scan\_on\_push) | Indicates whether images are scanned after being pushed to the repository | `bool` | `false` | no |
102107
| <a name="input_source_path"></a> [source\_path](#input\_source\_path) | Path to folder containing application code | `string` | `null` | no |
108+
| <a name="input_triggers"></a> [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 |
109+
| <a name="input_use_image_tag"></a> [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 |
103110

104111
## Outputs
105112

106113
| Name | Description |
107114
|------|-------------|
115+
| <a name="output_image_id"></a> [image\_id](#output\_image\_id) | The ID of the Docker image |
108116
| <a name="output_image_uri"></a> [image\_uri](#output\_image\_uri) | The ECR image URI for deploying lambda |
109117
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
110118

modules/docker-build/main.tf

+10-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ data "aws_caller_identity" "this" {}
55
locals {
66
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))
77
ecr_repo = var.create_ecr_repo ? aws_ecr_repository.this[0].id : var.ecr_repo
8-
image_tag = coalesce(var.image_tag, formatdate("YYYYMMDDhhmmss", timestamp()))
9-
ecr_image_name = format("%v/%v:%v", local.ecr_address, local.ecr_repo, local.image_tag)
8+
image_tag = var.use_image_tag ? coalesce(var.image_tag, formatdate("YYYYMMDDhhmmss", timestamp())) : null
9+
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)
1010
}
1111

1212
resource "docker_image" "this" {
@@ -18,12 +18,20 @@ resource "docker_image" "this" {
1818
build_args = var.build_args
1919
platform = var.platform
2020
}
21+
22+
force_remove = var.force_remove
23+
keep_locally = var.keep_locally
24+
triggers = var.triggers
2125
}
2226

2327
resource "docker_registry_image" "this" {
2428
name = docker_image.this.name
2529

2630
keep_remotely = var.keep_remotely
31+
32+
triggers = {
33+
image_id = docker_image.this.image_id
34+
}
2735
}
2836

2937
resource "aws_ecr_repository" "this" {

modules/docker-build/outputs.tf

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
output "image_uri" {
22
description = "The ECR image URI for deploying lambda"
3-
value = docker_registry_image.this.name
3+
value = var.use_image_tag ? docker_registry_image.this.name : format("%v@%v", docker_registry_image.this.name, docker_registry_image.this.id)
4+
}
5+
6+
output "image_id" {
7+
description = "The ID of the Docker image"
8+
value = docker_registry_image.this.id
49
}

modules/docker-build/variables.tf

+24
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ variable "create_sam_metadata" {
1010
default = false
1111
}
1212

13+
variable "use_image_tag" {
14+
description = "Controls whether to use image tag in ECR repository URI or not. Disable this to deploy latest image using ID (sha256:...)"
15+
type = bool
16+
default = true
17+
}
18+
1319
variable "ecr_address" {
1420
description = "Address of ECR repository for cross-account container image pulling (optional). Option `create_ecr_repo` must be `false`"
1521
type = string
@@ -88,3 +94,21 @@ variable "platform" {
8894
type = string
8995
default = null
9096
}
97+
98+
variable "force_remove" {
99+
description = "Whether to remove image forcibly when the resource is destroyed."
100+
type = bool
101+
default = false
102+
}
103+
104+
variable "keep_locally" {
105+
description = "Whether to delete the Docker image locally on destroy operation."
106+
type = bool
107+
default = false
108+
}
109+
110+
variable "triggers" {
111+
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"
112+
type = map(string)
113+
default = {}
114+
}

wrappers/docker-build/main.tf

+4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ module "wrapper" {
1212
ecr_repo = try(each.value.ecr_repo, var.defaults.ecr_repo, null)
1313
ecr_repo_lifecycle_policy = try(each.value.ecr_repo_lifecycle_policy, var.defaults.ecr_repo_lifecycle_policy, null)
1414
ecr_repo_tags = try(each.value.ecr_repo_tags, var.defaults.ecr_repo_tags, {})
15+
force_remove = try(each.value.force_remove, var.defaults.force_remove, false)
1516
image_tag = try(each.value.image_tag, var.defaults.image_tag, null)
1617
image_tag_mutability = try(each.value.image_tag_mutability, var.defaults.image_tag_mutability, "MUTABLE")
18+
keep_locally = try(each.value.keep_locally, var.defaults.keep_locally, false)
1719
keep_remotely = try(each.value.keep_remotely, var.defaults.keep_remotely, false)
1820
platform = try(each.value.platform, var.defaults.platform, null)
1921
scan_on_push = try(each.value.scan_on_push, var.defaults.scan_on_push, false)
2022
source_path = try(each.value.source_path, var.defaults.source_path, null)
23+
triggers = try(each.value.triggers, var.defaults.triggers, {})
24+
use_image_tag = try(each.value.use_image_tag, var.defaults.use_image_tag, true)
2125
}

0 commit comments

Comments
 (0)