Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added support for triggers in docker-build module when hash changes #510

Merged
merged 1 commit into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/container-image/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ No inputs.

| Name | Description |
|------|-------------|
| <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 |
| <a name="output_docker_image_id"></a> [docker\_image\_id](#output\_docker\_image\_id) | The ID of the Docker image |
| <a name="output_docker_image_uri"></a> [docker\_image\_uri](#output\_docker\_image\_uri) | The ECR Docker image URI used to deploy Lambda Function |
| <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 |
| <a name="output_lambda_function_arn"></a> [lambda\_function\_arn](#output\_lambda\_function\_arn) | The ARN of the Lambda Function |
Expand Down
30 changes: 25 additions & 5 deletions examples/container-image/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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" {
Expand All @@ -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" {
Expand Down
10 changes: 10 additions & 0 deletions examples/container-image/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
10 changes: 9 additions & 1 deletion modules/docker-build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -94,17 +97,22 @@ No modules.
| <a name="input_ecr_repo"></a> [ecr\_repo](#input\_ecr\_repo) | Name of ECR repository to use or to create | `string` | `null` | no |
| <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 |
| <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 |
| <a name="input_force_remove"></a> [force\_remove](#input\_force\_remove) | Whether to remove image forcibly when the resource is destroyed. | `bool` | `false` | no |
| <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 |
| <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 |
| <a name="input_keep_locally"></a> [keep\_locally](#input\_keep\_locally) | Whether to delete the Docker image locally on destroy operation. | `bool` | `false` | no |
| <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 |
| <a name="input_platform"></a> [platform](#input\_platform) | The target architecture platform to build the image for. | `string` | `null` | no |
| <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 |
| <a name="input_source_path"></a> [source\_path](#input\_source\_path) | Path to folder containing application code | `string` | `null` | no |
| <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 |
| <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 |

## Outputs

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

Expand Down
12 changes: 10 additions & 2 deletions modules/docker-build/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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" {
Expand All @@ -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" {
Expand Down
7 changes: 6 additions & 1 deletion modules/docker-build/outputs.tf
Original file line number Diff line number Diff line change
@@ -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
}
24 changes: 24 additions & 0 deletions modules/docker-build/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 = {}
}
4 changes: 4 additions & 0 deletions wrappers/docker-build/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}