Skip to content

A Terraform module for provisioning and installing Boundary Enterprise Controller on Azure virtual machines as described in HashiCorp Validated Designs

License

Notifications You must be signed in to change notification settings

hashicorp/terraform-azurerm-boundary-enterprise-controller-hvd

Boundary Enterprise Controller HVD on Azure VM

Terraform module aligned with HashiCorp Validated Designs (HVD) to deploy Boundary Enterprise Controller(s) on Microsoft Azure using Azure Virtual Machines. This module is designed to work with the complimentary Boundary Enterprise Worker HVD on Azure VM module.

Prerequisites

General

  • Terraform CLI >= 1.9 installed on workstation
  • Azure subscription that Boundary Controller will be hosted in with admin-like permissions to provision resources in via Terraform CLI
  • Azure Blob Storage Account for AzureRM Remote State backend is recommended but not required
  • Git CLI and Visual Studio Code editor installed on workstation are recommended but not required

Networking

  • Azure VNet ID
  • Load balancer subnet ID for cluster lb. API LB will also need one if it is to be internal
  • Load balancer static IP address for Cluster LB and for API if api load balancer is to be internal
  • Controller subnet ID with service endpoints enabled for Microsoft.key_vault, and Microsoft.Sql
  • Database subnet ID with service delegation configured for Microsoft.DBforPostgreSQL/flexibleServers for join action (Microsoft.Network/virtualNetworks/subnets/join/action)
  • Ability to create private endpoints on the database subnets
  • Network Security Group (NSG)/firewall rules:
    • Allow TCP/443 ingress from Boundary user clients access subnets to load balancer subnet (if api load balancer is internal) or VM subnet (if load balancer is external)
    • Allow TCP/9201 ingress from subnets that will contain Boundary Ingress Worker(s)
    • Allow TCP/443 ingress from load balancer subnet to VM subnet (if load balancer is internal)
    • Allow TCP/5432 ingress from Controller subnet to database subnet (for PostgreSQL traffic)

Key Vault

Secrets

  • Boundary license - raw contents of Boundary license file (*.hclic) (ex: cat boundary.hclic)

  • Boundary database password - used to create PostgreSQL Flexible Server; randomly generate this yourself (avoid the $ character as Azure PostgreSQL Flexible Server does not like it), fetched from within the module via data source.

  • Boundary TLS certificate - file in PEM format, base64-encoded into a string, and stored as a plaintext secret.

  • Boundary TLS private key - file in PEM format, base64-encoded into a string, and stored as a plaintext secret.

  • Boundary custom CA bundle - file in PEM format, base64-encoded into a string, and stored as a plaintext secret.

    📝 Note: see the Boundary cert rotation docs for instructions on how to base64-encode the certificates with proper formatting.

Keys

This module supports creating the necessary Key Vaults, Controller and Worker and associated keys, Root, Recovery, and Worker with the variables, create_boundary_controller_key_vault, create_boundary_worker_key_vault, create_boundary_controller_root_key, create_boundary_worker_key_vault, and create_boundary_worker_key. If due to security policy KMS keys have to be provisioned outside this module, these variables can be set to false and the the key vault name for the controller and worker key vaults, the resource group names, and the key names can be provided with these variables: boundary_controller_key_vault_rg_name, boundary_controller_key_vault_name, root_key_name, recovery_key_name, boundary_worker_key_vault_rg_name, boundary_worker_key_vault_name, and worker_key_name.

📝 Note: The Worker Key should be in a separate Key Vault than the Root and Recovery Keys, as Azure IAM does not allow individual permissions to Keys, only to Key Vaults, and the Worker(s) should never have access to the Root and Recovery Keys.

Compute

One of the following mechanisms for shell access to Boundary EC2 instances:

  • A mechanism for shell access to Azure Linux VMs within VMSS (SSH key pair, bastion host, username/password, etc.)

Usage

  1. Create/configure/validate the applicable prerequisites.

  2. Nested within the examples directory are subdirectories that contain ready-made Terraform configurations of example scenarios for how to call and deploy this module. To get started, choose an example scenario. If you are not sure which example scenario to start with, then we recommend starting with the default example.

  3. Copy all of the Terraform files from your example scenario of choice into a new destination directory to create your root Terraform configuration that will manage your Boundary deployment. If you are not sure where to create this new directory, it is common for us to see users create an environments/ directory at the root of this repo, and then a subdirectory for each Boundary instance deployment, like so:

    .
    └── 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 Boundary deployments; one for their sandbox environment, and one for their production environment. This is recommended, but not required.

  4. (Optional) Uncomment and update the AzureRM 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 Boundary 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 Boundary Controller deployment, and run terraform init, terraform plan, and terraform apply.

  7. After the terraform apply finishes successfully, you can monitor the install progress by connecting to the VM in your Boundary Controller Virtual Machine Scaleset (VMSS) via SSH and observing the cloud-init (user_data) logs:

    Higher-level logs:

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

    Lower-level logs:

    journalctl -xu cloud-final -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] boundary_custom_data script finished successfully!
  8. Once the cloud-init script finishes successfully, while still connected to the VM via SSH you can check the status of the boundary service:

    sudo systemctl status boundary
  9. After the Boundary Controller is deployed the Boundary system will be partially initialized. To complete the initialization process and setup an initial auth method, username and password, please use the terraform-boundary-bootstrap-hvd module

  10. Use the terraform-azurerm-boundary-worker-hvd module to deploy ingress, egress, etc workers as needed.

