### Terraform Install Path Configuration Examples Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Demonstrates setting the Terraform working directory using a configuration file, environment variable, or CLI flag. ```bash # Config file terraform-install-path: /home/user/infrastructure # Environment variable export CLOUDFLARE_TERRAFORM_INSTALL_PATH=/home/user/infrastructure # CLI flag cf-terraforming generate \ --terraform-install-path /home/user/infrastructure \ --resource-type cloudflare_zone ``` -------------------------------- ### Install cf-terraforming Locally Source: https://github.com/cloudflare/cf-terraforming/blob/master/README.md Installs the cf-terraforming tool in the current directory using go install. Ensure Go is installed and configured. ```bash GOBIN=$(pwd) go install -v github.com/cloudflare/cf-terraforming/cmd/cf-terraforming@master ``` -------------------------------- ### Configuration File Example Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/cli-commands.md An example of a YAML configuration file for cf-terraforming, showing how to set API credentials, zone, account, and other options. ```yaml email: "user@example.com" key: "your-api-key" # OR token: "your-api-token" zone: "zone-id-here" account: "account-id-here" terraform-install-path: "/path/to/terraform" verbose: true ``` -------------------------------- ### Install cf-terraforming via Go Source: https://github.com/cloudflare/cf-terraforming/blob/master/README.md Installs the cf-terraforming CLI tool using the Go build tool. Ensure Go is installed and configured. ```bash go install github.com/cloudflare/cf-terraforming/cmd/cf-terraforming@latest ``` -------------------------------- ### Install Terraform Binary Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/error-handling.md Installs the Terraform binary using the installer package. Returns an error if the installation fails, for example, due to network issues or if the release is not found. ```go tempExecPath, err := installer.Install(context.Background()) if err != nil { return "", fmt.Errorf("error installing Terraform: %w", err) } ``` -------------------------------- ### Single Resource Type Usage Example Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Example command to run the single resource type import workflow script. ```bash ./import_resource.sh zone-id cloudflare_record ``` -------------------------------- ### Import Zone Setting Example Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Example of importing a specific zone setting, like 'always_online', using Terraform. ```bash terraform import cloudflare_zone_setting.always_online zone-id/always_online ``` -------------------------------- ### Resource Not Found Error Example Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Example of a 'Resource not found (404)' error that may occur during import if the resource has been deleted. ```text Error: Resource not found (404) ``` -------------------------------- ### Path Parameter Usage Example Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/resource-endpoint-mapping.md Demonstrates how to use the `--resource-id` flag with `cf-terraforming generate` to list specific settings for a resource type. ```bash # List all zone settings cf-terraforming generate --resource-type cloudflare_zone_setting --zone $ZONE_ID # List specific zone settings only cf-terraforming generate \ --resource-type cloudflare_zone_setting \ --zone $ZONE_ID \ --resource-id "cloudflare_zone_setting=always_online,cache_level,security_level" ``` -------------------------------- ### Find or Install Terraform Executable Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/api-reference-generation.md This function intelligently resolves the Terraform binary path. It first checks for a user-specified path, then a pre-configured install path, and finally downloads and installs the latest compatible version if not found. ```go execPath, err := findOrInstallTerraform() if err != nil { log.Fatalf("Could not find or install Terraform: %v", err) } ``` -------------------------------- ### Initialize Terraform Executor Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/resource-generation-flow.md Sets up a Terraform executor for a given working directory and retrieves the installed provider version. ```go tf, err := tfexec.NewTerraform(workingDir, execPath) _, providerVersion, err := tf.Version(context.Background(), true) providerVersionString := detectedVersion.String() ``` -------------------------------- ### Exporting Environment Variables for Configuration Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Shows how to set environment variables to configure cf-terraforming, including API token, zone ID, and Terraform installation path. This is followed by an example command to generate resources. ```bash export CLOUDFLARE_API_TOKEN="your-token" export CLOUDFLARE_ZONE_ID="your-zone-id" export CLOUDFLARE_TERRAFORM_INSTALL_PATH="/path/to/tf" cf-terraforming generate --resource-type cloudflare_record ``` -------------------------------- ### Context Usage Example Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/types-and-structures.md Demonstrates the creation and usage of `context.Context` for managing request-scoped values and cancellation. It shows both background context and context with cancellation. ```go ctx := context.Background() // Or for cancellation: ctx, cancel := context.WithCancel(context.Background()) defer cancel() // API calls apiV0.ListZones(ctx) tf.Version(ctx, true) ``` -------------------------------- ### Install cf-terraforming via Homebrew Source: https://github.com/cloudflare/cf-terraforming/blob/master/README.md Installs the cf-terraforming CLI tool using Homebrew. If upgrading from an older version, uninstall and reinstall. ```bash brew tap cloudflare/cloudflare brew install cloudflare/cloudflare/cf-terraforming ``` -------------------------------- ### Example Usage of Resource ID Flags Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/cli-commands.md Demonstrates how to use the --resource-id flag to specify resource types and their corresponding IDs for import operations. ```bash --resource-id "cloudflare_zone_setting=always_online,cache_level" \ --resource-id "cloudflare_page_rule=rule1,rule2" ``` -------------------------------- ### Import Account-Level Ruleset Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Example of importing an account-level ruleset using Terraform. ```bash terraform import cloudflare_ruleset.example account:account-id/ruleset-id ``` -------------------------------- ### Import Zone-Level Ruleset Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Example of importing a zone-level ruleset using Terraform. ```bash terraform import cloudflare_ruleset.example zone:zone-id/ruleset-id ``` -------------------------------- ### Example Debug-Level Logging Output Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Illustrates the detailed output produced when debug-level logging is enabled, showing internal operations and configurations. ```log INFO[0000] terraform-binary-path flag not set INFO[0000] Using explicit Terraform install path DEBUG[0001] Terraform installed successfully. DEBUG[0002] initializing Terraform DEBUG[0003] initializing cloudflare-go with API Token DEBUG[0004] detected provider registry=registry.terraform.io/cloudflare/cloudflare version=5.0.0 DEBUG[0005] reading Terraform schema DEBUG[0006] reading and building resource resource=cloudflare_record DEBUG[0007] generating resource output count=42 resource=cloudflare_record ``` -------------------------------- ### Example User-Agent Header Format Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Shows the format of the User-Agent header after being modified by cf-terraforming, including the tool's version. ```text go-http-client/1.1 cf-terraforming/0.30.0 ``` -------------------------------- ### Cobra Flag Binding Example Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/types-and-structures.md Example of binding a persistent string flag to a variable and Viper configuration. This demonstrates how to handle command-line arguments and environment variables. ```go rootCmd.PersistentFlags().StringVarP(&zoneID, "zone", "z", "", "Zone ID") viper.BindPFlag("zone", rootCmd.PersistentFlags().Lookup("zone")) viper.BindEnv("zone", "CLOUDFLARE_ZONE_ID") ``` -------------------------------- ### Resource ID Mismatch Error Example Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Example of an 'resource with ID "x" not found' error indicating a mismatch between the generated import ID and the actual resource ID. ```text Error: resource with ID "x" not found ``` -------------------------------- ### Example YAML Configuration File Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Demonstrates the structure and available options for the cf-terraforming configuration file in YAML format. Includes settings for authentication, resource scope, Terraform paths, API details, logging, and import. ```yaml # Authentication (choose one method) token: "your-cloudflare-api-token" # OR email: "user@example.com" key: "your-cloudflare-api-key" # Resource Scope zone: "zone-id-here" # OR account: "account-id-here" # Terraform Configuration terraform-install-path: "/path/to/terraform/working/directory" terraform-binary-path: "/usr/local/bin/terraform" # API Configuration hostname: "api.cloudflare.com" provider-registry-hostname: "registry.terraform.io" # Logging verbose: true # Import Settings modern-import-block: false ``` -------------------------------- ### Go Function to Find or Install Terraform Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/cli-commands.md This Go function locates or downloads the Terraform binary. It prioritizes explicit paths, then checks an install path, and finally downloads the latest version if necessary. ```go func findOrInstallTerraform() (string, error) ``` -------------------------------- ### Check Terraform Provider Installation Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/usage-examples.md Verifies that the Cloudflare provider is correctly installed and configured for a Terraform project. ```bash # Verify provider in terraform cd /path/to/terraform terraform providers # Should show: # Providers required by configuration: # - cloudflare/cloudflare (~> 5.0) # Providers required by state: # - cloudflare/cloudflare ``` -------------------------------- ### Go Code for Import ID Construction Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Example Go code demonstrating how the import ID is constructed by retrieving the resource ID, looking up the format template, and replacing placeholders. ```go // Format from map format := resourceImportStringFormats["cloudflare_record"] // ":zone_id/:id" // Placeholder replacement importID := strings.Replace(format, ":zone_id", zoneID, 1) importID = strings.Replace(importID, ":id", resource.ID, 1) // Result: "zone-abc123/record-def456" // Output if useModernImportBlock { fmt.Printf("import {\n to = %s.%s\n id = \"%s\"\n}\n", resourceType, resourceName, importID) } else { fmt.Printf("terraform import %s.%s %s\n", resourceType, resourceName, importID) } ``` -------------------------------- ### Import Account-Level Custom Page Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Example of importing an account-level custom page using Terraform. ```bash terraform import cloudflare_custom_pages.error account:account-id/error_page_401 ``` -------------------------------- ### Generate Load Balancer Setup Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/usage-examples.md Export configurations for Cloudflare Load Balancers, Pools, and Monitors. Load Balancers are typically zone-level, while Pools and Monitors can be account-level. ```bash # Generate load balancers cf-terraforming generate \ --zone $CLOUDFLARE_ZONE_ID \ --resource-type cloudflare_load_balancer # Generate pools cf-terraforming generate \ --account $CLOUDFLARE_ACCOUNT_ID \ --resource-type cloudflare_load_balancer_pool # Generate monitors cf-terraforming generate \ --account $CLOUDFLARE_ACCOUNT_ID \ --resource-type cloudflare_load_balancer_monitor ``` -------------------------------- ### Combined Import Statements for Multiple Types Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Example output showing combined import statements generated for multiple resource types, including records, page rules, and firewall rules. ```bash terraform import cloudflare_record.terraform_managed_resource_rec1_0 zone-id/record-1 terraform import cloudflare_record.terraform_managed_resource_rec2_1 zone-id/record-2 terraform import cloudflare_page_rule.terraform_managed_resource_rule1_0 zone-id/rule-1 terraform import cloudflare_firewall_rule.terraform_managed_resource_fw1_0 zone-id/fw-1 terraform import cloudflare_firewall_rule.terraform_managed_resource_fw2_1 zone-id/fw-2 ``` -------------------------------- ### Terraform Import Block Example Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/types-and-structures.md Example of a modern Terraform import block (Terraform 1.5+). This format is used for importing resources directly within HCL configuration. ```hcl import { to = cloudflare_zone.terraform_managed_resource_abc_0 id = "zone-id" } ``` -------------------------------- ### Handle Provider Schema Read Failure Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/error-handling.md This snippet handles errors when reading the provider schema or detecting provider installation. It logs a fatal error if the schema cannot be read or the provider is not installed. ```go ps, err := tf.ProvidersSchema(context.Background()) if err != nil { log.Fatal("failed to read provider schema", err) } s := ps.Schemas[registryPath] if s == nil { log.Fatal("failed to detect provider installation") } ``` -------------------------------- ### Legacy Terraform Import Command Output Examples Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Demonstrates the default output format for Terraform import statements, suitable for all Terraform versions. This format is used when the `--modern-import-block` flag is not specified. ```bash terraform import cloudflare_record.terraform_managed_resource_rec1_0 zone-id/record-id terraform import cloudflare_page_rule.terraform_managed_resource_rule1_0 zone-id/rule-id terraform import cloudflare_tunnel.terraform_managed_resource_tunnel1_0 account-id/tunnel-id ``` -------------------------------- ### Add cf-terraforming to PATH Source: https://github.com/cloudflare/cf-terraforming/blob/master/README.md Optionally moves the built cf-terraforming executable to a directory in your system's PATH for global access. Verify the installation with --help. ```bash sudo mv cf-terraforming /usr/local/bin/ ``` ```bash cf-terraforming --help ``` -------------------------------- ### Logrus Log Level Configuration Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/types-and-structures.md Example of configuring the Logrus log level based on a verbose flag. This allows dynamic adjustment of logging verbosity during runtime. ```go var cfgLogLevel = logrus.InfoLevel if verbose { cfgLogLevel = logrus.DebugLevel } log.SetLevel(cfgLogLevel) ``` -------------------------------- ### Configure Production Environment for Cloudflare Terraforming Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Set up production configurations using a YAML file, emphasizing security by using environment variables for sensitive data like API tokens. Usage example demonstrates applying the production config. ```yaml # ~/.cf-terraforming.prod.yaml token: "prod-api-token" # Or use env var for security account: "prod-account-id" terraform-install-path: "/home/user/projects/prod-tf" verbose: false ``` ```bash export CLOUDFLARE_API_TOKEN="prod-token" cf-terraforming generate \ --config ~/.cf-terraforming.prod.yaml \ --resource-type cloudflare_zone ``` -------------------------------- ### Go Function to Get Resource Mappings Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/cli-commands.md Parses resource ID flags into a structured map. The input format is 'resourceType=id1,id2,...', and the output is a map of resource types to slices of their IDs. ```go func getResourceMappings() map[string][]string ``` -------------------------------- ### Export DNS Records to Terraform Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/00-START-HERE.md This example demonstrates how to export DNS records to Terraform configuration and import them into state using cf-terraforming. Ensure your Cloudflare API token and Zone ID are set as environment variables, and that Terraform is initialized in your project directory. ```bash export CLOUDFLARE_API_TOKEN="your-token" export CLOUDFLARE_ZONE_ID="your-zone-id" cd /path/to/terraform && terraform init cf-terraforming generate --resource-type cloudflare_record > dns.tf cf-terraforming import --resource-type cloudflare_record | bash ``` -------------------------------- ### Initialize Terraform Project Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/usage-examples.md Sets up a new Terraform project directory, initializes Git, and creates a basic Terraform configuration file with the Cloudflare provider. ```bash mkdir cloudflare-infrastructure cd cloudflare-infrastructure git init ``` ```hcl terraform { required_providers { cloudflare = { source = "cloudflare/cloudflare" version = "~> 5.0" } } } provider "cloudflare" { api_token = var.cloudflare_api_token } variable "cloudflare_api_token" { sensitive = true } ``` ```bash terraform init ``` -------------------------------- ### Configure Development Environment for Cloudflare Terraforming Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Define development-specific settings in a YAML configuration file. This includes API tokens, zone IDs, and installation paths. Usage example shows how to apply this config. ```yaml # ~/.cf-terraforming.dev.yaml token: "dev-api-token" zone: "dev-zone-id" terraform-install-path: "/home/user/projects/dev-tf" verbose: true ``` ```bash cf-terraforming generate \ --config ~/.cf-terraforming.dev.yaml \ --resource-type cloudflare_record ``` -------------------------------- ### Go Function for Initializing Configuration Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Illustrates the `initConfig` function in Go, which handles loading configuration from files and environment variables using the Viper library. It also sets the initial log level based on the 'verbose' setting. ```go func initConfig() { if cfgFile != "" { viper.SetConfigFile(cfgFile) } else { home, err := homedir.Dir() viper.AddConfigPath(home) viper.SetConfigName(".cf-terraforming") } viper.AutomaticEnv() // Enable env var reading viper.SetEnvPrefix("cf_terraforming") // Read config file (non-fatal if missing) if err := viper.ReadInConfig(); err == nil { log.Debug("using config file:", viper.ConfigFileUsed()) } // Set log level var cfgLogLevel = logrus.InfoLevel if verbose { cfgLogLevel = logrus.DebugLevel } log.SetLevel(cfgLogLevel) } ``` -------------------------------- ### Initialize Cloudflare API v0 Client Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/types-and-structures.md Demonstrates how to initialize the Cloudflare API v0 client using either an API token or an API key and email. ```go // Token-based apiV0, err := cfv0.NewWithAPIToken(apiToken, options...) // Key-based apiV0, err := cfv0.New(apiKey, apiEmail, options...) ``` -------------------------------- ### State Already Exists Error Example Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Example of a 'Resource already exists in state' error when attempting to import a resource that is already managed by Terraform. ```text Error: Resource already exists in state ``` -------------------------------- ### Initialize Terraform Source: https://github.com/cloudflare/cf-terraforming/blob/master/README.md Initializes the Terraform working directory. This command downloads the necessary provider plugins. ```bash terraform init ``` -------------------------------- ### Initialize Cloudflare API v4 Client Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/types-and-structures.md Shows how to initialize the Cloudflare API v4 client using API token and an optional HTTP client. ```go api := cloudflare.NewClient( option.WithAPIToken(apiToken), option.WithHTTPClient(httpClient), ) ``` -------------------------------- ### Create and Format HCL File Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/types-and-structures.md Shows the basic steps for creating an in-memory HCL file representation, appending a new resource block, and formatting the resulting HCL content. ```go f := hclwrite.NewEmptyFile() rootBody := f.Body() rootBody.AppendNewBlock("resource", []string{resourceType, resourceID}) hclwrite.Format(f.Bytes()) ``` -------------------------------- ### Transformed Data Structure Example Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/types-and-structures.md Example structure of transformed API data, represented as a slice of maps. This structure allows for flexible field extraction and modification using type assertions. ```json [ { "id": "resource-id", "name": "resource-name", "config": { "nested": "value" }, "items": [ { "item": "value" } ], }, // ... more resources ] ``` -------------------------------- ### Path Parameter Resource Initialization Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/resource-endpoint-mapping.md Shows the initialization of a map that defines resources supporting path parameters, used for granular filtering of resources. ```go settingsMap = map[string][]string{ "cloudflare_zone_setting": make([]string, 0), "cloudflare_hostname_tls_setting": make([]string, 0), "cloudflare_waiting_room_event": make([]string, 0), "cloudflare_r2_managed_domain": make([]string, 0), // ... more resources } ``` -------------------------------- ### Post-Import Verification Steps Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Bash commands to verify imported resources by listing them in the state, showing their details, and checking for drift with a Terraform plan. ```bash # List imported resources terraform state list | grep cloudflare_record # Verify each resource terraform state show cloudflare_record.terraform_managed_resource_rec1_0 # Check for drift terraform plan # Should show "No changes" if correct ``` -------------------------------- ### API Token Authentication via Configuration File Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Shows how to configure the Cloudflare API token directly within the `~/.cf-terraforming.yaml` configuration file. ```bash # Via config file echo "token: v1.0-xxx..." >> ~/.cf-terraforming.yaml ``` -------------------------------- ### API Key + Email Authentication via Configuration File Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Demonstrates configuring the Cloudflare API key and email address within the `~/.cf-terraforming.yaml` configuration file. ```yaml email: "user@example.com" key: "abcdef1234567890..." ``` -------------------------------- ### Account-Scoped Resource Endpoints Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/resource-endpoint-mapping.md Examples of common API endpoints for resources scoped to a specific Cloudflare account. ```http GET /accounts/{account_id}/members GET /accounts/{account_id}/tunnels GET /accounts/{account_id}/workers/kv/namespaces ``` -------------------------------- ### Zone-Scoped Resource Endpoints Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/resource-endpoint-mapping.md Examples of common API endpoints for resources scoped to a specific Cloudflare zone. ```http GET /zones/{zone_id}/dns_records GET /zones/{zone_id}/page_rules GET /zones/{zone_id}/firewall/rules ``` -------------------------------- ### Generated Cloudflare Record HCL Source: https://github.com/cloudflare/cf-terraforming/blob/master/README.md Example of Terraform HCL generated by cf-terraforming for a Cloudflare record resource. ```hcl resource "cloudflare_record" "terraform_managed_resource" { name = "example.com" proxied = false ttl = 120 type = "A" value = "198.51.100.4" zone_id = "0da42c8d2132a9ddaf714f9e7c920711" } ``` -------------------------------- ### Go Implementation for API Key + Email Authentication Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Provides the Go code snippet for initializing the Cloudflare API client using both an API key and email address. It configures the client with these credentials and other options. ```go apiV0, err = cfv0.New(apiKey, apiEmail, options...) api = cloudflare.NewClient( option.WithAPIKey(apiKey), option.WithAPIEmail(apiEmail), option.WithHTTPClient(httpClient), ) ``` -------------------------------- ### initConfig() Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/api-reference-generation.md Initializes the Viper configuration from a configuration file and environment variables. This function is called via Cobra's `OnInitialize` hook. ```APIDOC ## initConfig() ### Description Initializes viper configuration from file and environment variables. Called via Cobra's `OnInitialize` hook. ### Signature ```go func initConfig() void ``` ### Returns None ### Behavior 1. If `--config` specified, uses that file 2. Otherwise searches home directory for `.cf-terraforming` config file 3. Enables automatic environment variable binding 4. Sets environment variable prefix to `CLOUDFLARE_` and `CF_TERRAFORMING_` 5. Reads config file (silently succeeds if not found) 6. Sets logger to debug level if `--verbose` flag ### Side Effects Modifies viper state ### Example ```go cobra.OnInitialize(initConfig) ``` ``` -------------------------------- ### Import Zone-Level Custom Page Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Example of importing a zone-level custom page (e.g., a 401 error page) using Terraform. ```bash terraform import cloudflare_custom_pages.error zone:zone-id/error_page_401 ``` -------------------------------- ### Go Function to Initialize Configuration Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/cli-commands.md Initializes the Viper configuration, reading from files and environment variables. It supports binding environment variables prefixed with CLOUDFLARE_ and setting log levels via the --verbose flag. ```go func initConfig() ``` -------------------------------- ### Generate with Custom Terraform Path Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/cli-commands.md Generates HCL terraform resource blocks, specifying custom paths for the Terraform binary and installation directory. ```bash # Generate with custom terraform path cf-terraforming generate \ --resource-type cloudflare_zone \ --terraform-binary-path /usr/local/bin/terraform \ --terraform-install-path /path/to/tf/project ``` -------------------------------- ### Export Account Members Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/00-START-HERE.md Use the 'generate' command to export account members for a given account ID. Refer to usage examples for more details. ```bash cf-terraforming generate --resource-type cloudflare_account_member --account $ACCOUNT_ID ``` -------------------------------- ### Export DNS Records Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/00-START-HERE.md Use the 'generate' command to export DNS records for a given zone ID. Refer to usage examples for more details. ```bash cf-terraforming generate --resource-type cloudflare_record --zone $ZONE_ID ``` -------------------------------- ### Handle No Resources Found Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/error-handling.md Prints a message to stderr indicating that no resources of the specified type were found to generate. The process completes normally. ```go if resourceCount == 0 { fmt.Fprintf(cmd.OutOrStderr(), "no resources of type %q found to generate", resourceType) return } ``` -------------------------------- ### Initialize Viper Configuration Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/api-reference-generation.md Initializes Viper configuration, loading settings from a specified file or default locations, and enabling environment variable binding. This function is called via Cobra's OnInitialize hook. ```Go cobra.OnInitialize(initConfig) ``` -------------------------------- ### Persistent Terraform Install Path Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Uses a persistent cache directory for Terraform binaries specified via a CLI flag. This is checked after the explicit path. ```bash cf-terraforming generate \ --terraform-install-path /home/user/.terraform \ --resource-type cloudflare_zone ``` -------------------------------- ### Path Parameter Endpoint Replacement Logic Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/resource-endpoint-mapping.md Outlines the implementation logic for handling path parameters, including checking resource support, retrieving mappings, and replacing parameters in endpoints before fetching API responses. ```go if isSupportedPathParam(resources, resourceType) { resourceIDsMap = getResourceMappings() ids, ok := resourceIDsMap[resourceType] if ok && len(ids) == 0 { log.Fatalf("No resource IDs defined in Terraform for resource %s", resourceType) } } // Replace path parameters in endpoints if ok && len(pathParams) > 0 { endpoints := replacePathParams(pathParams, endpoint, resourceType) jsonStructData, err = getAPIResponse(result, pathParams, endpoints...) } else { jsonStructData, err = getAPIResponse(result, pathParams, endpoint) } ``` -------------------------------- ### Post-Process HCL for Specific Resources Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/resource-generation-flow.md Applies resource-specific transformations to the generated HCL. Examples include wrapping 'meta' with jsonencode() for cloudflare_stream or 'url' with urlencode() for cloudflare_observatory_scheduled_test. ```go postProcess(f, resourceType) ``` -------------------------------- ### Unsupported Resource Validation Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/resource-endpoint-mapping.md Logs a warning and skips unsupported resources if both 'list' and 'get' endpoints are undefined in the mapping. This prevents errors for resources not yet supported by the provider. ```go if resourceToEndpoint[resourceType]["list"] == "" && resourceToEndpoint[resourceType]["get"] == "" { log.WithFields(logrus.Fields{ "resource": resourceType, }).Warn("Unsupported terraform v5 provider resource") continue } ``` -------------------------------- ### Generate Resources Command Handler Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/api-reference-generation.md This function serves as the main entry point for the 'generate' subcommand. It orchestrates the entire resource generation process, from Terraform initialization to producing HCL output. ```go generateCmd = &cobra.Command{ Use: "generate", Run: generateResources(), PreRun: sharedPreRun, } ``` -------------------------------- ### Generate Cloudflare DNS Records to File Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/usage-examples.md Generates Cloudflare DNS records for a specified zone and saves them to a 'dns.tf' file. This is a basic usage example for generating Terraform configuration. ```bash cf-terraforming generate \ --zone $CLOUDFLARE_ZONE_ID \ --resource-type cloudflare_record > dns.tf ``` -------------------------------- ### API Key + Email Authentication via Environment Variables Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Shows how to set both the Cloudflare API key and email address using environment variables for authentication. This method grants full account access. ```bash # Via environment variables export CLOUDFLARE_EMAIL="user@example.com" export CLOUDFLARE_API_KEY="abcdef1234567890..." ``` -------------------------------- ### Endpoint Resolution Logic Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/resource-endpoint-mapping.md Determines the API endpoint to use for a resource, prioritizing 'list' and falling back to 'get'. This ensures consistent data retrieval by always returning an array. ```go endpoint := resourceToEndpoint[resourceType]["list"] if endpoint == "" { endpoint = resourceToEndpoint[resourceType]["get"] } ``` -------------------------------- ### Import Cloudflare Record (All Terraform Versions) Source: https://github.com/cloudflare/cf-terraforming/blob/master/README.md Generates the necessary commands to import a Cloudflare record resource into Terraform state. Requires Cloudflare API credentials and zone ID. ```bash cf-terraforming import \ --resource-type "cloudflare_record" \ --email $CLOUDFLARE_EMAIL \ --key $CLOUDFLARE_API_KEY \ --zone $CLOUDFLARE_ZONE_ID ``` -------------------------------- ### findOrInstallTerraform Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/api-reference-generation.md Intelligently resolves the Terraform binary path using a priority-based fallback strategy, including checking user-defined paths, existing installations, and downloading the latest compatible version if necessary. ```APIDOC ## findOrInstallTerraform ### Description Intelligent Terraform binary resolution with three fallback strategies. ### Signature ```go func findOrInstallTerraform() (string, error) ``` ### Returns - `string`: Full path to Terraform executable - `error`: Any error encountered during lookup or installation ### Logic Priority 1. If `--terraform-binary-path` is set, verify and use it 2. If binary exists at `--terraform-install-path`, use it 3. Download latest compatible Terraform (~1.0.x) to cache/temp location 4. Move downloaded binary to persistent install path ### Parameters None ### Error Conditions - `--terraform-binary-path` file not found - Cache directory not accessible - Download failure - Rename/copy failure ### Example ```go execPath, err := findOrInstallTerraform() if err != nil { log.Fatalf("Could not find or install Terraform: %v", err) } ``` ``` -------------------------------- ### Execute() Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/api-reference-generation.md Main entry point for the API reference generation tool. It executes the root Cobra command and handles any fatal errors during the process. ```APIDOC ## Execute() ### Description Main entry point. Executes the root Cobra command and handles any fatal errors. ### Signature ```go func Execute() void ``` ### Returns None ### Behavior 1. Calls `rootCmd.Execute()` 2. Logs errors if execution fails 3. Returns (no exit code control) ### Example ```go func main() { cmd.Execute() } ``` ``` -------------------------------- ### Go Implementation for API Token Authentication Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Provides the Go code snippet responsible for initializing the Cloudflare API client using an API token. It configures the client with the token and other options. ```go if useToken { apiV0, err = cfv0.NewWithAPIToken(apiToken, options...) api = cloudflare.NewClient( option.WithAPIToken(apiToken), option.WithHTTPClient(httpClient), ) } ``` -------------------------------- ### Execute Root Cobra Command Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/api-reference-generation.md The main entry point for the application. It executes the root Cobra command and handles any fatal errors that occur during execution. ```Go func main() { cmd.Execute() } ``` -------------------------------- ### GitHub Actions Workflow for Cloudflare Terraform Generation Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/usage-examples.md An example GitHub Actions workflow that automates the generation and formatting of Cloudflare Terraform resources. It checks for changes and creates a pull request if updates are detected. ```yaml name: Generate Cloudflare Terraform on: workflow_dispatch: schedule: - cron: '0 2 * * *' # Daily at 2 AM jobs: generate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: hashicorp/setup-terraform@v3 - name: Generate resources env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_ZONE_ID: ${{ secrets.CLOUDFLARE_ZONE_ID }} run: | cf-terraforming generate \ --resource-type cloudflare_record > dns.tf terraform fmt dns.tf - name: Create Pull Request if: git diff --exit-code dns.tf uses: peter-evans/create-pull-request@v5 with: commit-message: "chore: update generated cloudflare resources" title: "chore: update cloudflare terraform" body: "Auto-generated from cf-terraforming" ``` -------------------------------- ### Combined Endpoint Rewriting Logic Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/resource-endpoint-mapping.md Illustrates the logic for rewriting endpoints that contain `{accounts_or_zones}` and `{account_or_zone_id}` placeholders, adapting them based on whether an account ID or zone ID is provided. ```go if strings.Contains(endpoint, "{accounts_or_zones}") { if accountID != "" { endpoint = strings.Replace(endpoint, "/{accounts_or_zones}/{account_or_zone_id}/", "/accounts/{account_id}/", 1) } else { endpoint = strings.Replace(endpoint, "/{accounts_or_zones}/{account_or_zone_id}/", "/zones/{zone_id}/", 1) } } ``` -------------------------------- ### API Response Fetching Function Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/resource-endpoint-mapping.md The `getAPIResponse` function constructs HTTP GET requests, parses JSON, extracts data, and returns an array of resource objects. It handles multiple endpoints and API errors. ```go jsonStructData, err = getAPIResponse(result, pathParams, endpoints...) ``` -------------------------------- ### Shared Pre-Run Hook Initialization Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/api-reference-generation.md This pre-run hook is executed before any subcommand. It initializes Cloudflare API clients and validates essential configuration parameters like account and zone exclusivity, and authentication credentials. ```go func sharedPreRun(cmd *cobra.Command, args []string) { accountID = viper.GetString("account") zoneID = viper.GetString("zone") if accountID != "" && zoneID != "" { log.Fatal("--account and --zone are mutually exclusive") } } ``` -------------------------------- ### Clone and Build cf-terraforming Source: https://github.com/cloudflare/cf-terraforming/blob/master/README.md Clones the cf-terraforming repository and builds the executable locally. This is useful for development and testing. ```bash git clone https://github.com/cloudflare/cf-terraforming.git cd cf-terraforming ``` ```bash go build -o cf-terraforming ./cmd/cf-terraforming ``` ```bash ./cf-terraforming --help ``` -------------------------------- ### API Token Authentication via Environment Variable Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Demonstrates setting the Cloudflare API token using an environment variable for authentication. This method is recommended for its restricted scope. ```bash # Via environment variable export CLOUDFLARE_API_TOKEN="v1.0-xxx..." ``` -------------------------------- ### Saving and Executing Import Commands Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Shows how to save the generated Terraform import commands to a shell script file and then execute them line by line. ```bash # Save to file cf-terraforming import --resource-type cloudflare_record > imports.sh # Execute line by line bash imports.sh ``` -------------------------------- ### API Key + Email Authentication via CLI Flags Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/configuration-and-logging.md Illustrates providing the Cloudflare API key and email address as command-line flags for the `cf-terraforming generate` command. ```bash # Via CLI flags cf-terraforming generate \ --email user@example.com \ --key abcdef1234567890 \ --resource-type cloudflare_zone ``` -------------------------------- ### Generate Resources to Different Files Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/usage-examples.md Organizes generated Cloudflare resources into separate .tf files based on their resource type using a bash loop. ```bash #!/bin/bash ZONE_ID=$CLOUDFLARE_ZONE_ID TYPES="cloudflare_record cloudflare_page_rule cloudflare_firewall_rule cloudflare_load_balancer" for TYPE in $TYPES; do FILE="${TYPE}.tf" echo "Generating $TYPE to $FILE..." cf-terraforming generate \ --zone $ZONE_ID \ --resource-type "$TYPE" > "$FILE" done ``` -------------------------------- ### Generate Imports for Multiple Resource Types Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Command to generate import statements for multiple resource types simultaneously by listing them in the `--resource-type` flag. ```bash cf-terraforming import \ --zone $CLOUDFLARE_ZONE_ID \ --resource-type cloudflare_record,cloudflare_page_rule,cloudflare_firewall_rule ``` -------------------------------- ### Import Cloudflare Record (Terraform 1.5+) Source: https://github.com/cloudflare/cf-terraforming/blob/master/README.md Generates an import block compatible with Terraform 1.5 and later for Cloudflare record resources. Requires Cloudflare API credentials and zone ID. ```bash cf-terraforming import \ --resource-type "cloudflare_record" \ --modern-import-block \ --email $CLOUDFLARE_EMAIL \ --key $CLOUDFLARE_API_KEY \ --zone $CLOUDFLARE_ZONE_ID ``` -------------------------------- ### Settings Map for Path Parameters Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/types-and-structures.md A map used to track resources that support path parameters and to store their associated values. It is initialized with empty slices and populated by `getResourceMappings()`. ```go var settingsMap = map[string][]string{ "cloudflare_zone_setting": make([]string, 0), "cloudflare_hostname_tls_setting": make([]string, 0), "cloudflare_waiting_room_event": make([]string, 0), // ... 16 more resources supporting path parameters } ``` -------------------------------- ### Execute Import Commands (Manual) Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Manually executes individual `terraform import` commands for specific resources. ```bash terraform import cloudflare_record.terraform_managed_resource_abc_0 zone-id/record-id terraform import cloudflare_record.terraform_managed_resource_def_1 zone-id/record-id ``` -------------------------------- ### Generate With Custom Config File Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/usage-examples.md Use a custom YAML configuration file for settings like API tokens, zone IDs, and Terraform paths. This allows for environment-specific configurations. ```bash # Create config cat > ~/.cf-terraforming.prod.yaml << EOF token: "v1.0-xxx..." zone: "abc123def456..." terraform-install-path: "/home/user/terraform-prod" verbose: false EOF # Use config cf-terraforming generate \ --config ~/.cf-terraforming.prod.yaml \ --resource-type cloudflare_zone_settings_override ``` -------------------------------- ### Handle Resource Schema Not Found Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/error-handling.md Logs a fatal error if a resource type cannot be found in the initialized provider schema. This indicates the resource type is not defined. ```go if r == nil { log.Fatalf("failed to find %q in the initialized provider schema", resourceType) } ``` -------------------------------- ### Execute Import Commands (Modern Apply) Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Applies the generated HCL import blocks using `terraform apply` for Terraform 1.5+. ```bash terraform apply imports.tf ``` -------------------------------- ### Global Configuration Variables Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/types-and-structures.md Declares global variables for configuration parameters. These are populated from flags, environment variables, or configuration files via Viper and flag parsing in `initConfig()`. ```go var ( cfgFile, zoneID, hostname, apiEmail string apiKey, apiToken, accountID string terraformInstallPath, terraformBinaryPath, providerRegistryHostname string verbose, useModernImportBlock bool ) ``` -------------------------------- ### Review Generated Import Commands Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md Displays the content of the generated import script and shows the expected format of the `terraform import` commands. ```bash # View generated commands cat imports.sh # Expected format: # terraform import cloudflare_record.terraform_managed_resource_abc123_0 zone-id/record-id-1 # terraform import cloudflare_record.terraform_managed_resource_def456_1 zone-id/record-id-2 ``` -------------------------------- ### Generate Specific Zone Settings Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/usage-examples.md Fetch only specific zone settings by providing a comma-separated list of setting names using the --resource-id flag. This is more efficient than fetching all settings. ```bash cf-terraforming generate \ --zone $CLOUDFLARE_ZONE_ID \ --resource-type cloudflare_zone_setting \ --resource-id "cloudflare_zone_setting=always_online,cache_level,security_level" ``` -------------------------------- ### Bulk Account Resources Import Workflow Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/import-functionality.md A bash script to generate Terraform configuration and import statements for multiple account-level resources. ```bash #!/bin/bash ACCOUNT_ID=$1 RESOURCES=( "cloudflare_account_member" "cloudflare_tunnel" "cloudflare_workers_kv_namespace" "cloudflare_load_balancer_pool" ) for RESOURCE in "${RESOURCES[@]}"; do echo "Importing $RESOURCE..." # Generate cf-terraforming generate \ --account $ACCOUNT_ID \ --resource-type $RESOURCE >> account.tf 2>/dev/null # Import cf-terraforming import \ --account $ACCOUNT_ID \ --resource-type $RESOURCE >> account_imports.sh 2>/dev/null echo " ✓ Done" done echo "Configuration: account.tf" echo "Imports: account_imports.sh" ``` -------------------------------- ### Go Function for Shared Pre-Run Hook Source: https://github.com/cloudflare/cf-terraforming/blob/master/_autodocs/cli-commands.md This function serves as a pre-run hook for CLI subcommands, responsible for initializing Cloudflare API clients and configuring the logging level. ```go func sharedPreRun(cmd *cobra.Command, args []string) ```