terraform-google-terraform-enterprise-hvd

A Terraform module for provisioning and installing Terraform Enterprise on Google Compute Engine as described in HashiCorp Validated Designs

MPL-2.0 License

Stars
1
Committers
1

Terraform Enterprise HVD on GCP GCE

Terraform module aligned with HashiCorp Validated Designs (HVD) to deploy Terraform Enterprise (TFE) on Google Cloud Platform (GCP) using Compute Engine instances with a container runtime. This module defaults to deploying TFE in the active-active operational mode, but external is also supported. Docker is currently the only supported container runtime, but Podman support is being added.

Prerequisites

General

  • TFE license file (e.g. terraform.hclic)
  • Terraform CLI >= 1.9 installed on clients/workstations that will be used to deploy TFE
  • General understanding of how to use Terraform (Community Edition)
  • General understanding of how to use GCP
  • git CLI and Visual Studio Code editor installed on workstations are strongly recommended
  • GCP projeect that TFE will be deployed in with permissions to provision these resources via Terraform CLI
  • (Optional) GCP GCS bucket for GCS remote state backend that will be used to manage the Terraform state of this TFE deployment (out-of-band from the TFE application) via Terraform CLI (Community Edition)

Networking

  • GCP network VPC and the following subnets:
    • Load balancer subnetwork IDS (can be the same as Compute Engine (CE) subnets if desirable).
  • (Optional) GCS VPC Endpoint configured within VPC.
  • (Optional) GCS Hosted Zone for TFE DNS record creation.
  • Security groups. This module will create the:
    • necessary security groups and attach them to the applicable resources.
    • service accounts and assign them access to the provided secrets
    • firewall entries.
    • Ensure the TFE ingress requirements are met.
    • Ensure the TFE egress requirements are met.

Secrets Manager

GCP Secrets Manager "TFE bootstrap" secrets:

  • TFE license file - raw contents of file stored as a plaintext secret.
  • TFE encryption password - random characters stored as plaintext secret.
  • RDS (PostgreSQL) database password - random characters stored as plaintext secret.
  • (Optional) Redis password - random characters stored as a plaintext secret.
  • TFE TLS certificate - file in PEM format, base64-encoded into a string, and stored as a plaintext secret.
  • TFE TLS certificate private key - file in PEM format, base64-encoded into a string, and stored as a plaintext secret.
  • TLS CA bundle - file in PEM format, base64-encoded into a string, and stored as a plaintext secret.

Compute

One of the following mechanisms for shell access to TFE GC instances:

  • Ability to enable GCP IAP (this module supports this via a boolean input variable).
  • GC SSH Key Pair

Log Forwarding (optional)

One of the following logging destinations:

  • Stackdriver
  • A custom fluent bit configuration that will forward logs to custom destination.

Usage

  1. Create/configure/validate the applicable prerequisites.

  2. Nested within the examples directory are subdirectories containing ready-made Terraform configurations for example scenarios on how to call and deploy this module. To get started, choose the example scenario that most closely matches your requirements. You can customize your deployment later by adding additional module inputs as you see fit (see the Deployment-Customizations doc for more details).

  3. Copy all of the Terraform files from your example scenario of choice into a new destination directory to create your Terraform configuration that will manage your TFE deployment. This is a common directory structure for managing multiple TFE deployments:

    .
    └── environments
        ├── production
        │   ├── backend.tf
        │   ├── main.tf
        │   ├── outputs.tf
        │   ├── terraform.tfvars
        │   └── variables.tf
        └── sandbox
            ├── backend.tf
            ├── main.tf
            ├── outputs.tf
            ├── terraform.tfvars
            └── variables.tf
    

    📝 Note: in this example, the user will have two separate TFE deployments; one for their sandbox environment, and one for their production environment. This is recommended, but not required.

  4. (Optional) Uncomment and update the GCS remote state backend configuration provided in the backend.tf file with your own custom values. While this step is highly recommended, it is technically not required to use a remote backend config for your TFE deployment.

  5. Populate your own custom values into the terraform.tfvars.example file that was provided, and remove the .example file extension such that the file is now named terraform.tfvars.

  6. Navigate to the directory of your newly created Terraform configuration for your TFE deployment, and run terraform init, terraform plan, and terraform apply.

  7. After your terraform apply finishes successfully, you can monitor the installation progress by connecting to your TFE gcp instance shell via SSH or gcp IAP and observing the meta data script(user_data) logs:

    Higher-level logs:

    tail -f /var/log/tfe-cloud-init.log
    

    Lower-level logs:

    sudo journalctl -u google-startup-scripts.service -f
    

    📝 Note: the -f argument is to follow the logs as they append in real-time, and is optional. You may remove the -f for a static view.

    The log files should display the following message after the cloud-init (user_data) script finishes successfully:

    [INFO] tfe_user_data script finished successfully!
    
  8. After the cloud-init (user_data) script finishes successfully, while still connected to the TFE CE instance shell, you can check the health status of TFE:

    cd /etc/tfe
    sudo docker compose exec terraform-enterprise tfe-health-check-status
    
  9. Follow the steps to here to create the TFE initial admin user.

  • the module includes outputs for the initial admin user token retrieval.