Docs

Below are links to docs pages related to deployment customizations and day 2 operations of your Boundary Controller instance.

Module support

This open source software is maintained by the HashiCorp Technical Field Organization, independently of our enterprise products. While our Support Engineering team provides dedicated support for our enterprise offerings, this open source software is not included.

  • For help using this open source software, please engage your account team.
  • To report bugs/issues with this open source software, please open them directly against this code repository using the GitHub issues feature.

Please note that there is no official Service Level Agreement (SLA) for support of this software as a HashiCorp customer. This software falls under the definition of Community Software/Versions in your Agreement. We appreciate your understanding and collaboration in improving our open source projects.

Requirements

Name Version
terraform >= 1.9
azurerm ~> 3.101

Providers

Name Version
azurerm ~> 3.101

Resources

Name Type
azurerm_dns_a_record.boundary resource
azurerm_key_vault.boundary_controller resource
azurerm_key_vault.boundary_worker resource
azurerm_key_vault_access_policy.admin_controller resource
azurerm_key_vault_access_policy.admin_worker resource
azurerm_key_vault_access_policy.boundary_kv_reader resource
azurerm_key_vault_access_policy.controller_key_vault_controller resource
azurerm_key_vault_access_policy.postgres_cmk resource
azurerm_key_vault_access_policy.worker_key_vault_controller resource
azurerm_key_vault_key.recovery resource
azurerm_key_vault_key.root resource
azurerm_key_vault_key.worker resource
azurerm_lb.boundary_api resource
azurerm_lb.boundary_cluster resource
azurerm_lb_backend_address_pool.boundary_api resource
azurerm_lb_backend_address_pool.boundary_cluster resource
azurerm_lb_probe.boundary_api resource
azurerm_lb_probe.boundary_cluster resource
azurerm_lb_rule.boundary_api resource
azurerm_lb_rule.boundary_cluster resource
azurerm_linux_virtual_machine_scale_set.boundary resource
azurerm_postgresql_flexible_server.boundary resource
azurerm_postgresql_flexible_server_configuration.boundary resource
azurerm_postgresql_flexible_server_database.boundary resource
azurerm_private_dns_a_record.boundary resource
azurerm_private_dns_zone.postgres resource
azurerm_private_dns_zone_virtual_network_link.boundary resource
azurerm_private_dns_zone_virtual_network_link.postgres resource
azurerm_public_ip.boundary_api_lb resource
azurerm_resource_group.boundary resource
azurerm_role_assignment.boundary_kv_reader resource
azurerm_role_assignment.boundary_vmss_disk_encryption_set_reader resource
azurerm_user_assigned_identity.boundary resource
azurerm_user_assigned_identity.postgres resource
azurerm_client_config.current data source
azurerm_disk_encryption_set.vmss data source
azurerm_dns_zone.boundary data source
azurerm_image.custom data source
azurerm_key_vault.boundary_controller data source
azurerm_key_vault.boundary_worker data source
azurerm_key_vault.prereqs data source
azurerm_key_vault_key.recovery data source
azurerm_key_vault_key.root data source
azurerm_key_vault_key.worker data source
azurerm_key_vault_secret.boundary_database_password data source
azurerm_private_dns_zone.boundary data source

Inputs

