Skip to content

Commit a4f51a3

Browse files
authored
Merge pull request #630 from cloudflare/support-non-standard-binaries-and-registries
internal: provide a way to configure non-standard registries and binaries
2 parents 902ca88 + 0875f4f commit a4f51a3

File tree

3 files changed

+52
-29
lines changed

3 files changed

+52
-29
lines changed

README.md

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,27 @@ Usage:
2424
cf-terraforming [command]
2525
2626
Available Commands:
27+
completion Generate the autocompletion script for the specified shell
2728
generate Fetch resources from the Cloudflare API and generate the respective Terraform stanzas
2829
help Help about any command
2930
import Output `terraform import` compatible commands in order to import resources into state
3031
version Print the version number of cf-terraforming
3132
3233
Flags:
33-
-a, --account string Use specific account ID for commands
34-
-c, --config string Path to configuration file (default is $HOME/.cf-terraforming.yaml)
35-
-e, --email string API Email address associated with your account
36-
-h, --help Help for cf-terraforming
37-
-k, --key string API Key generated on the 'My Profile' page. See: https://dash.cloudflare.com/profile
38-
--resource-type string Which resource you wish to generate
39-
--terraform-binary-path string Path to an existing Terraform binary (otherwise, one will be downloaded)
40-
--terraform-install-path string Path to an initialized Terraform working directory (default ".")
41-
-t, --token string API Token
42-
-v, --verbose Specify verbose output (same as setting log level to debug)
43-
-z, --zone string Limit the export to a single zone ID
34+
-a, --account string Use specific account ID for commands
35+
-c, --config string Path to config file (default "/Users/jacob/.cf-terraforming.yaml")
36+
-e, --email string API Email address associated with your account
37+
-h, --help help for cf-terraforming
38+
--hostname string Hostname to use to query the API
39+
-k, --key string API Key generated on the 'My Profile' page. See: https://dash.cloudflare.com/profile
40+
--modern-import-block terraform import Whether to generate HCL import blocks for generated resources instead of terraform import compatible CLI commands. This is only compatible with Terraform 1.5+
41+
--provider-registry-hostname string Hostname to use for provider registry lookups (default "registry.terraform.io")
42+
--resource-type string Which resource you wish to generate
43+
--terraform-binary-path string Path to an existing Terraform binary (otherwise, one will be downloaded)
44+
--terraform-install-path string Path to an initialized Terraform working directory (default ".")
45+
-t, --token string API Token
46+
-v, --verbose Specify verbose output (same as setting log level to debug)
47+
-z, --zone string Limit the export to a single zone ID
4448
4549
Use "cf-terraforming [command] --help" for more information about a command.
4650
```
@@ -164,6 +168,27 @@ $ cf-terraforming import \
164168
--zone $CLOUDFLARE_ZONE_ID
165169
```
166170

