terraform-provider-docker
terraform-provider-docker copied to clipboard
changing `context` location in `docker_registry_image` resource fails to build image in Windows only
Versions:
Terraform: 1.0.11
kreuzwerker/docker: 2.15.0
aws: 3.69.0
Docker: 20.10.11
Hello. I am working with a company and implementing Terraform to their builds. In order to keep from redoing all their code base, I am adding a terraform
directory to their existing code and adding the Terraform there. I know this is a little tricky with the docker_registry_image
as it seems the provider wants the source code and Docker imaage inside the Terraform working directory, so I'm doing a workaround to get that to work. My workaround works with Unix (Linux/macOS) but it does not work with Windows. I receive the error: Error: Error building docker image: unable to build context: unable to read build context - CreateFile C: The system cannot find the file specified.
main.tf
terraform {
backend "s3" {
bucket = "xxx"
key = "xxx.tfstate"
region = "us-west-1"
}
required_providers {
docker = {
source = "kreuzwerker/docker"
version = ">= 2.8.0"
}
}
}
provider "aws" {
region = var.region
profile = "default"
}
provider "docker" {
host = local.os_check == "Windows" ? "npipe:////.//pipe//docker_engine" : null
registry_auth {
address = local.ecr_address
username = data.aws_ecr_authorization_token.token.user_name
password = data.aws_ecr_authorization_token.token.password
}
}
data "external" "os" {
working_dir = path.module
program = ["printf", "{\"os\": \"Linux\"}"]
}
resource "docker_registry_image" "image" {
name = format("%v:%v", aws_ecr_repository.repo.repository_url, "latest")
build {
context = trimsuffix("${path.cwd}", "/terraform") # DOES NOT WORK IN WINDOWS BUT WORKS IN UNIX
dockerfile = "Dockerfile"
}
}
var.tf:
locals {
ecr_address = format("%v.dkr.ecr.%v.amazonaws.com", data.aws_caller_identity.current.account_id, var.region)
ecr_image_name = format("%v/%v:%v", local.ecr_address, aws_ecr_repository.repo.id, "latest")
os_check = data.external.os.result.os == "Windows" ? "Windows" : "Linux"
}
variable "region" {
default = "us-west-1"
}
tree:
|-- Dockerfile
|-- Scripts
| `-- local-invoke-dev.bat
|-- entry.sh
|-- hrrr.py
`-- terraform
|-- main.tf
|-- printf.cmd
`-- var.tf
Output of plan:
# docker_registry_image.image will be created
+ resource "docker_registry_image" "image" {
+ id = (known after apply)
+ insecure_skip_verify = false
+ keep_remotely = false
+ name = "xxx.dkr.ecr.us-west-1.amazonaws.com/xxx:latest"
+ sha256_digest = (known after apply)
+ build {
+ context = "C:/Users/xxx/source/repos/xxx/xxx:506589686c3d0c3c58f829e0e75a60161c2aa08da96b2268b5e30f4cebe614a3"
+ dockerfile = "Dockerfile"
}
}
Since it doesn't work in Windows, the company is unable to do a local deploy using the following deploy-dev.bat
. file:
@echo off
cd ../terraform
terraform init
terraform workspace new dev
terraform workspace select dev
terraform apply -auto-approve
This will eventually be fixed via CI/CD pipelines running Linux, but local deploys are currently needed for testing.
I am wondering if it is passing the correct argument to CreateFile
.
The CreateFile function can also open disk devices. To open the first disk of your computer, it is necessary to use the \\.\PhysicalDrive0 name; to open the C: partition, use the \\. \C : name.
This issue is stale because it has been open 60 days with no activity.
Remove stale
label or comment or this will be closed in 7 days.
If you don't want this issue to be closed, please set the label pinned
.
I am having a similar problem, not sure if its caused by the same issue. I also have my terraform files in a /terraform
directory of the project, so hence want to build ..
.
resource "docker_registry_image" "image" {
name = "registry.digitalocean.com/myregistry/image:latest"
build{
auth_config{
host_name = "registry.digitalocean.com"
}
context = ".."
}
}
Error building docker image: unable to build context: read ..\terraform\terraform.tfstate: The process cannot access the file because another process has locked a portion of the file.
Same problem also for me on windows (with docker desktop installed).
In my case the error says that the a file is not present inside the context but exactly the same code with exactly the same dockerfile works on linux or mac.
Error building docker image: 0: COPY failed: file not found in build context or excluded by .dockerignore: stat docker_registry_image
... :-)
@mavogel could you please help on this? Passing a windows full path like D:\projects\test\src
doesn't work.
Looking at the attached image this is what I have inside an src
folder that is the root folder of my .net core solution.
I want this folder as the build context.
You can also see that there are CrazyBike.Buy
, CrazyBike.Assembler
, CrazyBike.Shipper
: these are 3 different projects --> 3 different docker images that I want to build.
Notice that inside the src
I have the related dockerfiles : Dockerfile.buy
, Dockerfile.assembler
, Dockerfile.shipper
.
I think each Dockerfile should be inside the related project folder but seems also that docker_registry_image
is not able to locate the docker file if it is not placed AT THE ROOT of the build context, can you confirm this? So I tried to put them at the root directly inside the src
.
This structure works trying to build on mac or linux but not on windows.
As mentioned before I receive an error like:
Error building docker image: 0: COPY failed: file not found in build context or excluded by .dockerignore: stat CrazyBike.Assembler/CrazyBike.Assembler.csproj: file does not exist
You see COPY failed just because inside the Dockerfile this is the first instruction that tries to use the build context.
I also tried removing the .dockerignore
files but this is not the problem (again, it works on mac or linux with .dockerignore
in place).
Please can someone help on this?
In the past 6 months we have improved a lot on the build
block, e.g. making path handling OS specific.
The build
block of the docker_registry_image
is now deprecated, please use docker_image
!
Closing this for now. If you notice any bugs, please open a new issue! Thanks :)
@Junkern Has the documentation not been updated to mention these changes? docker_image
doesn't seem to push to AWS ECR. At least I can't figure out the combination of docker_image.build.auth_config
to make it push with the current documentation. docker_registry_image
doesn't mention build
block as deprecated.
Apparently the tfplugindocs
, which creates the documenation, can only handle a Deprecated
parameter when it is for a primitive field. build
is a complex field so it does not work. I will update the documentation to include that directly in the description.
We are doing the change to have simpler code (only one resource for building a docker image) and to also be more aligned with the docker
cli. In docker there is also a docker build
and a docker push
command.
You use the docker_image
to build your image (basically copy over the build
from docker_registry_image
) and then use docker_registry_image
to push it to ECR:
resource "docker_image" "foo_image" {
provider = "docker.private"
name = "somename"
build {
// your build params
}
}
resource "docker_registry_image" "foo" {
provider = "docker.private"
name = docker_image.foo_image.name
insecure_skip_verify = true
keep_remotely = true
}