Docs

Below are links to docs pages related to deployment customizations as well as managing day 2 operations of your TFE instance.


Requirements

Name Version
terraform ~> 1.9
google ~> 5.39
google-beta ~> 5.39
random ~> 3.6

Providers

Name Version
google ~> 5.39
google-beta ~> 5.39
random ~> 3.6

Resources

Name Type
google-beta_google_project_service_identity.gcp_sa_cloud_sql resource
google-beta_google_sql_database_instance.tfe resource
google_compute_address.tfe_frontend_lb resource
google_compute_firewall.allow_https resource
google_compute_firewall.allow_iap resource
google_compute_firewall.allow_prometheus resource
google_compute_firewall.allow_ssh resource
google_compute_firewall.health_checks resource
google_compute_firewall.tfe_self resource
google_compute_forwarding_rule.tfe_frontend_lb resource
google_compute_global_address.postgres_private_ip resource
google_compute_health_check.tfe_auto_healing resource
google_compute_instance_template.tfe resource
google_compute_region_backend_service.tfe_backend_lb resource
google_compute_region_health_check.tfe_backend_lb resource
google_compute_region_instance_group_manager.tfe resource
google_dns_record_set.tfe resource
google_kms_crypto_key_iam_member.gcs_account resource
google_kms_crypto_key_iam_member.gcs_bucket resource
google_kms_crypto_key_iam_member.postgres resource
google_kms_crypto_key_iam_member.postgres_account resource
google_kms_crypto_key_iam_member.postgres_project resource
google_project_iam_member.stackdriver resource
google_redis_instance.tfe resource
google_secret_manager_secret_iam_member.ca_bundle resource
google_secret_manager_secret_iam_member.tfe_cert resource
google_secret_manager_secret_iam_member.tfe_encryption_password resource
google_secret_manager_secret_iam_member.tfe_license resource
google_secret_manager_secret_iam_member.tfe_privkey resource
google_service_account.tfe resource
google_service_account_key.tfe resource
google_service_networking_connection.postgres_endpoint resource
google_sql_database.tfe resource
google_sql_user.tfe resource
google_storage_bucket.tfe resource
google_storage_bucket_iam_member.tfe_bucket_object_admin resource
google_storage_bucket_iam_member.tfe_bucket_reader resource
random_id.gcs_bucket_suffix resource
random_id.postgres_suffix resource
google_client_config.default data source
google_compute_image.tfe data source
google_compute_network.vpc data source
google_compute_subnetwork.subnet data source
google_compute_zones.up data source
google_dns_managed_zone.tfe data source
google_kms_crypto_key.gcs_bucket data source
google_kms_crypto_key.postgres data source
google_kms_key_ring.gcs_bucket data source
google_kms_key_ring.postgres data source
google_secret_manager_secret_version.tfe_database_password_secret_id data source
google_storage_project_service_account.project data source

Inputs