Name Description Type Default Required
additional_package_names List of additional repository package names to install set(string) [] no
api_lb_is_internal Boolean to create an internal or external Azure Load Balancer for boundary. bool false no
api_lb_private_ip Private IP address for internal Azure Load Balancer. Only valid when lb_is_internal is true. string null no
api_lb_subnet_id Subnet ID for Boundary API load balancer. string null no
availability_zones List of Azure Availability Zones to spread boundary resources across. set(string)
[
"1",
"2",
"3"
]
no
boundary_controller_key_vault_name Name of the existing Azure Key Vault to use for Boundary Controller keys. string null no
boundary_controller_key_vault_rg_name Name of the existing Resource Group containing the Azure Key Vault to use for Boundary Controller keys. string null no
boundary_database_name PostgreSQL database name for boundary. string "boundary" no
boundary_database_paramaters PostgreSQL server parameters for the connection URI. Used to configure the PostgreSQL connection. string "sslmode=require" no
boundary_database_password_key_vault_secret_name Name of the secret in the Key Vault that contains the boundary database password. string n/a yes
boundary_fqdn Fully qualified domain name of boundary instance. This name should resolve to the load balancer IP address and will be what clients use to access boundary. string n/a yes
boundary_license_key_vault_secret_id ID of Key Vault secret containing boundary license. string n/a yes
boundary_license_reporting_opt_out Boolean to opt out of license reporting. bool false no
boundary_tls_ca_bundle_key_vault_secret_id ID of Key Vault secret containing boundary TLS custom CA bundle. string n/a yes
boundary_tls_cert_key_vault_secret_id ID of Key Vault secret containing boundary TLS certificate. string n/a yes
boundary_tls_disable Boolean to disable TLS for boundary. bool false no
boundary_tls_privkey_key_vault_secret_id ID of Key Vault secret containing boundary TLS private key. string n/a yes
boundary_version Version of Boundary to install. string "0.17.1+ent" no
boundary_worker_key_vault_name Name of the existing Azure Key Vault to use for Boundary Worker keys. string null no
boundary_worker_key_vault_rg_name Name of the existing Resource Group containing the Azure Key Vault to use for Boundary Worker keys. string null no
cluster_lb_private_ip Private IP address for internal Azure Load Balancer. string n/a yes
cluster_lb_subnet_id Subnet ID for Boundary 1ster load balancer. string null no
common_tags Map of common tags for taggable Azure resources. map(string) {} no
controller_subnet_id Subnet ID for controller VMs. string n/a yes
create_boundary_controller_key_vault Boolean to create a Key Vault for Boundary Controller. bool true no
create_boundary_controller_recovery_key Boolean to create a recovery key in the Boundary Controller Key Vault. bool true no
create_boundary_controller_root_key Boolean to create a root key in the Boundary Controller Key Vault. bool true no
create_boundary_private_dns_record Boolean to create a DNS record for boundary in a private Azure DNS zone. private_dns_zone_name must also be provided when true. bool false no
create_boundary_public_dns_record Boolean to create a DNS record for boundary in a public Azure DNS zone. public_dns_zone_name must also be provided when true. bool false no
create_boundary_worker_key Boolean to create the worker key. bool true no
create_boundary_worker_key_vault Boolean to create a Key Vault for Boundary Worker. bool true no
create_postgres_private_endpoint Boolean to create a private endpoint and private DNS zone for PostgreSQL Flexible Server. bool true no
create_resource_group Boolean to create a new Resource Group for this boundary deployment. bool true no
db_subnet_id Subnet ID for PostgreSQL database. string n/a yes
friendly_name_prefix Friendly name prefix for uniquely naming Azure resources. string n/a yes
is_govcloud_region Boolean indicating whether this boundary deployment is in an Azure Government Cloud region. bool false no
key_vault_cidr_allow_list List of CIDR blocks to allow access to the Key Vault. This should be the public IP address of the machine running the Terraform deployment. list(string) [] no
location Azure region for this boundary deployment. string n/a yes
postgres_administrator_login Username for administrator login of PostreSQL database. string "boundary" no
postgres_backup_retention_days Number of days to retain backups of PostgreSQL Flexible Server. number 35 no
postgres_cmk_key_vault_id ID of the Key Vault containing the customer-managed key (CMK) for encrypting the PostgreSQL Flexible Server database. string null no
postgres_cmk_key_vault_key_id ID of the Key Vault key to use for customer-managed key (CMK) encryption of PostgreSQL Flexible Server database. string null no
postgres_create_mode Determines if the PostgreSQL Flexible Server is being created as a new server or as a replica. string "Default" no
postgres_enable_high_availability Boolean to enable ZoneRedundant high availability with PostgreSQL database. bool false no
postgres_geo_backup_key_vault_key_id ID of the Key Vault key to use for customer-managed key (CMK) encryption of PostgreSQL Flexible Server geo-redundant backups. This key must be in the same region as the geo-redundant backup. string null no
postgres_geo_backup_user_assigned_identity_id ID of the User-Assigned Identity to use for customer-managed key (CMK) encryption of PostgreSQL Flexible Server geo-redundant backups. This identity must have 'Get', 'WrapKey', and 'UnwrapKey' permissions to the Key Vault. string null no
postgres_geo_redundant_backup_enabled Boolean to enable PostreSQL geo-redundant backup configuration in paired Azure region. bool true no
postgres_maintenance_window Map of maintenance window settings for PostgreSQL Flexible Server. map(number)
{
"day_of_week": 0,
"start_hour": 0,
"start_minute": 0
}
no
postgres_primary_availability_zone Number for the availability zone for the primary PostgreSQL Flexible Server instance to reside in. number 1 no
postgres_secondary_availability_zone Number for the availability zone for the standby PostgreSQL Flexible Server instance to reside in. number 2 no
postgres_sku PostgreSQL database SKU. string "GP_Standard_D4ds_v4" no
postgres_source_server_id ID of the source PostgreSQL Flexible Server to replicate from. Only valid when is_secondary_region is true and postgres_create_mode is Replica. string null no
postgres_storage_mb Storage capacity of PostgreSQL Flexible Server (unit is megabytes). number 65536 no
postgres_version PostgreSQL database version. number 16 no
prereqs_key_vault_id ID of the 'prereqs' Key Vault to use for prereqs boundary deployment. string n/a yes
prereqs_key_vault_name Name of the 'prereqs' Key Vault to use for prereqs boundary deployment. string n/a yes
prereqs_key_vault_rg_name Name of the Resource Group where the 'prereqs' Key Vault resides. string n/a yes
private_dns_zone_name Name of existing private Azure DNS zone to create DNS record in. Required when create_boundary_private_dns_record is true. string null no
private_dns_zone_rg Name of Resource Group where private_dns_zone_name resides. Required when create_boundary_private_dns_record is true. string null no
public_dns_zone_name Name of existing public Azure DNS zone to create DNS record in. Required when create_boundary_public_dns_record is true. string null no
public_dns_zone_rg Name of Resource Group where public_dns_zone_name resides. Required when create_boundary_public_dns_record is true. string null no
recovery_key_name Name of the existing recovery key in the Boundary Controller Key Vault. string null no
resource_group_name Name of Resource Group to create. string "boundary-controller-rg" no
root_key_name Name of the existing root key in the Boundary Controller Key Vault. string null no
vm_admin_username Admin username for VMs in VMSS. string "boundaryadmin" no
vm_custom_image_name Name of custom VM image to use for VMSS. If not using a custom image, leave this blank. string null no
vm_custom_image_rg_name Resource Group name where the custom VM image resides. Only valid if vm_custom_image_name is not null. string null no
vm_disk_encryption_set_name Name of the Disk Encryption Set to use for VMSS. string null no
vm_disk_encryption_set_rg Name of the Resource Group where the Disk Encryption Set to use for VMSS exists. string null no
vm_enable_boot_diagnostics Boolean to enable boot diagnostics for VMSS. bool false no
vm_image_offer Offer of the VM image. string "0001-com-ubuntu-server-jammy" no
vm_image_publisher Publisher of the VM image. string "Canonical" no
vm_image_sku SKU of the VM image. string "22_04-lts-gen2" no
vm_image_version Version of the VM image. string "latest" no
vm_sku SKU for VM size for the VMSS. string "Standard_D2s_v5" no
vm_ssh_public_key SSH public key for VMs in VMSS. string null no
vmss_availability_zones List of Azure Availability Zones to spread the VMSS VM resources across. set(string)
[
"1",
"2",
"3"
]
no
vmss_vm_count Number of VM instances in the VMSS. number 1 no
vnet_id VNet ID where boundary resources will reside. string n/a yes
worker_key_name Name of the existing worker key in the Boundary Worker Key Vault. string null no
worker_subnet_id Subnet ID for worker VMs. string n/a yes

