terraform-switcher
terraform-switcher copied to clipboard
Add Dockerfile for use in CI
Ref: https://github.com/warrensbox/terraform-switcher/issues/109
Thank you to @hongkongkiwi for the Dockerfile code.
The simplest solution to automate build in Dockerfub is to link GitHub account and use Automated Builds. For more control, you may want to add docker build/push in Travis-ci.
You can see en example here: https://hub.docker.com/r/barakbd/tfswitch
As extra information in case that helps anyone, I have just learned the following while checking this PR:
We can't use as a base and minimal image scratch here because terraform-switcher
use os/user and that thing is using a C system call internally to getpwuid_r
which is not in scratch obviously, that's the reason why we are compiling this code with the env CGO_ENABLED=1
and therefore CGO_ENABLED=0
which is required to make your binary work on scratch base image won't work
source: https://stackoverflow.com/a/29899712
When trying to build a golang binary using the golang docker image, from a repo that's using go.mod you might get the following error:
$GOPATH/go.mod exists but should not
That's because on the golang docker image the $GOPATH
it's set by default and go build
doesn't know if it should use the local path where we are running the build command to download the dependencies or $GOPATH
, so to solve this we have to unset the environment variable:
unset GOPATH
I indeed see this issue with scratch
:
$ docker run -it --rm tfswitch-scratch:multi -l
2021/05/27 05:20:40 Error getting url: Get "https://releases.hashicorp.com/terraform/": x509: certificate signed by unknown authority
2021/05/27 05:20:40 user: Current requires cgo or $USER set in environment
The alpine
based image is not much larger so it's fine:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tfswitch-alpine multi e5d1a420880c 2 minutes ago 18.9MB
tfswitch-scratch multi 67be03c96f40 10 minutes ago 13.3MB
I updated to go 1.16 and as a consequence also had update vendor files with go mod vendor
.
AFAIK, it is ok to gitignore the vendor
dir (https://stackoverflow.com/questions/51118691/should-i-add-go-dep-vendor-to-gitignore) but it is a matter of preference.
Tested the docker image with a TF repo (running this from withtin a TF repo directory):
$ docker run -it --entrypoint sh --rm -v $PWD:/terraform tfswitch:latest
/ # ls
bin etc lib mnt proc run srv terraform usr
dev home media opt root sbin sys tmp var
/ # cd terraform/
/terraform # tfswitch
Reading required version from terraform file
Reading required version from constraint: ~> 0.14.0
Matched version: 0.14.11
Downloading https://releases.hashicorp.com/terraform/0.14.11/terraform_0.14.11_linux_amd64.zip to terraform_0.14.11_linux_amd64.zip
Downloading ...
33789439 bytes downloaded.
Switched terraform to version "0.14.11"
/terraform # ls
Jenkinsfile config iam.tf output.tf secrets-manager.tf variables.tf
README.md ecr.tf lambda.tf provider.tf sqs.tf
api-gateway.tf files locals.tf rds.tf terraform.tf vpc.tf
@warrensbox - if you can remove the need for the os/user
and then we can build with CGO_ENABLED=0
we can make the docker image tiny using FROM scratch
Maybe we can do this here https://github.com/warrensbox/terraform-switcher/blob/a710b0368ae3aa13b0c4e1891ecce596e9e52c09/lib/install.go#L58:
if errCurr != nil {
installLocation = '/' + installPath
}
Since scratch
has only /
as a path.
I am not too familiar with go
so this is just a suggestion.
As extra information in case that helps anyone, I have just learned the following while checking this PR:
We can't use as a base and minimal image scratch here because
terraform-switcher
use os/user and that thing is using a C system call internally togetpwuid_r
which is not in scratch obviously, that's the reason why we are compiling this code with the envCGO_ENABLED=1
and thereforeCGO_ENABLED=0
which is required to make your binary work on scratch base image won't worksource: https://stackoverflow.com/a/29899712
When trying to build a golang binary using the golang docker image, from a repo that's using go.mod you might get the following error:
$GOPATH/go.mod exists but should not
That's because on the golang docker image the
$GOPATH
it's set by default andgo build
doesn't know if it should use the local path where we are running the build command to download the dependencies or$GOPATH
, so to solve this we have to unset the environment variable:
unset GOPATH
We can try to use this library to avoid using cgo - https://github.com/mitchellh/go-homedir
Will close this for now. Please open a PR again with latest code if this is still needed.