Skip to content

feat: Add buildx and multi-stage build support to docker-build module #679

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

Merged
merged 1 commit into from
May 16, 2025
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
1 change: 1 addition & 0 deletions examples/container-image/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Note that this example may create resources which cost money. Run `terraform des
|------|--------|---------|
| <a name="module_docker_build"></a> [docker\_build](#module\_docker\_build) | ../../modules/docker-build | n/a |
| <a name="module_docker_build_from_ecr"></a> [docker\_build\_from\_ecr](#module\_docker\_build\_from\_ecr) | ../../modules/docker-build | n/a |
| <a name="module_docker_build_multistage"></a> [docker\_build\_multistage](#module\_docker\_build\_multistage) | ../../modules/docker-build | n/a |
| <a name="module_ecr"></a> [ecr](#module\_ecr) | terraform-aws-modules/ecr/aws | n/a |
| <a name="module_lambda_function_with_docker_build"></a> [lambda\_function\_with\_docker\_build](#module\_lambda\_function\_with\_docker\_build) | ../../ | n/a |
| <a name="module_lambda_function_with_docker_build_from_ecr"></a> [lambda\_function\_with\_docker\_build\_from\_ecr](#module\_lambda\_function\_with\_docker\_build\_from\_ecr) | ../../ | n/a |
Expand Down
6 changes: 5 additions & 1 deletion examples/container-image/context/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# `--platform` argument is used to be able to build docker images when using another platform (e.g. Apple M1)
FROM --platform=linux/x86_64 scratch
FROM --platform=linux/x86_64 scratch AS first_stage

ARG FOO

ENV FOO $FOO

COPY empty /empty

FROM first_stage AS second_stage

COPY empty /empty_two
29 changes: 29 additions & 0 deletions examples/container-image/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,35 @@ module "docker_build_from_ecr" {
build_args = {
FOO = "bar"
}
# Can also use buildx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add one more Terraform example showing buildx and multi-stage builds?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

builder = "default"
docker_file_path = "${local.source_path}/Dockerfile"

triggers = {
dir_sha = local.dir_sha
}

cache_from = ["${module.ecr.repository_url}:latest"]
}

module "docker_build_multistage" {
source = "../../modules/docker-build"

ecr_repo = module.ecr.repository_name

use_image_tag = true
image_tag = "first_stage"

source_path = local.source_path
platform = "linux/amd64"
build_args = {
FOO = "bar"
}
builder = "default"
docker_file_path = "${local.source_path}/Dockerfile"

# multi-stage builds
build_target = "first_stage"

triggers = {
dir_sha = local.dir_sha
Expand Down
6 changes: 4 additions & 2 deletions modules/docker-build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ module "docker_image" {
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.22 |
| <a name="requirement_docker"></a> [docker](#requirement\_docker) | >= 3.0 |
| <a name="requirement_docker"></a> [docker](#requirement\_docker) | >= 3.5.0 |
| <a name="requirement_null"></a> [null](#requirement\_null) | >= 2.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.22 |
| <a name="provider_docker"></a> [docker](#provider\_docker) | >= 3.0 |
| <a name="provider_docker"></a> [docker](#provider\_docker) | >= 3.5.0 |
| <a name="provider_null"></a> [null](#provider\_null) | >= 2.0 |

## Modules
Expand All @@ -91,6 +91,8 @@ No modules.
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_build_args"></a> [build\_args](#input\_build\_args) | A map of Docker build arguments. | `map(string)` | `{}` | no |
| <a name="input_build_target"></a> [build\_target](#input\_build\_target) | Set the target build stage to build | `string` | `null` | no |
| <a name="input_builder"></a> [builder](#input\_builder) | The buildx builder to use for the Docker build. | `string` | `null` | no |
| <a name="input_cache_from"></a> [cache\_from](#input\_cache\_from) | List of images to consider as cache sources when building the image. | `list(string)` | `[]` | no |
| <a name="input_create_ecr_repo"></a> [create\_ecr\_repo](#input\_create\_ecr\_repo) | Controls whether ECR repository for Lambda image should be created | `bool` | `false` | no |
| <a name="input_create_sam_metadata"></a> [create\_sam\_metadata](#input\_create\_sam\_metadata) | Controls whether the SAM metadata null resource should be created | `bool` | `false` | no |
Expand Down
2 changes: 2 additions & 0 deletions modules/docker-build/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ resource "docker_image" "this" {
context = var.source_path
dockerfile = var.docker_file_path
build_args = var.build_args
builder = var.builder
target = var.build_target
platform = var.platform
cache_from = var.cache_from
}
Expand Down
12 changes: 12 additions & 0 deletions modules/docker-build/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,24 @@ variable "ecr_repo_tags" {
default = {}
}

variable "builder" {
description = "The buildx builder to use for the Docker build."
type = string
default = null
}

variable "build_args" {
description = "A map of Docker build arguments."
type = map(string)
default = {}
}

variable "build_target" {
description = "Set the target build stage to build"
type = string
default = null
}

variable "ecr_repo_lifecycle_policy" {
description = "A JSON formatted ECR lifecycle policy to automate the cleaning up of unused images."
type = string
Expand Down
2 changes: 1 addition & 1 deletion modules/docker-build/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ terraform {
}
docker = {
source = "kreuzwerker/docker"
version = ">= 3.0"
version = ">= 3.5.0"
}
null = {
source = "hashicorp/null"
Expand Down
2 changes: 2 additions & 0 deletions wrappers/docker-build/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ module "wrapper" {
for_each = var.items

build_args = try(each.value.build_args, var.defaults.build_args, {})
build_target = try(each.value.build_target, var.defaults.build_target, null)
builder = try(each.value.builder, var.defaults.builder, null)
cache_from = try(each.value.cache_from, var.defaults.cache_from, [])
create_ecr_repo = try(each.value.create_ecr_repo, var.defaults.create_ecr_repo, false)
create_sam_metadata = try(each.value.create_sam_metadata, var.defaults.create_sam_metadata, false)
Expand Down
2 changes: 1 addition & 1 deletion wrappers/docker-build/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ terraform {
}
docker = {
source = "kreuzwerker/docker"
version = ">= 3.0"
version = ">= 3.5.0"
}
null = {
source = "hashicorp/null"
Expand Down