Terraform module aligned with HashiCorp Validated Designs (HVD) to deploy Boundary Enterprise Controller(s) on Amazon Web Services (AWS) using EC2 instances. This module is designed to work with the complimentary Boundary Enterprise Worker HVD on AWS EC2 module.
This diagram shows a Boundary deployment with one controller and two sets of Boundary Workers, one for ingress and another for egress. Please review Boundary deployment customizations doc to understand different deployment settings for the Boundary deployment.
- Terraform CLI
>= 1.9installed on workstations. GitCLI and Visual Studio Code editor installed on workstations are strongly recommended.- AWS account that Boundary will be hosted in with permissions to provision these resources via Terraform CLI.
- (Optional) AWS S3 bucket for S3 Remote State backend that will solely be used to stand up the Boundary infrastructure via Terraform CLI (Community Edition).
- AWS VPC ID and the following subnets:
- Load balancer subnet IDs (can be the same as EC2 subnets if desirable).
- EC2 (controller) subnet IDs.
- RDS (database) subnet IDs.
- (Optional) KMS VPC Endpoint configured within VPC.
- (Optional) AWS Route53 Hosted Zone for Boundary DNS record creation.
- Security Groups:
- This module will create the necessary Security Groups and attach them to the applicable resources.
- Ensure the Boundary Network connectivity are met.
- Boundary license file - raw contents of Boundary license file (
*.hclic) (ex:cat boundary.hclic) - RDS (PostgreSQL) database password - used to create AWS Aurora Database; randomly generate this yourself, 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 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.
📝 Note: see the Boundary cert rotation docs for instructions on how to base64-encode the certificates with proper formatting.
One of the following mechanisms for shell access to Boundary EC2 instances:
- EC2 SSH Key Pair.
- Ability to enable AWS SSM (this module supports this via a boolean input variable).
This module supports creating the necessary KMS keys, Root, Recovery, Worker and BSR with the variables: create_root_kms_key, create_recovery_kms_key, create_worker_kms_key and if session recording is to be enabled, create_bsr_kms_key. If due to security policy KMS keys have to be provisioned outside this module, these variables can be set to false and the arn of each of the existing KMS keys can be provided with these variables, root_kms_key_arn, recovery_kms_key_arn, worker_kms_key_arn and if session recording is to be enabled bsr_kms_key_arn. Ensure that these already created KMS keys have a KMS policy that enables IAM authorization as this module will create IAM polices that grant access to these KMS keys.
-
Create/configure/validate the applicable prerequisites.
-
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.
-
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
sandboxenvironment, and one for theirproductionenvironment. This is recommended, but not required. -
(Optional) Uncomment and update the S3 remote state backend configuration provided in the
backend.tffile 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. -
Populate your own custom values into the
terraform.tfvars.examplefile that was provided, and remove the.examplefile extension such that the file is now namedterraform.tfvars. -
Navigate to the directory of your newly created Terraform configuration for your Boundary Controller deployment, and run
terraform init,terraform plan, andterraform apply. -
After your
terraform applyfinishes successfully, you can monitor the installation progress by connecting to your Boundary EC2 instance shell via SSH or AWS SSM 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
-fargument is to follow the logs as they append in real-time, and is optional. You may remove the-ffor 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! -
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
-
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
-
Use the terraform-aws-boundary-worker-hvd module to deploy ingress, egress, etc workers as needed.
Below are links to docs pages related to deployment customizations and day 2 operations of your Boundary Controller instance.
- Deployment Customizations
- Upgrading Boundary version
- Rotating Boundary TLS/SSL certificates
- Updating/modifying Boundary configuration settings
- Authenticate to Boundary Cluster with Boundary CLI
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.
| Name | Version |
|---|---|
| terraform | >= 1.9 |
| aws | >= 5.51.0 |
| Name | Version |
|---|---|
| aws | >= 5.51.0 |
| 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 (private) API load balancer. The api_lb_subnet_ids must be private subnets if this is set to true. |
bool |
true |
no |
| api_lb_subnet_ids | List of subnet IDs to use for the API load balancer. If the load balancer is external, then these should be public subnets. | list(string) |
n/a | yes |
| asg_health_check_grace_period | The amount of time to wait for a new Boundary EC2 instance to become healthy. If this threshold is breached, the ASG will terminate the instance and launch a new one. | number |
900 |
no |
| asg_instance_count | Desired number of Boundary EC2 instances to run in Autoscaling Group. Leave at 1 unless Active/Active is enabled. |
number |
1 |
no |
| asg_max_size | Max number of Boundary EC2 instances to run in Autoscaling Group. | number |
3 |
no |
| boundary_database_name | Name of Boundary database to create within RDS global cluster. | string |
"boundary" |
no |
| boundary_database_parameters | PostgreSQL server parameters for the connection URI. Used to configure the PostgreSQL connection. | string |
"sslmode=require" |
no |
| boundary_database_password_secret_arn | ARN of AWS Secrets Manager secret for the Boundary RDS Aurora (PostgreSQL) database password. | string |
n/a | yes |
| boundary_database_user | Username for Boundary RDS database cluster. | string |
"boundary" |
no |
| 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_reporting_opt_out | Boolean to opt out of license reporting. | bool |
false |
no |
| boundary_license_secret_arn | ARN of AWS Secrets Manager secret for Boundary license file. | string |
null |
no |
| boundary_session_recording_s3_kms_key_arn | ARN of KMS customer managed key (CMK) to encrypt Boundary Session Recording Bucket with. | string |
null |
no |
| boundary_tls_ca_bundle_secret_arn | ARN of AWS 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 |
| boundary_tls_cert_secret_arn | ARN of AWS Secrets Manager secret for Boundary TLS certificate in PEM format. Secret must be stored as a base64-encoded string. | string |
null |
no |
| boundary_tls_disable | Boolean to disable TLS for boundary. | bool |
false |
no |
| boundary_tls_privkey_secret_arn | ARN of AWS Secrets Manager secret for Boundary TLS private key in PEM format. Secret must be stored as a base64-encoded string. | string |
null |
no |
| boundary_version | Version of Boundary to install. | string |
"0.17.1+ent" |
no |
| bsr_kms_key_arn | ARN of KMS key to use for Boundary bsr. | string |
null |
no |
| cidr_allow_egress_ec2_http | List of destination CIDR ranges to allow TCP/80 egress from Boundary EC2 instances. | list(string) |
[ |
no |
| cidr_allow_egress_ec2_https | List of destination CIDR ranges to allow TCP/443 egress from Boundary EC2 instances. | list(string) |
[ |
no |
| cidr_allow_ingress_boundary_443 | List of CIDR ranges to allow ingress traffic on port 443 to Load Balancer server. | list(string) |
[ |
no |
| cidr_allow_ingress_boundary_9201 | List of CIDR ranges to allow ingress traffic on port 9201 to Controllers. | list(string) |
null |
no |
| cidr_allow_ingress_ec2_ssh | List of CIDR ranges to allow SSH ingress to Boundary EC2 instance (i.e. bastion IP, client/workstation IP, etc.). | list(string) |
[] |
no |
| cluster_lb_subnet_ids | List of subnet IDs to use for the Cluster load balancer. If the load balancer is external, then these should be public subnets. | list(string) |
n/a | yes |
| common_tags | Map of common tags for taggable AWS resources. | map(string) |
{} |
no |
| controller_subnet_ids | List of subnet IDs to use for the EC2 instance. Private subnets is the best practice here. | list(string) |
n/a | yes |
| create_bsr_kms_key | Boolean to create a KMS customer managed key (CMK) for Boundary Session Recording. | bool |
false |
no |
| create_lb | Boolean to create an AWS Network Load Balancer for boundary. | bool |
true |
no |
| create_recovery_kms_key | Boolean to create a KMS customer managed key (CMK) for Boundary Recovery. | bool |
true |
no |
| create_root_kms_key | Boolean to create a KMS customer managed key (CMK) for Boundary Root. | bool |
true |
no |
| create_route53_boundary_dns_record | Boolean to create Route53 Alias Record for boundary_hostname resolving to Load Balancer DNS name. If true, route53_hosted_zone_boundary is also required. |
bool |
false |
no |
| create_worker_kms_key | Boolean to create a KMS customer managed key (CMK) for Boundary Worker. | bool |
true |
no |
| ebs_iops | The amount of IOPS to provision for a gp3 volume. Must be at least 3000. |
number |
3000 |
no |
| ebs_is_encrypted | Boolean for encrypting the root block device of the Boundary EC2 instance(s). | bool |
false |
no |
| ebs_kms_key_arn | ARN of KMS key to encrypt EC2 EBS volumes. | string |
null |
no |
| ebs_throughput | The throughput to provision for a gp3 volume in MB/s. Must be at least 125 MB/s. |
number |
125 |
no |
| ebs_volume_size | The size (GB) of the root EBS volume for Boundary EC2 instances. Must be at least 50 GB. |
number |
50 |
no |
| ebs_volume_type | EBS volume type for Boundary EC2 instances. | string |
"gp3" |
no |
| ec2_allow_ssm | Boolean to attach the AmazonSSMManagedInstanceCore policy to the Boundary instance role, allowing the SSM agent (if present) to function. |
bool |
false |
no |
| ec2_ami_id | Custom AMI ID for Boundary EC2 Launch Template. If specified, value of os_distro must coincide with this custom AMI OS distro. |
string |
null |
no |
| ec2_instance_size | EC2 instance type for Boundary EC2 Launch Template. | string |
"m5.2xlarge" |
no |
| ec2_os_distro | Linux OS distribution for Boundary EC2 instance. Choose from amzn2, ubuntu, rhel, centos. |
string |
"ubuntu" |
no |
| ec2_ssh_key_pair | Name of existing SSH key pair to attach to Boundary EC2 instance. | string |
"" |
no |
| enable_session_recording | Boolean to enable session recording. | bool |
false |
no |
| friendly_name_prefix | Friendly name prefix used for uniquely naming AWS resources. | string |
n/a | yes |
| is_secondary_region | Boolean indicating whether this Boundary instance deployment is in the primary or secondary (replica) region. | bool |
false |
no |
| kms_bsr_cmk_alias | Alias for KMS customer managed key (CMK). | string |
"boundary-session-recording" |
no |
| kms_cmk_deletion_window | Duration in days to destroy the key after it is deleted. Must be between 7 and 30 days. | number |
7 |
no |
| kms_cmk_enable_key_rotation | Boolean to enable key rotation for the KMS customer managed key (CMK). | bool |
false |
no |
| kms_endpoint | AWS VPC endpoint for KMS service. | string |
"" |
no |
| kms_recovery_cmk_alias | Alias for KMS customer managed key (CMK). | string |
"boundary-recovery" |
no |
| kms_root_cmk_alias | Alias for KMS customer managed key (CMK). | string |
"boundary-root" |
no |
| kms_worker_cmk_alias | Alias for KMS customer managed key (CMK). | string |
"boundary-worker" |
no |
| rds_apply_immediately | Boolean to apply changes immediately to RDS cluster instance. | bool |
true |
no |
| rds_aurora_engine_mode | RDS Aurora database engine mode. | string |
"provisioned" |
no |
| rds_aurora_engine_version | Engine version of RDS Aurora PostgreSQL. | number |
16.2 |
no |
| rds_aurora_instance_class | Instance class of Aurora PostgreSQL database. | string |
"db.r7g.xlarge" |
no |
| rds_aurora_replica_count | Number of replica (reader) cluster instances to create within the RDS Aurora database cluster (within the same region). | number |
1 |
no |
| rds_availability_zones | List of AWS Availability Zones to spread Aurora database cluster instances across. Leave null and RDS will automatically assigns 3 AZs. | list(string) |
null |
no |
| rds_backup_retention_period | The number of days to retain backups for. Must be between 0 and 35. Must be greater than 0 if the database cluster is used as a source of a read replica cluster. | number |
35 |
no |
| rds_deletion_protection | Boolean to enable deletion protection for RDS global cluster. | bool |
false |
no |
| rds_force_destroy | Boolean to enable the removal of RDS database cluster members from RDS global cluster on destroy. | bool |
false |
no |
| rds_global_cluster_id | ID of RDS global cluster. Only required when is_secondary_region is true. |
string |
null |
no |
| rds_kms_key_arn | ARN of KMS key to encrypt Boundary RDS cluster with. | string |
null |
no |
| rds_parameter_group_family | Family of Aurora PostgreSQL DB Parameter Group. | string |
"aurora-postgresql16" |
no |
| rds_preferred_backup_window | Daily time range (UTC) for RDS backup to occur. Must not overlap with rds_preferred_maintenance_window. |
string |
"04:00-04:30" |
no |
| rds_preferred_maintenance_window | Window (UTC) to perform RDS database maintenance. Must not overlap with rds_preferred_backup_window. |
string |
"Sun:08:00-Sun:09:00" |
no |
| rds_replication_source_identifier | ARN of a source DB cluster or DB instance if this DB cluster is to be created as a Read Replica. Intended to be used by Aurora Replica in Secondary region. | string |
null |
no |
| rds_skip_final_snapshot | Boolean to enable RDS to take a final database snapshot before destroying. | bool |
false |
no |
| rds_source_region | Source region for RDS cross-region replication. Only required when is_secondary_region is true. |
string |
null |
no |
| rds_storage_encrypted | Boolean to encrypt RDS storage. | bool |
false |
no |
| rds_subnet_ids | List of subnet IDs to use for RDS database subnet group. Private subnets is the best practice here. | list(string) |
n/a | yes |
| recovery_kms_key_arn | ARN of KMS key to use for Boundary recovery. | string |
null |
no |
| root_kms_key_arn | ARN of KMS key to use for Boundary Root. | string |
null |
no |
| route53_boundary_hosted_zone_is_private | Boolean indicating if route53_boundary_hosted_zone_name is a private hosted zone. |
bool |
false |
no |
| route53_boundary_hosted_zone_name | Route53 Hosted Zone name to create boundary_hostname Alias record in. Required if create_boundary_alias_record is true. |
string |
null |
no |
| sg_allow_ingress_boundary_9201 | List of Security Groups to allow ingress traffic on port 9201 to Controllers. | list(string) |
[] |
no |
| vpc_id | ID of VPC where Boundary will be deployed. | string |
n/a | yes |
| worker_kms_key_arn | ARN of KMS key to use for Boundary worker. | string |
null |
no |
| Name | Description |
|---|---|
| api_lb_dns_name | DNS name of the Load Balancer for Boundary clients. |
| aurora_aws_rds_cluster_endpoint | Aurora DB cluster instance endpoint. |
| aurora_rds_cluster_arn | ARN of Aurora DB cluster. |
| aurora_rds_cluster_members | List of instances that are part of this Aurora DB Cluster. |
| aurora_rds_global_cluster_id | Aurora Global Database cluster identifier. |
| boundary_url | URL to access Boundary application based on value of boundary_fqdn input. |
| bsr_s3_bucket_arn | The arn of the S3 bucket for Boundary Session Recording. |
| cluster_lb_dns_name | DNS name of the Load Balancer for Boundary Ingress Workers. |
| created_kms_bsr_arn | The ARN of the created BSR KMS key |
| created_kms_recovery_arn | The ARN of the created recovery KMS key |
| created_kms_recovery_id | The ID of the created recovery KMS key |
| created_kms_root_arn | The ARN of the created root KMS key |
| created_kms_worker_arn | The ARN of the created worker KMS key |
| provided_kms_recovery_arn | The ARN of the provided recovery KMS key |
| provided_kms_recovery_id | The ID of the provided recovery KMS key |
| provided_kms_root_arn | The ARN of the provided root KMS key |
| provided_kms_worker_arn | The ARN of the provided BSR KMS key |
| provided_kms_worker_id | The ID of the provided worker KMS key |
