{"id":14957780,"url":"https://github.com/easkay/ha-vault","last_synced_at":"2025-08-30T09:36:00.836Z","repository":{"id":48746864,"uuid":"201645850","full_name":"easkay/HA-Vault","owner":"easkay","description":"Examples of HA configurations of Hashicorp Vault across AWS, GCP, and Azure","archived":false,"fork":false,"pushed_at":"2023-05-02T16:48:04.000Z","size":113,"stargazers_count":12,"open_issues_count":4,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-07T00:27:22.159Z","etag":null,"topics":["ansible","aws","azure","gcp","hashicorp-consul","hashicorp-p","hashicorp-terraform","hashicorp-vault"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/easkay.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-10T15:08:41.000Z","updated_at":"2024-07-09T14:01:59.000Z","dependencies_parsed_at":"2024-09-22T04:01:56.031Z","dependency_job_id":"7e3a8fb5-3a04-46d7-823c-6001e6a7a153","html_url":"https://github.com/easkay/HA-Vault","commit_stats":{"total_commits":31,"total_committers":2,"mean_commits":15.5,"dds":"0.032258064516129004","last_synced_commit":"a1f1812a052fe78f929065a78fd0d505edf53479"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/easkay/HA-Vault","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easkay%2FHA-Vault","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easkay%2FHA-Vault/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easkay%2FHA-Vault/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easkay%2FHA-Vault/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/easkay","download_url":"https://codeload.github.com/easkay/HA-Vault/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easkay%2FHA-Vault/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272833294,"owners_count":25000870,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","aws","azure","gcp","hashicorp-consul","hashicorp-p","hashicorp-terraform","hashicorp-vault"],"created_at":"2024-09-24T13:15:34.195Z","updated_at":"2025-08-30T09:36:00.810Z","avatar_url":"https://github.com/easkay.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Production-ish Vault installation with a Consul cluster (storage)\n\n_NOTE_: This setup does not ship ready out-of-the-box, there are some tweaks the end user should do.\n\n## Super-quick getting started (try it out)\n\nThis repo assumes you're running on Linux or macOS.\n\nEnsure you have the following installed Terraform 0.13 (min), Packer 1.5 (min), Vault 1.4 (min), and ansible 2.8 (min).\nThe configs should work with newer versions as well.\nThis repo assumes some prior knowledge and experience with Vault, Terraform, Packer, and at least one of the cloud providers mentioned.\n\n### Common setup\n\n1. Replace any instances of `example.com` in the `tls-bootstrap/bootstrap.sh` with a domain that you control.\n1. Replace any instances of `example.com` in the `ansible/group_vars/example.yml` file with the same domain as the previous step.\n1. `cd` into the `ansible` folder and run the following to create Consul tokens for the necessary use cases:\n    ```\n    uuidgen | tr '[:upper:]' '[:lower:]' \u003e roles/consul/files/tokens/agent\n    uuidgen | tr '[:upper:]' '[:lower:]' \u003e roles/consul/files/tokens/haproxy\n    uuidgen | tr '[:upper:]' '[:lower:]' \u003e roles/consul/files/tokens/vault\n    ```\n1. `cd` into the `tls-bootstrap` folder, run `./bootstrap.sh`.\n\nPick a cloud provider - AWS, GCP, or Azure and setup the infrastructure as follows.\nIt's recommended to have a console for your chosen provider open and available, having logged in.\n\n### AWS\n\n1. Ensure you have a default VPC that has a minimum of 2 subnets and outbound internet access.\n    If you don't have one or don't want one, adjust the Packer templates and Terraform to use a different pre-configured VPC.\n1. Adjust the Packer and Terrafom variables.\n    1. Check the `aws/packer/example.vars` file and supply credentials and a region.\n    1. Check the `aws/terraform/example.tfvars` file and adjust the hostnames and trusted external IPs to fit your setup. It's recommended to add the outbound IP of your machine to this list. _NOTE_: AWS requires that these addresses be in CIDR format.\n1. Build the images with Packer.\n    1. `cd` into the `aws/packer` folder, run\n        ```\n        packer build --var-file example.vars consul.json\n        packer build --var-file example.vars vault.json\n        ```\n1. Run the Terraform.\n    1. `cd` into the `aws/terraform` folder, run `terraform init ; terraform apply --var-file example.tfvars` and if the plan looks good, approve it.\n    1. **While Terraform is running**, setup the domain configured in `aws/terraform/example.tfvars` to point at the AWS ELB. This can be done with a CNAME record in your DNS zone, or by resolving the DNS record (`dig \u003chostname\u003e`) and editing the hosts file as follows. If the `dig` command doesn't produce IPs for the ELB, ensure it's finished provisioning and retry.\n        ```\n        \u003cip_1\u003e vault-0.vault.example.com vault-1.vault.example.com vault.example.com consul.example.com\n        \u003cip_2\u003e vault-0.vault.example.com vault-1.vault.example.com vault.example.com consul.example.com\n        \u003cip_3\u003e vault-0.vault.example.com vault-1.vault.example.com vault.example.com consul.example.com\n        ```\n    1. If the Terraform apply step hangs on provisioning `null_resource.consul_acl_bootstrap`, check that Consul is responding at `consul.\u003cyour_domain\u003e:8501`.\n    1. If you receive an error similar to `Failed to create new policy: Unexpected response code: 500 (\u003cspecific error message\u003e)`, the situation can be recovered by locating the `null_resource consul_acl_bootstrap` resource and commenting all lines of the `command` _except_ those which start with `consul acl policy` or `consul acl token`. Terraform should then be re-run.\n\n### GCP\n\n1. Ensure you have a default VPC (named 'default') with a subnet (named 'default') that has outbound internet access.\n    If you don't have one or don't want one, adjust the Packer templates and Terraform to look for a different pre-configured VPC.\n1. Adjust the Packer and Terrafom variables.\n    1. Check the `gcp/packer/example.vars` file and supply credentials and a project ID.\n    1. Check the `gcp/terraform/example.tfvars` file and supply credentials and adjust the hostnames and trusted external IPs to fit your setup. It's recommended to add the outbound IP of your machine to this list.\n1. Build the images with Packer.\n    1. `cd` into the `gcp/packer` folder, run\n        ```\n        packer build --var-file example.vars consul.json\n        packer build --var-file example.vars vault.json\n        ```\n1. Run the Terraform.\n    1. `cd` into the `gcp/terraform` folder, run `terraform init ; terraform apply --var-file example.tfvars` and if the plan looks good, approve it.\n    1. **While Terraform is running**, setup the domain configured in `gcp/terraform/example.tfvars` to point at the Load Balancer frontends. This can be done with A records in your DNS zone, or by editing the hosts file:\n        ```\n        \u003cconsul_ip\u003e consul.example.com\n        \u003cvault_ip\u003e vault-0.vault.example.com vault-1.vault.example.com vault.example.com\n        ```\n    1. If the Terraform apply step hangs on provisioning `null_resource.consul_acl_bootstrap`, check that Consul is responding at `consul.\u003cyour_domain\u003e:8501`.\n    1. If you receive an error similar to `Failed to create new policy: Unexpected response code: 500 (\u003cspecific error message\u003e)`, the situation can be recovered by locating the `null_resource consul_acl_bootstrap` resource and commenting all lines of the `command` _except_ those which start with `consul acl policy` or `consul acl token`. Terraform should then be re-run.\n\n### Azure\n\n1. Ensure you have a virtual network setup that has outbound internet access with a Network Security Group named 'default' attached to the relevant subnet.\n    1. Create a new resource group, called 'default'.\n    1. Create a new virtual network, called 'default' with whatever IP space fits your needs.\n    1. Create a new network security group, called 'default' and associate it with the subnet in the virtual network.\n1. Adjust the Packer and Terrafom variables.\n    1. Check the `azure/packer/example.vars` file and supply a subscription ID, a resource group name, and a region.\n    1. Check the `azure/terraform/example.tfvars` file and adjust the hostnames and trusted external IPs to fit your setup.\n1. Login to the azure CLI if not already, and select the appropriate subscription with `az account set -s \u003csubscription name or ID\u003e`.\n1. Build the images with Packer.\n    1. `cd` into the `azure/packer` folder, run\n        ```\n        packer build --var-file example.vars consul.json\n        packer build --var-file example.vars vault.json\n        ```\n    1. If you run into issues authenticating with AzureAD, service principal authentication can be used instead. See [the packer docs](https://packer.io/docs/builders/azure-arm.html#service-principal).\n1. Run the Terraform.\n    1. `cd` into the `azure/terraform` folder, run `terraform init ; terraform apply --var-file example.tfvars` and if the plan looks good, approve it.\n    1. **While Terraform is running**, setup the domains configured in `azure/terraform/example.tfvars` to point at the Load Balancer public IPs. This can be done with A records in your DNS zone, or by editing the hosts file:\n        ```\n        \u003cconsul_public_ip\u003e consul.example.com\n        \u003cvault_public_ip\u003e vault-0.vault.example.com vault-1.vault.example.com vault.example.com\n        ```\n    1. You may receive an error relating to HealthProbes when creating the scale set for Consul, in this case, re-attempt the running of Terraform.\n    1. If you receive an error similar to `Failed to create new policy: Unexpected response code: 500 (\u003cspecific error message\u003e)`, the situation can be recovered by locating the `null_resource consul_acl_bootstrap` resource and commenting all lines of the `command` _except_ those which start with `consul acl policy` or `consul acl token`. Terraform should then be re-run.\n\n### Testing and Usage\n\n1. Prepare a client certificate for use with Consul.\n    1. `cd` into the `ansible` folder, run `openssl pkcs12 -export -in consul.crt -inkey consul.key -out consul.p12` and enter a password when prompted.\n    1. Import this certificate into your browser of choice.\n1. Try to access Consul by browsing to `https://consul.\u003cyour_domain\u003e:8501/ui`, select the certificate when prompted.\n1. Click on the `ACL` navbar item.\n1. Find the master token created during bootstrap and supply it to the UI, it should be in a file at `\u003ccloud_provider\u003e/terraform/master-token`.\n1. Try to access the HAProxy stats page for vault by visiting `http://vault.\u003cyour_domain\u003e/haproxy-stats` or `http://\u003cstats_ip\u003e/haproxy-stats` if running on GCP.\n1. Initialise Vault and unseal if you wish to experiment further.\n    1. `cd` into the `ansible` folder, and setup some useful environment variables.\n        ```\n        export VAULT_ADDR=https://vault-0.vault.\u003cyour_domain\u003e\n        export VAULT_CACERT=\"$(pwd)/vault-ca.crt\"\n        ```\n    1. Run `vault operator init`.\n    1. Copy the unseal keys and root token from the output and paste them into a text editor.\n    1. Unseal the specific Vault node by running the following `vault operator unseal` and supplying an unseal key when prompted. Repeat this process until the node is unsealed.\n    1. Once enough keys have been entered (3 by default), refresh the HAProxy stats page and look for the server that was just unsealed (vault-0) - it should be green at the bottom.\n\n## Getting started (more in-depth)\n\n### Terraform\n\nThe Terraform config in this repo uses the local filesystem for state storage instead of remote state.\nIt is highly recommended to use a remote storage mechanism for Terraform's state.\n\nAdditionally, there are no version pins for any of the providers and it's recommended that you set some.\n\n\n\n### Network\n\nIt's assumed that a network and subnet are available in which to setup the cluster, please adjust the automation accordingly.\n\n\n### Variables (ansible)\n\nMost variables are already setup with sensible values, but secrets or sensitive variables should be set per installation along with any other installation-specific variables.\nThe `example.yml` group variables are not stored securely for the purposes of enabling easy experimentation with this setup.\nOf course for a proper deployment, these secrets should be appropriately protected using something such as ansible-vault or by not committing them at all.\n\n_NOTE_: Special remarks about Consul tokens are made further on, though they can be configured through variables.\n\n#### Consul role\n\n```\nconsul_user_password_hash - The password hash to set for the Consul system user\n\nconsul_gossip_encryption_key - The encryption key used to secure Gossip traffic between Consul nodes, generated with `consul keygen`\n```\n\n#### HAProxy-consul-template role\n\n```\nconsul_template_user_password_hash - The password hash to set for the consul-template system user\n\nvault_lb_hostname - The external hostname used to access the load-balanced Vault endpoint.\n```\n\n#### Vault role\n\n```\nvault_user_password_hash - The password hash to set for the Vault system user\n```\n\n### Variables (terraform)\n\nThere is only a handful of variables needed by Terraform, each of which should be tweaked for your needs:\n```\nvault_hostname - The hostname which will be used to access Vault's load-balanced endpoint.\n\nconsul_hostname - The hostname which will be used to access Consul's load-balanced endpoint.\n\ntrusted_external_ips - The external IPs to permit when configuring external access to Vault and Consul.\n\nconsul_retry_join_config - This should not require adjustment unless the cloud auto-join tag or value is changed.\n```\n\nSome variables are provider-specific, such as GCP:\n\n```\ncredentials - The path on disk of a credentials file for Terraform to use.\n\nproject - The ID of the project to provision resources in.\n\nregion - The region in which to provision resources.\n```\n\n### Tokens\n\nConsul tokens are required for the Consul agent, for consul-template, and for Vault.\nThe `SecretID` values for each token are set in advance so that the machines can boot and automatically be able to perform their function without extra setup.\nThese are configured through variables in Ansible, which by default look for the tokens on the filesystem using the `lookup` plugin.\nYou should populate these tokens with your own values, which must be UUIDs, and can be supplied through files or by setting the ansible variables explicitly.\n_NOTE_: If you choose to use ansible variables instead of files, the ACL bootstrap process in Terraform will need to be adjusted to remove the creation of Consul tokens.\n\nThe relevant ansible variables are as follows:\n```\nconsul_agent_acl_token - The token for the Consul agent to use, expects a corresponding file in `ansible/roles/consul/files/tokens/agent`\n\nconsul_default_acl_token - The default token used by the Consul agent, expects a corresponding file in `ansible/roles/consul/files/tokens/agent`\n\nconsul_template_consul_token - The token used by consul-template to obtain node data about vault, expects a corresponding file in `ansible/roles/consul/files/tokens/haproxy`\n\nvault_consul_acl_token - The token used by Vault to access Consul's KV store, expects a corresponding file in `ansible/roles/consul/files/tokens/vault`\n```\n\n### Certificates\n\nCertificates are used to secure traffic from Consul and Vault (TLS server certificates) as well as to Consul (TLS client certificates).\nYou should generate your own keys and certificates signed by a CA you trust.\nSpecific recommendations about TLS are in the Design section and a script is provided in `tls-bootstrap` to get things started.\n_NOTE_: Some values (particularly CNs and SANs) will need to be adjusted depending on hostnames in use.\nParticular attention should be paid to the hostnames on the certificate to ensure that communication isn't blocked.\nConsul expects a name of `consul` to be present within the Consul server and client certificates by default.\n\nAnsible and Terraform expect the following files to be available at the root of the `ansible` folder:\n\n* consul.crt - The certificate file (optionally containing the issuing CA's certificate) to use for Consul server and client authentication.\n* consul-ca.crt - The certificate file of the CA that signs the certificate in `consul.crt`.\n* consul.key - The private key file to use for Consul server and client authentication.\n* vault.crt - The certificate file (optionally containing the issuing CA's certificate) to use for Vault server authentication.\n* vault-ca.crt - The certificate file of the CA that signs the certificate in `vault.crt`.\n* vault.key - The private key file to use for Vault server authentication.\n\n### DNS\n\nHostnames are only needed in a few places, and should be adjusted before provisioning.\nSee\n* `haproxy-consul-template` ansible role, defaults\n* `vault_hostname` variable in Terraform\n* `consul_hostname` variable in Terraform\n* `CERTIFICATE_DOMAIN` variable in `tls-bootstrap/bootstrap.sh`\n\nThe automation does _NOT_ create any DNS records, but does expect them to exist and therefore you should add the necessary automation to Terraform or arrange some other means of ensuring that the expected hostname resolves to an address on the load-balancer.\n\n### Backups\n\nThere is no provision made to enable backups as the situation of each user is likely to be different.\nSince Consul is the backing store for Vault, an automated process that takes a snapshot of Consul and saves it somewhere would probably be useful.\n\n## Design\n\n### External access\n\nAll external access is IP controlled within security groups configured through Terraform.\nHTTPS communication to Consul is exposed via a load-balancer on port 8501 and traffic is sent to the autoscaling group.\nHTTPS communication to Vault is exposed via a load-balancer on port 443 and traffic is sent to HAProxy on the Vault nodes.\nDepending on the hostname supplied, traffic is routed either to any available Vault node or directly to a specific node.\n\nThis is done so that individual Vault nodes can be unsealed externally and so as to enable initialisation of Vault.\n\n### DNS\n\nConsul and Vault are exposed through a load-balancer and are expected to be available at `vault.\u003cdomain\u003e` and `consul.\u003cdomain\u003e`.\nIndividual Vault server nodes are available at `\u003cinstance name\u003e.vault.\u003cdomain\u003e` where `\u003cinstance name\u003e` is the name of the VM within the cloud provider.\nBy default this is something like `vault-0`.\n\nVarious systems need to be aware of the hostnames used for access, as well as requiring certificates with appropriate CNs and SANs.\nIn particular these are:\n* HAProxy (via the `haproxy-consul-template` ansible role)\n* Terraform (via the `vault_hostname` and `consul_hostname` locals)\n\n### TLS\n\nPrivate CAs are created to secure traffic to Consul and Vault, and the script in `tls-bootstrap` is designed to achieve this.\nYou can use whatever certificates you'd like, including Let's Encrypt but be aware of the following:\n\n* The certificates and keys are baked into the machine images\n* Ansible expects the certificate and key files to be available to it, so they should be placed in the `ansible` folder or within the `files` folder of the relevant role\n* If using a public CA, ensure that the `.crt` file contains the certificate of the issuing CA and any intermediates, and that the `-ca.crt` file contains the certificate of the root CA.\n* The CA used to secure outgoing communication (TLS server certs) from Consul must be the same as the one used to secure incoming communication (TLS client certs), so a private CA is recommended.\n\nCertificates are needed at various points in the provisioning process, chiefly by ansible and Terraform.\nAnsible bakes the certificate and key files into the machine image, and Terraform uses the Consul certificate files in the ACL bootstrapping process.\n\n_NOTE_: The CNs and SANs used on certificates are critical and must match various expected names.\nOf course for external access, the certificates should have `consul.\u003cdomain\u003e`, `vault.\u003cdomain\u003e`, and `*.vault.\u003cdomain\u003e` names.\nIn addition, to enable Consul to communicate securely with itself, it expects a given name to be present in the certificate, by default this is `consul`.\nIf you wish to adjust this, be sure to update the Consul configuration to expect the newly assigned value.\n\n### Consul\n\nAn autoscaling group is created for Consul, but with no scaling rules as this is a very installation-specific concern.\nThe Consul nodes are designed to be able to join a cluster with minimal fuss and use the cloud auto-join mechanism to do so.\nThe agent goes through a bootstrap process on startup to configure the cloud auto-join settings as well as setting the agent ACL.\nThe cloud auto-join settings are configured in Terraform.\n\n#### ACLs\n\nThe ACL system is bootstrapped using the bootstrap process and currently is achieved using a null resource in Terraform to call the relevant APIs from the machine running Terraform.\nThe master token is captured and output to the filesystem for the operator to do with as they please.\nSome essential policies and tokens are also created at this point to enable Vault and consul-template to function.\nThe bootstrap process will retry indefinitely until it succeeds, which can lead to an infinite provisioning loop if the bootstrap operation is successful but subsequent operations fail.\nIn this situation, the bootstrap process should be reset, or the relevant lines should be commented allowing Terraform to re-run.\n\nHaving Consul tokens within machine images has been avoided as much as possible, however a certain amount of it is necessary.\nFor the purposes of configuring the Consul agent with the necessary permissions to do node updates, a file is placed in `/etc/consul.d` for use in the agent bootstrap process.\nOnce the agent has been configured to use the token with the agent ACL API, the token file is deleted as token persistence within Consul is enabled.\n\n### HAProxy and consul-template\n\nHAProxy is installed on the Vault nodes to be able to direct traffic as necessary and achieve the direct-to-node or load-balanced access as previously described.\nTo achieve this, there are two types/groups of backends - a backend per node for the direct-to-node access, containing only that specific node, and a single backend containing all nodes for the load-balanced access.\nHAProxy is deliberately unaware of the content of any HTTP requests going through it (except stats), and uses the SNI conversation as a judgement for where to send traffic.\nThe HAProxy frontends can optionally accept the proxy protocol (defaults to on) from the fronting load-balancer.\nAll backends within HAProxy (individual nodes and load-balanced pool) have health checks enabled.\nThe load-balanced backend uses an HTTPS check to Vault's health endpoint and the individual node backends use HTTPS health checks to Vault's health endpoint, permitting most error conditions.\nIn addition, all backends send the proxy protocol to Vault.\n\nConsul-tempmlate is used to query Consul for Vault node information and populates HAProxy's configuration accordingly for the individual node backends as well as the load-balanced backend.\n\n### Vault\n\nVault is setup to receive the proxy protocol and is configured such that any IP in the subnet is allowed to send the proxy protocol to Vault.\nThis enables multiple Vault nodes to load-balance one another (with HAProxy) without needing to authorise specific IPs or needing to dynamically configure Vault according to what nodes are available.\n\nIt's expected that the `file` audit method will be used and so logrotate has been configured accordingly, especting an audit log file to be placed in `/var/log/vault/` with an extension of `.log`.\n\nIt should be noted that auto-unsealing is not in use in this installation and the initialisation of Vault is left as an exercise for the operator.\n\n## Considerations of automation and setup\n\n### TLS certificates\n\nIt is hypothetically possible to create one or more PKI backends within Vault and have them serve as the CAs for securing Consul and Vault communication.\nThis could give you such benefits as not needing to create machine images that contain certificates and keys, instead having the nodes generate keys and obtain signed certificates from Vault upon startup.\n\nThe reason this hasn't been done is that it makes the overall setup more complicated and requires more initial configuration during the setup of the system, as it creates a cyclical dependency on the cluster itself.\nYou may of course pursue such a setup should you wish, just bear in mind the differences between automating 'the first' setup and 'the ongoing' setup.\nIf the cluster needed to be rebuilt, it's likely that you would need to revert to storing certificates and keys within the image until the cluster can be brought up from scratch again.\nOne way to achieve the self-certificating setup would be to use consul-template to request certificates from Vault, and restarting Consul or triggering a config reload when the files changed.\nIt would be best to use the Vault agent as well to maintain a Vault token and have the agent make requests to Vault on behalf of consul-template.\nYou would also need to change the explicit CA cert file in Consul's config, with a directory to permit the change in CA to take place as new agents are rolled out to the autoscaling group.\n\nIncidentally the commentary mentions Consul as a target of automated certificates, but the approach for Vault would be very similar.\n\nIt would also be possible to use a secret storage mechanism on a cloud provider to store the certificates and keys and have the machines pull them out of storage on startup.\nThis hasn't been done in order to simplify the setup and to avoid introducing further dependencies outwith those already in use.\nDepending on your situation, you may wish to avoid trusting such a tool, or you may consider that acceptable.\n\nIf you wanted to pull certificates in on startup, it would be reasonably trivial to do and the userdata field could be used fairly effectively.\n\n### ACL tokens\n\nIn this setup, Consul tokens are created with known secret values already provisioned within components such as consul-template and Vault.\nThe tokens are stored in the machine image and removed if possible after startup (Consul only).\n\nIt would be possible to instead store these tokens within Vault or even a cloud provider's secrets storage facility and have the nodes retrieve them on startup.\nThis hasn't been done for similar reasons to those discussed in the previous section - to avoid introducing unnecessary dependencies, to limit the reach of trust, and also to avoid complexity in the setup.\n\nOnce again, such a setup is fairly trivial to achieve, and the recommendation is to use userdata to trigger the behaviour.\n\n### ACL bootstrapping\n\nIt's possible to use the Consul provider for Terraform to create ACL policies and tokens within Consul.\n\nIn this setup, policies and tokens are instead created by calling the APIs via the Consul binary.\nThe reason for this is, again to avoid introducing complexity into the initial setup.\nWhen managing resources via Terraform, layered and explicitly-ordered dependencies within the same configuration don't always work well.\nThe CLI-based approach allows for plenty of retries and a more robust experience than attempting to wire the Consul provider up to a cluster that doesn't yet exist or is still being provisioned.\n\nAgain, you could bootstrap the cluster and then go on to manage the ACL policies and tokens within Terraform, including importing the master and default tokens and this has been left as an exercise for the operator.\nIt would also be possible to use Vault to create and distribute tokens for use with Consul, and much like the previous sections, this has been left out so as to not introduce complexity.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feaskay%2Fha-vault","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feaskay%2Fha-vault","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feaskay%2Fha-vault/lists"}