Terraform module aligned with HashiCorp Validated Designs (HVD) to deploy Nomad Enterprise on Amazon Web Services (AWS) using EC2 instances.
- Knowledge of Terraform and AWS
- Terraform CLI
>= 1.9installed on client/workstations - An AWS account with permissions to provision resources via Terraform
gitCLI and Visual Studio Code recommended on workstations
- AWS VPC ID and the following subnets:
- Subnets for the EC2 instances (compute)
📝 Note: Specify at least two subnets for high availability.
- This module will create security groups for EC2 instances.
- Define CIDR ranges for Nomad access, managed via the input variable
cidr_allow_ingress_nomad.
TLS certificates for Nomad have very specific requirements for server and client nodes. Nomad Agent Certificates Let's Encrypt Certificates can not be used for Nomad due to the Nomad specific requirements. This module has the option to not enable TLS with nomad_tls_enabled however this should never be used outside a lab environment.
- TLS certificate (e.g.
cert.pem) and private key (e.g.privkey.pem) for the Nomad web UI, in PEM format.- TLS private key must not be password-protected.
- TLS certificate authority (CA) bundle (e.g.
ca_bundle.pem) in PEM format. - These TLS files will be stored as secrets in AWS Secrets Manager.
📝 Store these TLS files as AWS Secrets Manager secrets to securely manage your certificates.
Gossip Encryption is required for this module. A Gossip Encryption Key can be generated by the Nomad CLI with nomad operator gossip keyring generate. Create this before deploying the module and store this in AWS Secrets Manager.
The following secrets must be stored in AWS Secrets Manager to bootstrap the Nomad Server deployment:
- Nomad license - text string used for Nomad Enterprise licensing - This is only needed for Nomad Server deployment
- Nomad Gossip Encryption Key - text string generated by
nomad operator gossip keyring generate- This is only needed for Nomad Server deployment - Nomad TLS certificate and private key - stored as base64-encoded PEM secrets in AWS Secrets Manager
📝 See the Nomad documentation for more details on securing these secrets in AWS Secrets Manager.
-
Configure the prerequisites.
-
In the
examplesdirectory, you’ll find subdirectories with ready-made Terraform configurations for deploying this module. Select an example that matches your use case, and copy its contents to a new directory.📝 Example structure for managing multiple Nomad deployments:
. └── environments ├── production │ ├── backend.tf │ ├── main.tf │ ├── outputs.tf │ ├── terraform.tfvars │ └── variables.tf └── sandbox ├── backend.tf ├── main.tf ├── outputs.tf ├── terraform.tfvars └── variables.tf📝 This example has two separate Nomad deployments: one for a
sandboxenvironment and one for aproductionenvironment. -
(Optional) If using S3 for remote state, configure the
backend.tffile with custom values. -
Update the
terraform.tfvarsfile with your custom values, then runterraform init,terraform plan, andterraform apply. -
After
terraform applycompletes successfully, connect to the Nomad EC2 instance shell using SSH or AWS SSM to monitor the cloud-init logs:Connecting to EC2 instance:
ssh -i /path/to/ec2_ssh_key_pair.pem ubuntu@<ec2-private-ip>
Viewing logs:
tail -f /var/log/nomad-cloud-init.log
-
Once the installation finishes, verify the health of the Nomad cluster by checking the Nomad Web UI or by running:
nomad server members
-
If
nomad_acl_enabledistruethe Nomad cluster will need to be bootstrapped with the commandnomad acl bootstrap. This will generate a bootstrap token that can be used to login to the CLI or UI.
Additional documentation for managing and customizing your Nomad deployment is available in the docs folder:
- Nomad Version Upgrades
- Nomad TLS Certificate Rotation
- Nomad Configuration Settings
- Nomad Deployment Customizations
During deployment the output of the user_data script can be traced in /var/log/cloud-init.log, /var/log/cloud-init-output.log and /var/log/vault-cloud-init.log due to set -xeuo pipefail in the default install-vault.sh.tpl
For help debugging cloud init and user data scripts
- https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html#userdata-linux
- https://cloudinit.readthedocs.io/en/latest/howto/debugging.html#cloud-init-ran-but-didn-t-do-what-i-want-it-to
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.0 |
| Name | Version |
|---|---|
| aws | ~> 5.0 |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| friendly_name_prefix | Friendly name prefix used for uniquely naming AWS resources. | string |
n/a | yes |
| instance_subnets | List of AWS subnet IDs for instance(s) to be deployed into. | list(string) |
n/a | yes |
| key_name | SSH key name, already registered in AWS, to use for instance access | string |
n/a | yes |
| nomad_client | Boolean to enable the Nomad client agent. | bool |
n/a | yes |
| nomad_datacenter | Specifies the data center of the local agent. A datacenter is an abstract grouping of clients within a region. Clients are not required to be in the same datacenter as the servers they are joined with, but do need to be in the same region. | string |
n/a | yes |
| nomad_server | Boolean to enable the Nomad server agent. | bool |
n/a | yes |
| region | AWS region where Nomad will be deployed. | string |
n/a | yes |
| vpc_id | ID of the AWS VPC resources are deployed into. | string |
n/a | yes |
| additional_package_names | List of additional repository package names to install | set(string) |
[] |
no |
| additional_security_group_ids | List of AWS security group IDs to apply to all cluster nodes. | list(string) |
[] |
no |
| asg_health_check_grace_period | The amount of time to wait for a new Nomad EC2 instance to become healthy. If this threshold is breached, the ASG will terminate the instance and launch a new one. | number |
600 |
no |
| associate_public_ip | Whether public IPv4 addresses should automatically be attached to cluster nodes. | bool |
false |
no |
| autopilot_health_enabled | Whether autopilot upgrade migration validation is performed for server nodes at boot-time | bool |
true |
no |
| cidr_allow_ingress_nomad | List of CIDR ranges to allow ingress traffic on port 443 or 80 to Nomad server or load balancer. | list(string) |
[ |
no |
| cni_version | Version of CNI plugin to install. | string |
"1.6.0" |
no |
| common_tags | Map of common tags for taggable AWS resources. | map(string) |
{} |
no |
| create_nlb | Boolean to create a Network Load Balancer for Nomad. | bool |
true |
no |
| create_route53_nomad_dns_record | Boolean to create Route53 Alias Record for nomad_hostname resolving to Load Balancer DNS name. If true, route53_hosted_zone_nomad is also required. |
bool |
false |
no |
| custom_install_template | Filename of a custom Install script template to use in place of of the built-in user_data script. The file must exist within a directory named './templates' in your current working directory. | string |
null |
no |
| data_ebs_iops | Amount of IOPS to configure when EBS volume type is gp3. Must be greater than or equal to 3000 and less than or equal to 16000. |
number |
3000 |
no |
| data_ebs_throughput | Throughput (MB/s) to configure when data EBS volume type is gp3. Must be greater than or equal to 125 and less than or equal to 1000. |
number |
250 |
no |
| data_ebs_volume_size | Size (GB) of the data EBS volume for Nomad EC2 instances. Must be greater than or equal to 50 and less than or equal to 16000. |
number |
50 |
no |
| data_ebs_volume_type | EBS volume type for data Nomad EC2 instances vol. | string |
"gp3" |
no |
| ebs_is_encrypted | Boolean to encrypt the EBS root block device of the Nomad EC2 instance(s). An AWS managed key will be used when true unless a value is also specified for ebs_kms_key_arn. |
bool |
true |
no |
| ebs_kms_key_arn | ARN of KMS customer managed key (CMK) to encrypt Nomad EC2 EBS volumes. | string |
null |
no |
| ec2_allow_ssm | Boolean to attach the AmazonSSMManagedInstanceCore policy to the Nomad instance role, allowing the SSM agent (if present) to function. |
bool |
false |
no |
| ec2_ami_id | AMI to launch ASG instances from. | string |
null |
no |
| ec2_os_distro | Linux OS distribution type for Nomad EC2 instance. Choose from al2023, ubuntu, rhel, centos. |
string |
"ubuntu" |
no |
| instance_type | EC2 instance type to launch. | string |
"m5.large" |
no |
| lb_is_internal | Boolean to create an internal (private) load balancer. The lb_subnet_ids must be private subnets when this is true. |
bool |
true |
no |
| lb_subnet_ids | List of subnet IDs to use for the load balancer. If lb_is_internal is false, then these should be public subnets. Otherwise, these should be private subnets. |
list(string) |
null |
no |
| nomad_acl_enabled | Boolean to enable ACLs for Nomad. | bool |
true |
no |
| nomad_architecture | Architecture of the Nomad binary to install. | string |
"amd64" |
no |
| nomad_fqdn | Fully qualified domain name of the Nomad Cluster. This name should resolve to the load balancer IP address and will be what admins will use to access Nomad. | string |
null |
no |
| nomad_gossip_encryption_key_secret_arn | ARN of AWS Secrets Manager secret for Nomad gossip encryption key. | string |
null |
no |
| nomad_license_secret_arn | ARN of AWS Secrets Manager secret for Nomad license file. | string |
null |
no |
| nomad_nodes | Number of Nomad nodes to deploy. | number |
6 |
no |
| nomad_region | Specifies the region of the local agent. A region is an abstract grouping of datacenters. Clients are not required to be in the same region as the servers they are joined with, but do need to be in the same datacenter. If not specified, the region is set AWS region. | string |
null |
no |
| nomad_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 |
null |
no |
| nomad_tls_cert_secret_arn | ARN of AWS Secrets Manager secret for Nomad TLS certificate in PEM format. Secret must be stored as a base64-encoded string. | string |
null |
no |
| nomad_tls_enabled | Boolean to enable TLS for Nomad. | bool |
true |
no |
| nomad_tls_privkey_secret_arn | ARN of AWS Secrets Manager secret for Nomad TLS private key in PEM format. Secret must be stored as a base64-encoded string. | string |
null |
no |
| nomad_ui_enabled | Boolean to enable the Nomad UI. | bool |
true |
no |
| nomad_upstream_servers | List of Nomad server addresses to join the Nomad client with. | list(string) |
null |
no |
| nomad_upstream_tag_key | String of the tag key the Nomad client should look for in AWS to join with. Only needed for auto-joining the Nomad client. | string |
null |
no |
| nomad_upstream_tag_value | String of the tag value the Nomad client should look for in AWS to join with. Only needed for auto-joining the Nomad client. | string |
null |
no |
| nomad_version | Version of Nomad to install. | string |
"1.9.0+ent" |
no |
| permit_all_egress | Whether broad (0.0.0.0/0) egress should be permitted on cluster nodes. If disabled, additional rules must be added to permit HTTP(S) and other necessary network access. | bool |
true |
no |
| root_ebs_iops | Amount of IOPS to configure when root EBS volume type is gp3. Must be greater than or equal to 3000 and less than or equal to 16000. |
number |
3000 |
no |
| root_ebs_throughput | Throughput (MB/s) to configure when root EBS volume type is gp3. Must be greater than or equal to 125 and less than or equal to 1000. |
number |
250 |
no |
| root_ebs_volume_size | Size (GB) of the root EBS volume for Nomad EC2 instances. Must be greater than or equal to 50 and less than or equal to 16000. |
number |
50 |
no |
| root_ebs_volume_type | EBS volume type for root Nomad EC2 instances vol. | string |
"gp3" |
no |
| route53_nomad_hosted_zone_is_private | Boolean indicating if route53_nomad_hosted_zone_name is a private hosted zone. |
bool |
false |
no |
| route53_nomad_hosted_zone_name | Route53 Hosted Zone name to create nomad_hostname Alias record in. Required if create_nomad_alias_record is true. |
string |
null |
no |
| Name | Description |
|---|---|
| nomad_cli_config | Environment variables to configure the nomad CLI |
| nomad_url | URL to access Nomad application based on value of nomad_fqdn input. |