Outputs

Name Description
boundary_controller_cluster_lb_private_ip Private IP address of the Boundary Cluster Load Balancer.
boundary_database_host FQDN and port of PostgreSQL Flexible Server.
boundary_database_name Name of PostgreSQL Flexible Server database.
created_boundary_controller_key_vault_name Name of the created Boundary Controller Key Vault.
created_boundary_recovery_key_name Name of the created Boundary Recovery Key.
created_boundary_root_key_name Name of the created Boundary Root Key.
created_boundary_worker_key_name Name of the created Boundary Worker Key.
created_boundary_worker_key_vault_name Name of the created Boundary Worker Key Vault.
provided_boundary_controller_key_vault_name Name of the provided Boundary Controller Key Vault.
provided_boundary_recovery_key_name Name of the provided Boundary Recovery Key.
provided_boundary_root_key_name Name of the provided Boundary Root Key.
provided_boundary_worker_key_name Name of the provided Boundary Worker Key.
provided_boundary_worker_key_vault_name Name of the provided Boundary Worker Key Vault.
resource_group_name Name of the Resource Group.
url URL of Boundary Controller based on boundary_fqdn input.

About

A Terraform module for provisioning and installing Boundary Enterprise Controller on Azure virtual machines as described in HashiCorp Validated Designs

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published