Name Description Type Default Required
friendly_name_prefix Friendly name prefix used for uniquely naming resources. string n/a yes
network The VPC network to host the cluster in string n/a yes
project_id ID of GCP Project to create resources in. string n/a yes
region Region of GCP Project to create resources in. string n/a yes
subnet Existing VPC subnet for TFE instance(s) and optionally TFE frontend load balancer. string n/a yes
tfe_encryption_password_secret_id ID of Secrets Manager secret for TFE encryption password. string n/a yes
tfe_fqdn Fully qualified domain name of TFE instance. This name should resolve to the load balancer IP address and will be what clients use to access TFE. string n/a yes
tfe_license_secret_id ID of Secrets Manager secret for TFE license file. string n/a yes
tfe_tls_ca_bundle_secret_id ID of Secrets Manager secret for private/custom TLS Certificate Authority (CA) bundle in PEM format. Secret must be stored as a base64-encoded string. string n/a yes
tfe_tls_cert_secret_id ID of Secrets Manager secret for TFE TLS certificate in PEM format. Secret must be stored as a base64-encoded string. string n/a yes
tfe_tls_privkey_secret_id ID of Secrets Manager secret for TFE TLS private key in PEM format. Secret must be stored as a base64-encoded string. string n/a yes
cidr_ingress_https_allow CIDR ranges to allow HTTPS traffic inbound to TFE instance(s). list(string) [ "0.0.0.0/0"] no
cidr_ingress_ssh_allow CIDR ranges to allow SSH traffic inbound to TFE instance(s) via IAP tunnel. list(string) [ "10.0.0.0/16"] no
cloud_dns_managed_zone Zone name to create TFE Cloud DNS record in if create_cloud_dns_record is set to true. string null no
common_labels Common labels to apply to GCP resources. map(string) {} no
create_cloud_dns_record Boolean to create Google Cloud DNS record for tfe_fqdn resolving to load balancer IP. cloud_dns_managed_zone is required when true. bool false no
custom_fluent_bit_config Custom Fluent Bit configuration for log forwarding. Only valid when tfe_log_forwarding_enabled is true and log_fwd_destination_type is custom. string null no
disk_size_gb Size in Gigabytes of root disk of TFE instance(s). number 50 no
docker_version Full Version version string for OS choice while installing Docker to install on TFE GCP instances. string "26.1.4-1" no
enable_active_active Boolean indicating whether to deploy TFE in the Active:Active architecture using external Redis. bool false no
enable_iap (Optional bool) Enable https://cloud.google.com/iap/docs/using-tcp-forwarding#console, defaults to true. bool true no
extra_no_proxy A comma-separated string of hostnames or IP addresses to configure for TFE no_proxy list. string "" no
gcs_bucket_key_name Name of KMS Key to use for gcs bucket encryption. string null no
gcs_bucket_keyring_name Name of KMS Key Ring that contains KMS key to use for gcs bucket encryption. Geographic location of key ring must match gcs_bucket_location. string null no
gcs_bucket_location [Optional one of ca,us, europe, asia,au,nam-eur-asia1] Location for GCS bucket. All regions are multi-region https://cloud.google.com/kms/docs/locations string "us" no
gcs_force_destroy Boolean indicating whether to allow force destroying the gcs bucket. If set to true the gcs bucket can be destroyed if it is not empty. bool false no
http_proxy Proxy address to configure for TFE to use for outbound connections. string "" no
image_name VM image for TFE instance(s). string "ubuntu-2404-noble-amd64-v20240607" no
image_project ID of project in which the resource belongs. string "ubuntu-os-cloud" no
initial_delay_sec The number of seconds that the managed instance group waits before it applies autohealing policies to new instances or recently recreated instances number 1200 no
instance_count Target size of Managed Instance Group for number of TFE instances to run. Only specify a value greater than 1 if enable_active_active is set to true. number 1 no
is_secondary_region Boolean indicating whether this TFE deployment is in the 'primary' region or 'secondary' region. bool false no
load_balancing_scheme Determines whether load balancer is internal-facing or external-facing. string "external" no
log_fwd_destination_type Type of log forwarding destination. Valid values are stackdriver or custom. string "stackdriver" no
machine_type (Optional string) Size of machine to create. Default n2-standard-4 from https://cloud.google.com/compute/docs/machine-resource. string "n2-standard-4" no
network_project_id ID of GCP Project where the existing VPC resides if it is different than the default project. string null no
postgres_availability_type Availability type of Cloud SQL PostgreSQL instance. string "REGIONAL" no
postgres_backup_start_time HH:MM time format indicating when daily automatic backups should run. string "00:00" no
postgres_disk_size Size in GB of PostgreSQL disk. number 50 no
postgres_extra_params Parameter keyword/value pairs to support additional PostgreSQL parameters that may be necessary. string "sslmode=require" no
postgres_key_name Name of KMS Key to use for Cloud SQL for PostgreSQL encryption. string null no
postgres_keyring_name Name of KMS Key Ring that contains KMS key to use for Cloud SQL for PostgreSQL database encryption. Geographic location of key ring must match location of database instance. string null no
postgres_machine_type Machine size of Cloud SQL PostgreSQL instance. string "db-custom-4-16384" no
postgres_version PostgreSQL version to use. string "POSTGRES_15" no
redis_auth_enabled Boolean to enable authentication on Redis instance. bool true no
redis_connect_mode Network connection mode for Redis instance. string "PRIVATE_SERVICE_ACCESS" no
redis_memory_size_gb The size of the Redis instance in GiB. number 6 no
redis_tier The service tier of the Redis instance. Set to STANDARD_HA for high availability. string "STANDARD_HA" no
redis_transit_encryption_mode Boolean to enable TLS for Redis instance. string "DISABLED" no
redis_version The version of Redis software. string "REDIS_6_X" no
tfe_capacity_concurrency Maximum number of concurrent Terraform runs to allow on a TFE node. number 10 no
tfe_capacity_cpu Maxium number of CPU cores that a Terraform run is allowed to consume in TFE. Set to 0 for no limit. number 0 no
tfe_capacity_memory Maximum amount of memory (in MiB) that a Terraform run is allowed to consume in TFE. number 2048 no
tfe_database_password_secret_id ID of secret stored in GCP Secrets Manager containing TFE install secrets. string null no
tfe_hairpin_addressing Boolean to enable hairpin addressing for Layer 4 load balancer with loopback prevention. Only valid when lb_is_internal is false, as hairpin addressing will automatically be enabled when lb_is_internal is true, regardless of this setting. bool true no
tfe_iact_subnets Comma-separated list of subnets in CIDR notation that are allowed to retrieve the initial admin creation token via the API, or GUI string "" no
tfe_iact_time_limit Number of minutes that the initial admin creation token can be retrieved via the API after the application starts. Defaults to 60 string "60" no
tfe_iact_trusted_proxies Comma-separated list of subnets in CIDR notation that are allowed to retrieve the initial admin creation token via the API, or GUI string "" no
tfe_image_name Name of the TFE container image. Only set this if you are hosting the TFE container image in your own custom repository. string "hashicorp/terraform-enterprise" no
tfe_image_repository_password Pasword for container registry where TFE container image is hosted. Leave null if using the default TFE registry as the default password is the TFE license file. string null no
tfe_image_repository_url Repository for the TFE image. Only set this if you are hosting the TFE container image in your own custom repository. string "images.releases.hashicorp.com" no
tfe_image_repository_username Username for container registry where TFE container image is hosted. string "terraform" no
tfe_image_tag Tag for the TFE image. This represents the version of TFE to deploy. string "v202402-2" no
tfe_license_reporting_opt_out Boolean to opt out of license reporting. bool false no
tfe_log_forwarding_enabled Boolean to enable TFE log forwarding feature. bool false no
tfe_metrics_enable Boolean to enable metrics. bool false no
tfe_metrics_http_port HTTP port for TFE metrics scrape. number 9090 no
tfe_metrics_https_port HTTPS port for TFE metrics scrape. number 9091 no
tfe_mounted_disk_path (Optional) Path for mounted disk source, defaults to /opt/hashicorp/terraform-enterprise string "/opt/hashicorp/terraform-enterprise/data" no
tfe_operational_mode Operational mode for TFE. string "active-active" no
tfe_run_pipeline_docker_network Docker network where the containers that execute Terraform runs will be created. The network must already exist, it will not be created automatically. Leave null to use the default network. string null no
tfe_run_pipeline_image Name of the Docker image to use for the run pipeline driver. string null no
tfe_run_pipeline_image_ecr_repo_name Name of the ECR repository containing your custom TFE run pipeline image. string null no
tfe_tls_enforce Boolean to enforce TLS. bool false no
tfe_user_data_template (optional) File name for user_data_template.sh.tpl file in ./templates folder no path required string "tfe_user_data.sh.tpl" no
tfe_vault_disable_mlock Boolean to disable mlock for internal Vault. bool false no
verbose_template [Optional bool] Enables the user_data template to be output in full for debug and review purposes. bool false no

Outputs

Name Description
gcp_db_instance_ip Cloud SQL DB instance IP.
gcs_bucket_name Name of TFE gcs bucket.
google_sql_database_instance_id ID of Cloud SQL DB instance.
lb_ip_address IP Address of the Load Balancer.
tfe_fqdn tfe_fqdn input.
tfe_initial_user_url Terraform-Enterprise URL create initial admin user based on the tfe_fqdn input, and tfe_iact_subnets is set
tfe_retrieve_iact Terraform-Enterprise URL to retrieve initial user token based on tfe_fqdn input, and tfe_iact_subnets is set
url URL of TFE application based on tfe_fqdn input.
user_data_template n/a
Related Projects