terraform-provider-docker icon indicating copy to clipboard operation
terraform-provider-docker copied to clipboard

Apple M1 Build Context `platform` does not work

Open hunttom opened this issue 2 years ago • 3 comments

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform (and docker Provider) Version

  • Using previously-installed hashicorp/aws v4.22.0
  • Using previously-installed kreuzwerker/docker v2.16.0
  • Using Terraform v1.2.5

Affected Resource(s)

  • docker_registry_image

Terraform Configuration Files

resource "docker_registry_image" "build_image" {
  name = local.ecr_image_name

  build {
    context    = local.source_path
    dockerfile = var.docker_file_path
    build_args = local.build_args
    platform = "linux/amd64"
  }
}

Panic Output

Error when running Lambda functions: IMAGE Launch error: fork/exec /lambda-entrypoint.sh: exec format error Entrypoint: [/lambda-entrypoint.sh] Cmd: [lambda_function.lambda_handler] WorkingDir: [/var/task]

Expected Behaviour

Successfully build Lambda image using appropriate platform.

Actual Behaviour

Unable to build AMD64 containers for AWS Lambda because docker_registry_image does not honor platform build context.

Steps to Reproduce

Build an image and upload to ECR using Terraform on Apple M1 processor. Test image, validate that platform in build-context does not work.

  1. terraform apply
  2. Run generic AWS Lambda test to validate that Lambda doesn't work with linux/amd64 format.
  3. Switch image type to ARM, run test again.
  4. AWS Lambda works with ARM image.

Important Factoids

  1. I have tested using Docker locally and uploaded to ECR. It works fine specifying docker build -t lambda-image-repo . --platform=linux/amd64
  2. I have tested on an Intel-based processor and TF provider works fine.

hunttom avatar Jul 25 '22 20:07 hunttom

Thanks for submitting this issue! I am currently working on other issues, so this would take a while to fix. In general, we are planning on moving all the docker build things solely to the docker_image, to have single responsibility within the resources. Could you check whether it also does not work when using the docker_image?

Junkern avatar Jul 27 '22 15:07 Junkern

No problem - I was able to successfully build the image using docker_image because it didn't have the platform = linux/amd64' however, I passed the TARGETARCH variable using the build_config block.

The module seems to take the global environmental variables when creating the image which was causing the issue.

hunttom avatar Jul 28 '22 15:07 hunttom

I also ran into this issue but was able to workaround it by adding the following to my Dockerfile:

FROM --platform=linux/x86_64 public.ecr.aws/lambda/python:3.9

I would also like to mention that if what @hunttom saying is true regarding environment variables, I wonder if setting export DOCKER_DEFAULT_PLATFORM=linux/amd64 could help.

GonzalezAndrew avatar Aug 03 '22 22:08 GonzalezAndrew

Hi, I'm running into the same issue and a bit confused on how to use docker build to push an image to ecr? Any chance you can send some example?

alecryan88 avatar Jan 07 '23 23:01 alecryan88

@alecryan88 here is some terraform code pulled from the terraform-aws-lambda/docker-build sub module. Notice how the local variable, ecr_image_name is formatted, it is formatted in a fashion that will push your image to the given ECR repo. The docker-build sub module will be a great starting point for using Terraform to push images to AWS ECR.

data "aws_region" "current" {}

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)
}

resource "docker_registry_image" "this" {
  name = local.ecr_image_name

  build {
    context    = var.source_path
    dockerfile = var.docker_file_path
    build_args = var.build_args
  }

  keep_remotely = var.keep_remotely
}

GonzalezAndrew avatar Jan 09 '23 13:01 GonzalezAndrew

I just tested this on my local machine. I have two docker_image resources, one builds for linux/amd64 and one builds for linux/arm64. Both images where build and work on their respective machines.

The build attribute of the docker_registry_image resource is removed with the newest version, closing this issue

Junkern avatar Feb 23 '23 15:02 Junkern