github.com/openshift/installer@v1.4.17/docs/dev/terraform.md (about) 1 # Embedded Terraform in the Installer 2 3 The installer runs terraform in order to provision the infrastructure for a cluster. However, there is a design goal 4 for the installer that the user performing the installation should not be required to have any software pre-installed 5 in their environment. This design goal precludes the user from, for example, being required to have any containerization 6 software available. To get around this for terraform, the installer embeds within its binary the needed terraform 7 binaries. At installation time, the terraform binaries are extracted from the installer into the local file system. 8 9 ## Design 10 11 ### Building terraform binaries 12 13 The terraform binary and all of the terraform provider binaries are built from the ./terraform directory. For example, 14 the aws terraform provider is built from ./terraform/providers/aws. The terraform binary is built from 15 ./terraform/terraform. Each of the terraform providers is compressed into its own zip file to reduce the size of the 16 installer binary. Terraform can use the zipped terraform providers as is without the installer having to unzip the 17 providers first. 18 19 ### Embedding terraform binaries 20 21 After the terraform providers are built, they are each copied into the ./pkg/terraform/providers/mirror directory. The 22 ./pkg/terraform/providers directory is embedded into the installer. To make things simpler, we automatically assign 23 every terraform provider to the openshift/local registry and use a version of 1.0.0. This keeps us from having to track 24 the actual registry name of the provider or the actual version used. This does not have any effect on the behavior of 25 terraform since the installer tightly controls which providers are made available. As an example, when building for 26 linux on amd64, the aws terraform provider would be placed at 27 ./pkg/terraform/providers/mirror/openshift/local/aws/terraform-provider-aws_1.0.0_linux_amd64.zip. The terraform binary 28 is copied into ./pkg/terraform/terraform to be embedded into the installer as well. 29 30 ### Extracting terraform binaries 31 32 When the installer is provisioning the infrastructure for a cluster, the installer extracts the necessary terraform 33 binaries to the local file system. Every terraform stage must define which terraform providers are needed for the stage. 34 The installer will use that information to (1) build a version.tf file to tell terraform which providers to use and (2) 35 extract only the needed providers. 36 37 For example, the set of terraform providers required for the gcp stages are the google and ignition terraform providers. 38 The installer will extract the terraform binary to ${install-dir}/terraform/bin/terraform. The installer will extract 39 the google and ignition terraform providers to ${install-dir}/terraform/plugins. The terraform exec is configured to use 40 ${install-dir}/terraform/plugins as the explicit directory for the plugins. 41 42 ## Adding a new terraform provider 43 44 To add a new terraform provider, create a directory under ./terraform/providers. For example, if you want to add a 45 terraform provider named mycloud, then you would create the ./terraform/providers/mycloud directory. 46 47 ### Public terraform provider 48 49 If the terraform provider you want to add is a public terraform provider, create a tools.go file with an unnamed import 50 to the main package of the terraform provider. Add a go.mod file with a require statement to the terraform provider 51 module. 52 53 For example, let's say that you are adding the mycloud terraform provider. The mycloud terraform provider is in the 54 github.com/hashicorp/terraform-provider-mycloud repository. The main package of the terraform provider is 55 github.com/hashicorp/terraform-provider-mycloud. The version of the terraform provider is v1.2.3. 56 57 ```go 58 // ./terraform/providers/mycloud/tools.go 59 package main 60 61 import ( 62 _ "github.com/hashicorp/terraform-provider-mycloud" 63 ) 64 ``` 65 66 ```go 67 // ./terraform/providers/mycloud/go.mod 68 module github.com/openshift/installer/terraform/providers/mycloud 69 70 go 1.18 71 72 require github.com/hashicorp/terraform-provider-mycloud v1.2.3 73 ``` 74 75 After creating the directory and adding the tools.go and go.mod file, run the following command. 76 1. `make -C terraform go-mod-tidy-vendor.mycloud` 77 78 When there is a tools.go file, the Makefile will build the terraform provider from the package referenced in the unnamed 79 import in the tools.go file. For the example mycloud terraform provider, the terraform provider will be built from the 80 ./terraform/providers/mycloud/vendor/github.com/hashicorp/terraform/provider-mycloud directory. 81 82 ### Custom terraform provider 83 84 If the terraform provider you want to add is a custom terraform provider, then create a main.go file for the custom 85 terraform provider. 86 87 When there is a main.go file, the Makefile will build the terraform provider from the top-level package of the custom 88 terraform provider. 89 90 ## Update the version of terraform or a provider 91 92 To update the version of terraform or a provider, modify the version in the go.mod file for the relevant sub-module. 93 To update the version of terraform, change the version of the required module in ./terraform/terraform/go.mod. To update 94 the version of the aws terraform provider, change the version of the required module in ./terraform/providers/aws/go.mod. 95 96 After updating the require statement in the go.mod file, perform the following actions in the sub-module. 97 1. Remove the require stanza in the go.mod file for the indirect requires. 98 2. Match the replaces in the go.mod file with the replaces from the go.mod file in the upstream terraform provider. 99 3. Run `make -C terraform go-mod-tidy-vendor`.