171+
## Using non-standard registries
172+
173+
By default, we use the Hashicorp registry (registry.terraform.io) for looking up
174+
the provider to introspect the schema. If you are attempting to use another
175+
registry, you will need to provide the `--provider-registry-hostname` flag or
176+
`CLOUDFLARE_PROVIDER_REGISTRY_HOSTNAME` environment variable to query the correct
177+
registry.
178+
179+
## Using non-standard Terraform binaries
180+
181+
Internally, we use [`terraform-exec`](https://github.com/hashicorp/terraform-exec)
182+
library to run Terraform operations in the same way that the CLI tooling would.
183+
If a `terraform` binary is not available on your system path, we will attempt
184+
to download the latest to use it.
185+
186+
Should you have the binary stored in a non-standard location, want to use an
187+
existing binary, or you wish to provide a Terraform compatible binary (such as
188+
`tofu`), you need to provide the `--terraform-binary-path` flag or
189+
`CLOUDFLARE_TERRAFORM_BINARY_PATH` environment variable to instruct
190+
`cf-terraforming` which you expect to use.
191+
167192
## Supported Resources
168193

169194
Any resources not listed are currently not supported.

internal/app/cf-terraforming/cmd/generate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func generateResources() func(cmd *cobra.Command, args []string) {
8383
if err != nil {
8484
log.Fatal("failed to read provider schema", err)
8585
}
86-
s := ps.Schemas["registry.terraform.io/cloudflare/cloudflare"]
86+
s := ps.Schemas[providerRegistryHostname+"/cloudflare/cloudflare"]
8787
if s == nil {
8888
log.Fatal("failed to detect provider installation")
8989
}

internal/app/cf-terraforming/cmd/root.go

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
)
1010

1111
var log = logrus.New()
12-
var cfgFile, zoneID, hostname, apiEmail, apiKey, apiToken, accountID, terraformInstallPath, terraformBinaryPath string
12+
var cfgFile, zoneID, hostname, apiEmail, apiKey, apiToken, accountID, terraformInstallPath, terraformBinaryPath, providerRegistryHostname string
1313
var verbose, useModernImportBlock bool
1414
var api *cloudflare.API
1515
var terraformImportCmdPrefix = "terraform import"
@@ -42,12 +42,11 @@ func init() {
4242
return
4343
}
4444

45-
// Here you will define your flags and configuration settings.
46-
// Cobra supports persistent flags, which, if defined here,
47-
// will be global for your application.
4845
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", home+"/.cf-terraforming.yaml", "Path to config file")
46+
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Specify verbose output (same as setting log level to debug)")
47+
rootCmd.PersistentFlags().StringVar(&resourceType, "resource-type", "", "Which resource you wish to generate")
48+
rootCmd.PersistentFlags().BoolVarP(&useModernImportBlock, "modern-import-block", "", false, "Whether to generate HCL import blocks for generated resources instead of `terraform import` compatible CLI commands. This is only compatible with Terraform 1.5+")
4949

50-
// Zone selection
5150
rootCmd.PersistentFlags().StringVarP(&zoneID, "zone", "z", "", "Limit the export to a single zone ID")
5251
if err = viper.BindPFlag("zone", rootCmd.PersistentFlags().Lookup("zone")); err != nil {
5352
log.Fatal(err)
@@ -56,7 +55,6 @@ func init() {
5655
log.Fatal(err)
5756
}
5857

59-
// Account
6058
rootCmd.PersistentFlags().StringVarP(&accountID, "account", "a", "", "Use specific account ID for commands")
6159
if err = viper.BindPFlag("account", rootCmd.PersistentFlags().Lookup("account")); err != nil {
6260
log.Fatal(err)
@@ -65,7 +63,6 @@ func init() {
6563
log.Fatal(err)
6664
}
6765

68-
// API credentials
6966
rootCmd.PersistentFlags().StringVarP(&apiEmail, "email", "e", "", "API Email address associated with your account")
7067
if err = viper.BindPFlag("email", rootCmd.PersistentFlags().Lookup("email")); err != nil {
7168
log.Fatal(err)
@@ -98,28 +95,29 @@ func init() {
9895
log.Fatal(err)
9996
}
10097

101-
// Debug logging mode
102-
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Specify verbose output (same as setting log level to debug)")
103-
104-
rootCmd.PersistentFlags().StringVar(&resourceType, "resource-type", "", "Which resource you wish to generate")
105-
10698
rootCmd.PersistentFlags().StringVar(&terraformInstallPath, "terraform-install-path", ".", "Path to an initialized Terraform working directory")
107-
10899
if err = viper.BindPFlag("terraform-install-path", rootCmd.PersistentFlags().Lookup("terraform-install-path")); err != nil {
109100
log.Fatal(err)
110101
}
102+
if err = viper.BindEnv("terraform-install-path", "CLOUDFLARE_TERRAFORM_INSTALL_PATH"); err != nil {
103+
log.Fatal(err)
104+
}
111105

112106
rootCmd.PersistentFlags().StringVar(&terraformBinaryPath, "terraform-binary-path", "", "Path to an existing Terraform binary (otherwise, one will be downloaded)")
113-
114107
if err = viper.BindPFlag("terraform-binary-path", rootCmd.PersistentFlags().Lookup("terraform-binary-path")); err != nil {
115108
log.Fatal(err)
116109
}
117-
118-
if err = viper.BindEnv("terraform-install-path", "CLOUDFLARE_TERRAFORM_INSTALL_PATH"); err != nil {
110+
if err = viper.BindEnv("terraform-binary-path", "CLOUDFLARE_TERRAFORM_BINARY_PATH"); err != nil {
119111
log.Fatal(err)
120112
}
121113

122-
rootCmd.PersistentFlags().BoolVarP(&useModernImportBlock, "modern-import-block", "", false, "Whether to generate HCL import blocks for generated resources instead of `terraform import` compatible CLI commands. This is only compatible with Terraform 1.5+")
114+
rootCmd.PersistentFlags().StringVarP(&providerRegistryHostname, "provider-registry-hostname", "", "registry.terraform.io", "Hostname to use for provider registry lookups")
115+
if err = viper.BindPFlag("provider-registry-hostname", rootCmd.PersistentFlags().Lookup("provider-registry-hostname")); err != nil {
116+
log.Fatal(err)
117+
}
118+
if err = viper.BindEnv("provider-registry-hostname", "CLOUDFLARE_PROVIDER_REGISTRY_HOSTNAME"); err != nil {
119+
log.Fatal(err)
120+
}
123121
}
124122

125123
// initConfig reads in config file and ENV variables if set.

0 commit comments

Comments
 (0)