├── .gitignore ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── aws-local-env.sh ├── azure-local-env.sh ├── ci-functions.sh ├── consul-template └── scripts │ └── install-consul-template.sh ├── consul ├── Vagrantfile ├── consul-aws.json ├── consul-azure.json ├── init │ └── systemd │ │ ├── consul-online.service │ │ ├── consul-online.sh │ │ ├── consul-online.target │ │ ├── consul-snapshot.service │ │ └── consul.service └── scripts │ ├── install-consul-systemd.sh │ └── install-consul.sh ├── envconsul └── scripts │ └── install-envconsul.sh ├── gcp-local-env.sh ├── hashistack ├── README.md ├── Vagrantfile ├── hashistack-aws.json ├── hashistack-azure.json └── hashistack-gcp.json ├── nomad ├── Vagrantfile ├── init │ └── systemd │ │ ├── nomad-force-leave-missing-peers-ec2.service │ │ ├── nomad-force-leave-missing-peers-ec2.sh │ │ ├── nomad-online.service │ │ ├── nomad-online.sh │ │ ├── nomad-online.target │ │ ├── nomad-vault.service │ │ ├── nomad.service │ │ ├── vault-token-ready.service │ │ ├── vault-token-ready.sh │ │ └── vault-token-ready.target ├── nomad-aws.json └── scripts │ ├── install-docker.sh │ ├── install-java.sh │ ├── install-nomad-systemd.sh │ └── install-nomad.sh ├── shared └── scripts │ ├── Gemfile │ ├── base-aws.sh │ ├── base-azure.sh │ ├── base.sh │ ├── cleanup-aws.sh │ ├── cleanup.sh │ ├── disable-firewall.sh │ ├── setup-ssh-user.sh │ ├── setup-testing.sh │ ├── setup-user.sh │ └── web-terminal.sh ├── spec ├── consul │ └── consul_spec.rb ├── nomad │ ├── docker_spec.rb │ ├── java_spec.rb │ └── nomad_spec.rb ├── shared │ ├── network_spec.rb │ ├── ntp_spec.rb │ └── ssh_spec.rb ├── spec_helper.rb └── vault │ └── vault_spec.rb ├── vault-si ├── config │ └── vault-si.hcl └── scripts │ └── vault-si-install.sh ├── vault ├── Vagrantfile ├── init │ └── systemd │ │ ├── vault-secure-intro.service │ │ └── vault.service ├── scripts │ ├── install-vault-systemd.sh │ └── install-vault.sh └── vault-aws.json └── versions.sh /.gitignore: -------------------------------------------------------------------------------- 1 | ### Packer ### 2 | # Cache objects 3 | packer_cache/ 4 | 5 | # For built boxes 6 | *.box 7 | 8 | ### Terraform ### 9 | # Compiled files 10 | *.tfstate 11 | *.tfstate.backup 12 | 13 | # Module directory 14 | */.terraform/modules/ 15 | .terraform/ 16 | 17 | ### Vagrant ### 18 | .vagrant/ 19 | 20 | ### SSH Keys ### 21 | *.pem 22 | 23 | ### local testing ### 24 | hashistack/env.sh 25 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem 'rake' 4 | gem 'serverspec' 5 | gem 'rainbow' 6 | gem 'serverspec-extended-types' 7 | gem 'specinfra' 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 HashiCorp, Inc. 2 | 3 | Mozilla Public License Version 2.0 4 | ================================== 5 | 6 | 1. Definitions 7 | -------------- 8 | 9 | 1.1. "Contributor" 10 | means each individual or legal entity that creates, contributes to 11 | the creation of, or owns Covered Software. 12 | 13 | 1.2. "Contributor Version" 14 | means the combination of the Contributions of others (if any) used 15 | by a Contributor and that particular Contributor's Contribution. 16 | 17 | 1.3. "Contribution" 18 | means Covered Software of a particular Contributor. 19 | 20 | 1.4. "Covered Software" 21 | means Source Code Form to which the initial Contributor has attached 22 | the notice in Exhibit A, the Executable Form of such Source Code 23 | Form, and Modifications of such Source Code Form, in each case 24 | including portions thereof. 25 | 26 | 1.5. "Incompatible With Secondary Licenses" 27 | means 28 | 29 | (a) that the initial Contributor has attached the notice described 30 | in Exhibit B to the Covered Software; or 31 | 32 | (b) that the Covered Software was made available under the terms of 33 | version 1.1 or earlier of the License, but not also under the 34 | terms of a Secondary License. 35 | 36 | 1.6. "Executable Form" 37 | means any form of the work other than Source Code Form. 38 | 39 | 1.7. "Larger Work" 40 | means a work that combines Covered Software with other material, in 41 | a separate file or files, that is not Covered Software. 42 | 43 | 1.8. "License" 44 | means this document. 45 | 46 | 1.9. "Licensable" 47 | means having the right to grant, to the maximum extent possible, 48 | whether at the time of the initial grant or subsequently, any and 49 | all of the rights conveyed by this License. 50 | 51 | 1.10. "Modifications" 52 | means any of the following: 53 | 54 | (a) any file in Source Code Form that results from an addition to, 55 | deletion from, or modification of the contents of Covered 56 | Software; or 57 | 58 | (b) any new file in Source Code Form that contains any Covered 59 | Software. 60 | 61 | 1.11. "Patent Claims" of a Contributor 62 | means any patent claim(s), including without limitation, method, 63 | process, and apparatus claims, in any patent Licensable by such 64 | Contributor that would be infringed, but for the grant of the 65 | License, by the making, using, selling, offering for sale, having 66 | made, import, or transfer of either its Contributions or its 67 | Contributor Version. 68 | 69 | 1.12. "Secondary License" 70 | means either the GNU General Public License, Version 2.0, the GNU 71 | Lesser General Public License, Version 2.1, the GNU Affero General 72 | Public License, Version 3.0, or any later versions of those 73 | licenses. 74 | 75 | 1.13. "Source Code Form" 76 | means the form of the work preferred for making modifications. 77 | 78 | 1.14. "You" (or "Your") 79 | means an individual or a legal entity exercising rights under this 80 | License. For legal entities, "You" includes any entity that 81 | controls, is controlled by, or is under common control with You. For 82 | purposes of this definition, "control" means (a) the power, direct 83 | or indirect, to cause the direction or management of such entity, 84 | whether by contract or otherwise, or (b) ownership of more than 85 | fifty percent (50%) of the outstanding shares or beneficial 86 | ownership of such entity. 87 | 88 | 2. License Grants and Conditions 89 | -------------------------------- 90 | 91 | 2.1. Grants 92 | 93 | Each Contributor hereby grants You a world-wide, royalty-free, 94 | non-exclusive license: 95 | 96 | (a) under intellectual property rights (other than patent or trademark) 97 | Licensable by such Contributor to use, reproduce, make available, 98 | modify, display, perform, distribute, and otherwise exploit its 99 | Contributions, either on an unmodified basis, with Modifications, or 100 | as part of a Larger Work; and 101 | 102 | (b) under Patent Claims of such Contributor to make, use, sell, offer 103 | for sale, have made, import, and otherwise transfer either its 104 | Contributions or its Contributor Version. 105 | 106 | 2.2. Effective Date 107 | 108 | The licenses granted in Section 2.1 with respect to any Contribution 109 | become effective for each Contribution on the date the Contributor first 110 | distributes such Contribution. 111 | 112 | 2.3. Limitations on Grant Scope 113 | 114 | The licenses granted in this Section 2 are the only rights granted under 115 | this License. No additional rights or licenses will be implied from the 116 | distribution or licensing of Covered Software under this License. 117 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 118 | Contributor: 119 | 120 | (a) for any code that a Contributor has removed from Covered Software; 121 | or 122 | 123 | (b) for infringements caused by: (i) Your and any other third party's 124 | modifications of Covered Software, or (ii) the combination of its 125 | Contributions with other software (except as part of its Contributor 126 | Version); or 127 | 128 | (c) under Patent Claims infringed by Covered Software in the absence of 129 | its Contributions. 130 | 131 | This License does not grant any rights in the trademarks, service marks, 132 | or logos of any Contributor (except as may be necessary to comply with 133 | the notice requirements in Section 3.4). 134 | 135 | 2.4. Subsequent Licenses 136 | 137 | No Contributor makes additional grants as a result of Your choice to 138 | distribute the Covered Software under a subsequent version of this 139 | License (see Section 10.2) or under the terms of a Secondary License (if 140 | permitted under the terms of Section 3.3). 141 | 142 | 2.5. Representation 143 | 144 | Each Contributor represents that the Contributor believes its 145 | Contributions are its original creation(s) or it has sufficient rights 146 | to grant the rights to its Contributions conveyed by this License. 147 | 148 | 2.6. Fair Use 149 | 150 | This License is not intended to limit any rights You have under 151 | applicable copyright doctrines of fair use, fair dealing, or other 152 | equivalents. 153 | 154 | 2.7. Conditions 155 | 156 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 157 | in Section 2.1. 158 | 159 | 3. Responsibilities 160 | ------------------- 161 | 162 | 3.1. Distribution of Source Form 163 | 164 | All distribution of Covered Software in Source Code Form, including any 165 | Modifications that You create or to which You contribute, must be under 166 | the terms of this License. You must inform recipients that the Source 167 | Code Form of the Covered Software is governed by the terms of this 168 | License, and how they can obtain a copy of this License. You may not 169 | attempt to alter or restrict the recipients' rights in the Source Code 170 | Form. 171 | 172 | 3.2. Distribution of Executable Form 173 | 174 | If You distribute Covered Software in Executable Form then: 175 | 176 | (a) such Covered Software must also be made available in Source Code 177 | Form, as described in Section 3.1, and You must inform recipients of 178 | the Executable Form how they can obtain a copy of such Source Code 179 | Form by reasonable means in a timely manner, at a charge no more 180 | than the cost of distribution to the recipient; and 181 | 182 | (b) You may distribute such Executable Form under the terms of this 183 | License, or sublicense it under different terms, provided that the 184 | license for the Executable Form does not attempt to limit or alter 185 | the recipients' rights in the Source Code Form under this License. 186 | 187 | 3.3. Distribution of a Larger Work 188 | 189 | You may create and distribute a Larger Work under terms of Your choice, 190 | provided that You also comply with the requirements of this License for 191 | the Covered Software. If the Larger Work is a combination of Covered 192 | Software with a work governed by one or more Secondary Licenses, and the 193 | Covered Software is not Incompatible With Secondary Licenses, this 194 | License permits You to additionally distribute such Covered Software 195 | under the terms of such Secondary License(s), so that the recipient of 196 | the Larger Work may, at their option, further distribute the Covered 197 | Software under the terms of either this License or such Secondary 198 | License(s). 199 | 200 | 3.4. Notices 201 | 202 | You may not remove or alter the substance of any license notices 203 | (including copyright notices, patent notices, disclaimers of warranty, 204 | or limitations of liability) contained within the Source Code Form of 205 | the Covered Software, except that You may alter any license notices to 206 | the extent required to remedy known factual inaccuracies. 207 | 208 | 3.5. Application of Additional Terms 209 | 210 | You may choose to offer, and to charge a fee for, warranty, support, 211 | indemnity or liability obligations to one or more recipients of Covered 212 | Software. However, You may do so only on Your own behalf, and not on 213 | behalf of any Contributor. You must make it absolutely clear that any 214 | such warranty, support, indemnity, or liability obligation is offered by 215 | You alone, and You hereby agree to indemnify every Contributor for any 216 | liability incurred by such Contributor as a result of warranty, support, 217 | indemnity or liability terms You offer. You may include additional 218 | disclaimers of warranty and limitations of liability specific to any 219 | jurisdiction. 220 | 221 | 4. Inability to Comply Due to Statute or Regulation 222 | --------------------------------------------------- 223 | 224 | If it is impossible for You to comply with any of the terms of this 225 | License with respect to some or all of the Covered Software due to 226 | statute, judicial order, or regulation then You must: (a) comply with 227 | the terms of this License to the maximum extent possible; and (b) 228 | describe the limitations and the code they affect. Such description must 229 | be placed in a text file included with all distributions of the Covered 230 | Software under this License. Except to the extent prohibited by statute 231 | or regulation, such description must be sufficiently detailed for a 232 | recipient of ordinary skill to be able to understand it. 233 | 234 | 5. Termination 235 | -------------- 236 | 237 | 5.1. The rights granted under this License will terminate automatically 238 | if You fail to comply with any of its terms. However, if You become 239 | compliant, then the rights granted under this License from a particular 240 | Contributor are reinstated (a) provisionally, unless and until such 241 | Contributor explicitly and finally terminates Your grants, and (b) on an 242 | ongoing basis, if such Contributor fails to notify You of the 243 | non-compliance by some reasonable means prior to 60 days after You have 244 | come back into compliance. Moreover, Your grants from a particular 245 | Contributor are reinstated on an ongoing basis if such Contributor 246 | notifies You of the non-compliance by some reasonable means, this is the 247 | first time You have received notice of non-compliance with this License 248 | from such Contributor, and You become compliant prior to 30 days after 249 | Your receipt of the notice. 250 | 251 | 5.2. If You initiate litigation against any entity by asserting a patent 252 | infringement claim (excluding declaratory judgment actions, 253 | counter-claims, and cross-claims) alleging that a Contributor Version 254 | directly or indirectly infringes any patent, then the rights granted to 255 | You by any and all Contributors for the Covered Software under Section 256 | 2.1 of this License shall terminate. 257 | 258 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 259 | end user license agreements (excluding distributors and resellers) which 260 | have been validly granted by You or Your distributors under this License 261 | prior to termination shall survive termination. 262 | 263 | ************************************************************************ 264 | * * 265 | * 6. Disclaimer of Warranty * 266 | * ------------------------- * 267 | * * 268 | * Covered Software is provided under this License on an "as is" * 269 | * basis, without warranty of any kind, either expressed, implied, or * 270 | * statutory, including, without limitation, warranties that the * 271 | * Covered Software is free of defects, merchantable, fit for a * 272 | * particular purpose or non-infringing. The entire risk as to the * 273 | * quality and performance of the Covered Software is with You. * 274 | * Should any Covered Software prove defective in any respect, You * 275 | * (not any Contributor) assume the cost of any necessary servicing, * 276 | * repair, or correction. This disclaimer of warranty constitutes an * 277 | * essential part of this License. No use of any Covered Software is * 278 | * authorized under this License except under this disclaimer. * 279 | * * 280 | ************************************************************************ 281 | 282 | ************************************************************************ 283 | * * 284 | * 7. Limitation of Liability * 285 | * -------------------------- * 286 | * * 287 | * Under no circumstances and under no legal theory, whether tort * 288 | * (including negligence), contract, or otherwise, shall any * 289 | * Contributor, or anyone who distributes Covered Software as * 290 | * permitted above, be liable to You for any direct, indirect, * 291 | * special, incidental, or consequential damages of any character * 292 | * including, without limitation, damages for lost profits, loss of * 293 | * goodwill, work stoppage, computer failure or malfunction, or any * 294 | * and all other commercial damages or losses, even if such party * 295 | * shall have been informed of the possibility of such damages. This * 296 | * limitation of liability shall not apply to liability for death or * 297 | * personal injury resulting from such party's negligence to the * 298 | * extent applicable law prohibits such limitation. Some * 299 | * jurisdictions do not allow the exclusion or limitation of * 300 | * incidental or consequential damages, so this exclusion and * 301 | * limitation may not apply to You. * 302 | * * 303 | ************************************************************************ 304 | 305 | 8. Litigation 306 | ------------- 307 | 308 | Any litigation relating to this License may be brought only in the 309 | courts of a jurisdiction where the defendant maintains its principal 310 | place of business and such litigation shall be governed by laws of that 311 | jurisdiction, without reference to its conflict-of-law provisions. 312 | Nothing in this Section shall prevent a party's ability to bring 313 | cross-claims or counter-claims. 314 | 315 | 9. Miscellaneous 316 | ---------------- 317 | 318 | This License represents the complete agreement concerning the subject 319 | matter hereof. If any provision of this License is held to be 320 | unenforceable, such provision shall be reformed only to the extent 321 | necessary to make it enforceable. Any law or regulation which provides 322 | that the language of a contract shall be construed against the drafter 323 | shall not be used to construe this License against a Contributor. 324 | 325 | 10. Versions of the License 326 | --------------------------- 327 | 328 | 10.1. New Versions 329 | 330 | Mozilla Foundation is the license steward. Except as provided in Section 331 | 10.3, no one other than the license steward has the right to modify or 332 | publish new versions of this License. Each version will be given a 333 | distinguishing version number. 334 | 335 | 10.2. Effect of New Versions 336 | 337 | You may distribute the Covered Software under the terms of the version 338 | of the License under which You originally received the Covered Software, 339 | or under the terms of any subsequent version published by the license 340 | steward. 341 | 342 | 10.3. Modified Versions 343 | 344 | If you create software not governed by this License, and you want to 345 | create a new license for such software, you may create and use a 346 | modified version of this License if you rename the license and remove 347 | any references to the name of the license steward (except to note that 348 | such modified license differs from this License). 349 | 350 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 351 | Licenses 352 | 353 | If You choose to distribute Source Code Form that is Incompatible With 354 | Secondary Licenses under the terms of this version of the License, the 355 | notice described in Exhibit B of this License must be attached. 356 | 357 | Exhibit A - Source Code Form License Notice 358 | ------------------------------------------- 359 | 360 | This Source Code Form is subject to the terms of the Mozilla Public 361 | License, v. 2.0. If a copy of the MPL was not distributed with this 362 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 363 | 364 | If it is not possible or desirable to put the notice in a particular 365 | file, then You may include the notice in a location (such as a LICENSE 366 | file in a relevant directory) where a recipient would be likely to look 367 | for such a notice. 368 | 369 | You may add additional accurate notices of copyright ownership. 370 | 371 | Exhibit B - "Incompatible With Secondary Licenses" Notice 372 | --------------------------------------------------------- 373 | 374 | This Source Code Form is "Incompatible With Secondary Licenses", as 375 | defined by the Mozilla Public License, v. 2.0. 376 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Guides Configuration 2 | 3 | This repo contains Packer templates used by HashiCorp Terraform modules in the [hashicorp-modules](https://github.com/hashicorp-modules/) GitHub Org. 4 | 5 | ### Building HashiStack images locally (outside of the CI pipeline) 6 | 7 | This is a workflow that's designed to allow you to trigger local builds of enterprise or OSS Packer images. This functionality is currently under development. 8 | 9 | This is particularly useful for customers using Azure, as it's not possible to share machine images. 10 | 11 | #### Prerequisites 12 | 13 | - Access HashiCorp enterprise binaries 14 | - If you are building Azure images, you'll need to follow the steps at the below links to set up and authenticate with an Azure account 15 | - [Azure setup instructions](https://github.com/tdsacilowski/azure-consul/blob/master/README.md#deployment-prerequisites) 16 | - [Azure RM setup guide](https://www.terraform.io/docs/providers/azurerm/index.html) 17 | 18 | #### An example using Packer to build images on Azure 19 | 20 | After authenticating (see above) with Azure, perform the following steps. 21 | 22 | - Authenticate with Azure using the [Azure setup instructions](https://github.com/tdsacilowski/azure-consul/blob/master/README.md#deployment-prerequisites). 23 | - Create a file like the below with your credentials and source it before running the next step. 24 | **You can skip this step if you want. The `azure-local-env.sh` will take care of it for you, asking you to input each variable that is not already set in your environment.** 25 | 26 | ``` 27 | vi env.sh 28 | ``` 29 | 30 | ``` 31 | #!/bin/bash 32 | # env.sh 33 | # Exporting variables in both cases just in case, no pun intended 34 | export ARM_SUBSCRIPTION_ID="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" 35 | export ARM_CLIENT_ID="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" 36 | export ARM_CLIENT_SECRET="cccccccc-cccc-cccc-cccc-cccccccccccc" 37 | export ARM_TENANT_ID="dddddddd-dddd-dddd-dddd-dddddddddddd" 38 | export subscription_id="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" 39 | export client_id="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" 40 | export client_secret="cccccccc-cccc-cccc-cccc-cccccccccccc" 41 | ``` 42 | 43 | ``` 44 | source env.sh 45 | ``` 46 | 47 | - With the root of this repo as your working directory, run the following before each packer build: 48 | ``` 49 | # Source azure-local-env.sh before each packer build to regenerate URLs, 50 | # as the enterprise download URLs expire after 10 minutes. 51 | # 52 | $ source azure-local-env.sh # aws-local-env.sh for AWS (AWS local build untested) 53 | $ cd hashistack 54 | $ packer build hashistack-azure.json 55 | ``` 56 | 57 | --- 58 | 59 | ## Consul 60 | 61 | Contains Consul specific installation scripts, configuration files. Also has Packer templates specific to Consul usage. 62 | 63 | Example AWS Consul build command: 64 | 65 | ``` 66 | source aws-local-env.sh 67 | AWS_REGION="us-west-1" packer build consul-aws.json 68 | ``` 69 | 70 | Example Azure Consul build command: 71 | 72 | ``` 73 | source azure-local-env.sh 74 | AZURE_RESOURCE_GROUP="PackerImages" AZURE_LOCATION="West US" PACKER_ENVIRONMENT="dev" CONSUL_VERSION="0.9.2" packer build consul-azure.json 75 | ``` 76 | 77 | --- 78 | 79 | ## Vault 80 | 81 | Contains Vault specific installation scripts, configuration files. Also has Packer templates specific to Vault usage. 82 | 83 | Example AWS Vault (including Consul) build command: 84 | 85 | ``` 86 | source aws-local-env.sh 87 | AWS_REGION="us-west-1" packer build vault-aws.json 88 | ``` 89 | 90 | --- 91 | 92 | ## Nomad 93 | Contains Nomad specific installation scripts, configuration files. Also has Packer templates specific to Nomad usage. 94 | 95 | 96 | Example AWS Nomad (including Consul) build command: 97 | 98 | ``` 99 | source aws-local-env.sh 100 | AWS_REGION="us-west-1" packer build nomad-aws.json 101 | ``` 102 | 103 | --- 104 | 105 | ## HashiStack 106 | Contains provider specific templates that installs HashiCorp software on a single node (Consul, Nomad, Vault, consul-template and envconsul). 107 | 108 | Example AWS HashiStack build command: 109 | 110 | ``` 111 | source aws-local-env.sh 112 | AWS_REGION="us-west-1" packer build hashistack-aws.json 113 | ``` 114 | 115 | Example Azure HashiStack build command: 116 | 117 | ``` 118 | source azure-local-env.sh 119 | VCS_NAME="local" PACKER_ENVIRONMENT="production" CONSUL_VERSION="1.2.0" VAULT_VERSION="0.10.3" NOMAD_VERSION="0.8.4" packer build hashistack-azure.json 120 | ``` 121 | 122 | Example GCP HashiStack build command: 123 | 124 | ``` 125 | source gcp-local-env.sh 126 | VCS_NAME="local" PACKER_ENVIRONMENT="production" CONSUL_VERSION="1.2.0" VAULT_VERSION="0.10.3" NOMAD_VERSION="0.8.4" packer build hashistack-gcp.json 127 | ``` 128 | 129 | ## Continuous Integration 130 | 131 | Product versions for the builds are set on the versions.sh file. This file should be sourced at the start of the CI Build process. The ci-functions.sh file should be sourced at the start of the CI Build process and introduces three functions: 132 | 133 | - prepare() will download the ${PACKER_VERSION} 134 | - validate() will run packer validate on the packer templates, for a set of arguments (like consul nomad vault hashistack) 135 | - build() will build and deploy the images 136 | 137 | The following script can be used to parallelize the image build process: 138 | 139 | ``` 140 | build consul & 141 | build vault & 142 | build nomad & 143 | build hashistack & 144 | 145 | for job in `jobs -p`; do 146 | echo $job 147 | wait $job || let "FAIL+=1" 148 | done 149 | 150 | echo $FAIL 151 | 152 | if [ "$FAIL" == "0" ]; then 153 | echo -e "\033[32m\033[1m[BUILD SUCCESFUL]\033[0m" 154 | else 155 | echo -e "\033[31m\033[1m[BUILD ERROR]\033[0m" 156 | fi 157 | ``` 158 | 159 | --- 160 | 161 | ## Some notes on the CI pipeline 162 | 163 | - All images are built privately and then their launch permissions are updated by a Terraform Workspace hosted in Atlas (https://atlas.hashicorp.com/terraform/atlas-demo/environments/image-permission-aws/changes/runs). 164 | 165 | - Please do not update variables manually on the TFE job. They are updated by the CI process when it runs directly from the `versions.sh` file available in this repository. 166 | 167 | ## Image Version Table: 168 | 169 | | Release | Consul | Vault | Nomad | 170 | |-------------|-------------|-------------|-------------| 171 | | 0.1.0 | 1.2.0 | 0.10.3 | 0.8.4 | 172 | | 0.1.1 | 1.2.0-ent | 0.10.3-ent | 0.8.4-ent | 173 | | 0.1.2 | 1.2.1 | 0.10.3 | 0.8.4 | 174 | | 0.1.3 | 1.2.1-ent | 0.10.3-ent | 0.8.4-ent | 175 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'rspec/core/rake_task' 3 | require 'json' 4 | require 'pathname' 5 | require 'rainbow' 6 | require 'rspec/core/rake_task' 7 | require 'uri' 8 | require 'rake' 9 | require 'rspec/core/rake_task' 10 | 11 | namespace :consul do 12 | desc 'Run serverspec tests' 13 | RSpec::Core::RakeTask.new(:spec) do |t| 14 | t.pattern = ['spec/consul/*_spec.rb','spec/shared/*_spec.rb'] 15 | end 16 | 17 | 18 | desc 'Validate Templates' 19 | task :validate do 20 | Pathname.glob('consul/consul.json').sort.each do |template| 21 | puts Rainbow("Validating #{template}...").green 22 | unless system "packer validate #{template}" 23 | puts Rainbow("#{template} is not a valid packer template").red 24 | raise "#{template} is not a valid packer template" 25 | end 26 | end 27 | end 28 | 29 | desc 'Build Templates' 30 | task :build do 31 | Pathname.glob('consul/consul.json').sort.each do |template| 32 | unless system "packer build #{template}" 33 | puts Rainbow("#{template} build failed").red 34 | raise "#{template} built succesfully" 35 | end 36 | end 37 | end 38 | end 39 | 40 | namespace :nomad do 41 | desc 'Run serverspec tests' 42 | RSpec::Core::RakeTask.new(:spec) do |t| 43 | t.pattern = ['spec/consul/*_spec.rb','spec/nomad/*_spec.rb','spec/shared/*_spec.rb'] 44 | end 45 | 46 | 47 | desc 'Validate Templates' 48 | task :validate do 49 | Pathname.glob('nomad/nomad.json').sort.each do |template| 50 | puts Rainbow("Validating #{template}...").green 51 | unless system "packer validate #{template}" 52 | puts Rainbow("#{template} is not a valid packer template").red 53 | raise "#{template} is not a valid packer template" 54 | end 55 | end 56 | end 57 | 58 | desc 'Build Templates' 59 | task :build do 60 | Pathname.glob('nomad/nomad.json').sort.each do |template| 61 | unless system "packer build #{template}" 62 | puts Rainbow("#{template} build failed").red 63 | raise "#{template} built succesfully" 64 | end 65 | end 66 | end 67 | end 68 | 69 | namespace :vault do 70 | desc 'Run serverspec tests' 71 | RSpec::Core::RakeTask.new(:spec) do |t| 72 | t.pattern = ['spec/consul/*_spec.rb','spec/shared/*_spec.rb','spec/vault/*_spec.rb'] 73 | end 74 | 75 | 76 | desc 'Validate Templates' 77 | task :validate do 78 | Pathname.glob('vault/vault.json').sort.each do |template| 79 | puts Rainbow("Validating #{template}...").green 80 | unless system "packer validate #{template}" 81 | puts Rainbow("#{template} is not a valid packer template").red 82 | raise "#{template} is not a valid packer template" 83 | end 84 | end 85 | end 86 | 87 | desc 'Build Templates' 88 | task :build do 89 | Pathname.glob('vault/vault.json').sort.each do |template| 90 | unless system "packer build #{template}" 91 | puts Rainbow("#{template} build failed").red 92 | raise "#{template} built succesfully" 93 | end 94 | end 95 | end 96 | end 97 | 98 | namespace :hashistack do 99 | desc 'Run serverspec tests' 100 | RSpec::Core::RakeTask.new(:spec) do |t| 101 | t.pattern = ['spec/consul/*_spec.rb','spec/nomad/*_spec.rb','spec/shared/*_spec.rb','spec/vault/*_spec.rb'] 102 | end 103 | 104 | 105 | desc 'Validate Templates' 106 | task :validate do 107 | Pathname.glob('hashistack/hashistack.json').sort.each do |template| 108 | puts Rainbow("Validating #{template}...").green 109 | unless system "packer validate #{template}" 110 | puts Rainbow("#{template} is not a valid packer template").red 111 | raise "#{template} is not a valid packer template" 112 | end 113 | end 114 | end 115 | 116 | desc 'Build Templates' 117 | task :build do 118 | Pathname.glob('hashistack/hashistack.json').sort.each do |template| 119 | unless system "packer build #{template}" 120 | puts Rainbow("#{template} build failed").red 121 | raise "#{template} built succesfully" 122 | end 123 | end 124 | end 125 | end 126 | -------------------------------------------------------------------------------- /aws-local-env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # aws-local-env.sh 3 | # 4 | # Disclaimer: Building AWS Packer images locally has not been tested. The Azure process has. 5 | # 6 | # Variables you'll need to trigger Packer image builds locally 7 | # If you have an ~/.aws/credentials file, you'll need to override that with 8 | # the credentials given to you via this repo: https://github.com/hashicorp/licensing-binaries 9 | # and this job: https://tfe.hashicorp.engineering/terraform/licensing/environments/binaries/changes/runs 10 | # 11 | # The procedure for getting your binary credentials is documented in the [SE Handbook](https://docs.google.com/document/d/1lRYgJMIGejYbaxTpZmc3hnbj7aWRg7dFXCN3_x87mYQ/edit#heading=h.6blw4fxx8vz1) 12 | # 13 | # Below is one example of how to use it 14 | # 15 | # 16 | ## Example usage: 17 | # 18 | # $ cd /root/of/this/repository 19 | # $ source aws-local-env.sh 20 | # $ cd hashistack # or cd into any dir containing an AWS Packer build file 21 | # $ packer build hashistack.json 22 | # 23 | # TODO: See if we need a separate set of variables for the binary downloads 24 | # so we're not conflicting with the credentials being used to build the image. 25 | 26 | # Source versions from this repository 27 | source versions.sh 28 | 29 | if [ -z ${S3BUCKET} ]; then 30 | read -p $'\033[1;32mPlease enter an S3 bucket name for enterprise binary download: \033[0m' S3BUCKET 31 | export S3BUCKET="${S3BUCKET}" 32 | else 33 | export S3BUCKET="${S3BUCKET}" 34 | fi 35 | 36 | if [ -z ${AWS_ACCESS_KEY_ID} ]; then 37 | read -p $'\033[1;32mPlease enter an AWS access key ID for enterprise binary download: \033[0m' AWS_ACCESS_KEY_ID 38 | export AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" 39 | else 40 | export AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" 41 | fi 42 | 43 | if [ -z ${AWS_SECRET_ACCESS_KEY} ]; then 44 | read -p $'\033[1;32mPlease enter an AWS secret access key for enterprise binary download: \033[0m' AWS_SECRET_ACCESS_KEY 45 | export AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" 46 | else 47 | export AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" 48 | fi 49 | 50 | export VCS_NAME="local" 51 | export RELEASE_VERSION="${RELEASE_VERSION}" 52 | export CONSUL_VERSION="${CONSUL_VERSION}" 53 | export VAULT_VERSION="${VAULT_VERSION}" 54 | export NOMAD_VERSION="${NOMAD_VERSION}" 55 | # Re-source this file for every Packer run to re-generate URLs 56 | # They are set to expire after 10 minutes 57 | export CONSUL_ENT_URL=$(AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" \ 58 | AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" \ 59 | aws s3 presign \ 60 | --region="us-east-1" \ 61 | s3://${S3BUCKET}/consul-enterprise/${CONSUL_VERSION}/consul-enterprise_${CONSUL_VERSION}+ent_linux_amd64.zip \ 62 | --expires-in 600) 63 | export VAULT_ENT_URL=$(AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" \ 64 | AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" \ 65 | aws s3 presign \ 66 | --region="us-east-1" \ 67 | s3://${S3BUCKET}/vault/prem/${VAULT_VERSION}/vault-enterprise_${VAULT_VERSION}+prem_linux_amd64.zip \ 68 | --expires-in 600) 69 | export NOMAD_ENT_URL=$(AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" \ 70 | AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" \ 71 | aws s3 presign \ 72 | --region="us-east-1" \ 73 | s3://${S3BUCKET}/nomad-enterprise/${NOMAD_VERSION}/nomad-enterprise_${NOMAD_VERSION}+ent_linux_amd64.zip \ 74 | --expires-in 600) 75 | 76 | # Feel free to comment out the below reminder if you're familiar with this process 77 | echo -e "\n\033[0;32mBinary downloads generated by this script expire in 10 minutes." 78 | echo -e "Make sure to re-source this file to regenerate URLs for every Packer build." 79 | -------------------------------------------------------------------------------- /azure-local-env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # azure-local-env.sh 3 | # 4 | # Variables you'll need to trigger Packer image builds locally 5 | # If you have an ~/.aws/credentials file, you'll need to override that with 6 | # the credentials given to you via this repo: https://github.com/hashicorp/licensing-binaries 7 | # and this job: https://tfe.hashicorp.engineering/terraform/licensing/environments/binaries/changes/runs 8 | # 9 | # The procedure for getting your binary credentials is documented in the [SE Handbook](https://docs.google.com/document/d/1lRYgJMIGejYbaxTpZmc3hnbj7aWRg7dFXCN3_x87mYQ/edit#heading=h.6blw4fxx8vz1) 10 | # 11 | # Below is one example of how to use it 12 | # First, authenticate with Azure using this guide: https://www.terraform.io/docs/providers/azurerm/authenticating_via_azure_cli.html 13 | # There are also some useful tips for authenticating here: https://github.com/tdsacilowski/azure-consul 14 | # 15 | ## Example usage: 16 | # 17 | # $ cd /root/of/this/repository 18 | # $ source local-build-env.sh 19 | # $ cd hashistack # or cd into any dir containing an Azure Packer build file 20 | # $ packer build hashistack-azure.json 21 | # 22 | 23 | # Source versions from this repository 24 | source versions.sh 25 | 26 | if [ -z ${S3BUCKET} ]; then 27 | read -p $'\033[1;32mPlease enter an S3 bucket name for enterprise binary download: \033[0m' S3BUCKET 28 | export S3BUCKET="${S3BUCKET}" 29 | else 30 | export S3BUCKET="${S3BUCKET}" 31 | fi 32 | 33 | if [ -z ${AWS_ACCESS_KEY_ID} ]; then 34 | read -p $'\033[1;32mPlease enter an AWS access key ID for enterprise binary download: \033[0m' AWS_ACCESS_KEY_ID 35 | export AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" 36 | else 37 | export AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" 38 | fi 39 | 40 | if [ -z ${AWS_SECRET_ACCESS_KEY} ]; then 41 | read -p $'\033[1;32mPlease enter an AWS secret access key for enterprise binary download: \033[0m' AWS_SECRET_ACCESS_KEY 42 | export AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" 43 | else 44 | export AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" 45 | fi 46 | 47 | if [ -z ${AZURE_RESOURCE_GROUP} ]; then 48 | read -p $'\033[1;32mPlease enter an Azure resource group for image creation and storage: \033[0m' AZURE_RESOURCE_GROUP 49 | export AZURE_RESOURCE_GROUP="${AZURE_RESOURCE_GROUP}" 50 | else 51 | export AZURE_RESOURCE_GROUP="${AZURE_RESOURCE_GROUP}" 52 | fi 53 | 54 | if [ -z "${AZURE_LOCATION}" ]; then 55 | read -p $'\033[1;32mPlease enter an Azure location for image creation: \033[0m' AZURE_LOCATION 56 | export AZURE_LOCATION="${AZURE_LOCATION}" 57 | else 58 | export AZURE_LOCATION="${AZURE_LOCATION}" 59 | fi 60 | 61 | if [ -z ${PACKER_ENVIRONMENT} ]; then 62 | read -p $'\033[1;32mPlease enter an environment tag for your image: \033[0m' PACKER_ENVIRONMENT 63 | export PACKER_ENVIRONMENT="${PACKER_ENVIRONMENT}" 64 | else 65 | export PACKER_ENVIRONMENT="${PACKER_ENVIRONMENT}" 66 | fi 67 | 68 | ### 69 | 70 | if [ -z ${ARM_SUBSCRIPTION_ID} ]; then 71 | read -p $'\033[1;32mPlease enter your Azure subscription ID: \033[0m' ARM_SUBSCRIPTION_ID 72 | export ARM_SUBSCRIPTION_ID="${ARM_SUBSCRIPTION_ID}" 73 | export subscription_id="${ARM_SUBSCRIPTION_ID}" 74 | else 75 | export ARM_SUBSCRIPTION_ID="${ARM_SUBSCRIPTION_ID}" 76 | export subscription_id="${ARM_SUBSCRIPTION_ID}" 77 | fi 78 | 79 | if [ -z ${ARM_CLIENT_ID} ]; then 80 | read -p $'\033[1;32mPlease enter your Azure client ID: \033[0m' ARM_CLIENT_ID 81 | export ARM_CLIENT_ID="${ARM_CLIENT_ID}" 82 | export client_id="${ARM_CLIENT_ID}" 83 | else 84 | export ARM_CLIENT_ID="${ARM_CLIENT_ID}" 85 | export client_id="${ARM_CLIENT_ID}" 86 | fi 87 | 88 | if [ -z ${ARM_CLIENT_SECRET} ]; then 89 | read -p $'\033[1;32mPlease enter your Azure client secret: \033[0m' ARM_CLIENT_SECRET 90 | export ARM_CLIENT_SECRET="${ARM_CLIENT_SECRET}" 91 | export client_secret="${ARM_CLIENT_SECRET}" 92 | else 93 | export ARM_CLIENT_SECRET="${ARM_CLIENT_SECRET}" 94 | export client_secret="${ARM_CLIENT_SECRET}" 95 | fi 96 | 97 | if [ -z ${ARM_TENANT_ID} ]; then 98 | read -p $'\033[1;32mPlease enter your Azure tenant ID: \033[0m' ARM_TENANT_ID 99 | export ARM_TENANT_ID="${ARM_TENANT_ID}" 100 | else 101 | export ARM_TENANT_ID="${ARM_TENANT_ID}" 102 | fi 103 | 104 | if [ -z ${PACKER_ENVIRONMENT} ]; then 105 | read -p $'\033[1;32mPlease enter an environment tag for your image: \033[0m' PACKER_ENVIRONMENT 106 | export PACKER_ENVIRONMENT="${PACKER_ENVIRONMENT}" 107 | else 108 | export PACKER_ENVIRONMENT="${PACKER_ENVIRONMENT}" 109 | fi 110 | 111 | export VCS_NAME="local" 112 | export CONSUL_RELEASE="${CONSUL_VERSION}" 113 | export NOMAD_RELEASE="${NOMAD_VERSION}" 114 | export VAULT_RELEASE="${VAULT_VERSION}" 115 | export CONSUL_VERSION="${CONSUL_VERSION}" 116 | export NOMAD_VERSION="${NOMAD_VERSION}" 117 | export VAULT_VERSION="${VAULT_VERSION}" 118 | export DISTRIBUTION="ent" 119 | export CONSUL_VERSION="${CONSUL_RELEASE}" 120 | export VAULT_VERSION="${VAULT_RELEASE}" 121 | export NOMAD_VERSION="${NOMAD_RELEASE}" 122 | # Re-source this file for every Packer run to re-generate URLs 123 | # They are set to expire after 10 minutes 124 | export CONSUL_ENT_URL=$(AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" \ 125 | AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" \ 126 | aws s3 presign \ 127 | --region="us-east-1" \ 128 | s3://${S3BUCKET}/consul-enterprise/${CONSUL_VERSION}/consul-enterprise_${CONSUL_VERSION}+ent_linux_amd64.zip \ 129 | --expires-in 600) 130 | export VAULT_ENT_URL=$(AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" \ 131 | AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" \ 132 | aws s3 presign \ 133 | --region="us-east-1" \ 134 | s3://${S3BUCKET}/vault/prem/${VAULT_VERSION}/vault-enterprise_${VAULT_VERSION}+prem_linux_amd64.zip \ 135 | --expires-in 600) 136 | export NOMAD_ENT_URL=$(AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" \ 137 | AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" \ 138 | aws s3 presign \ 139 | --region="us-east-1" \ 140 | s3://${S3BUCKET}/nomad-enterprise/${NOMAD_VERSION}/nomad-enterprise_${NOMAD_VERSION}+ent_linux_amd64.zip \ 141 | --expires-in 600) 142 | 143 | # Feel free to comment out the below reminder if you're familiar with this process 144 | echo -e '\n\033[0;32mBinary downloads generated by this script expire in 10 minutes.' 145 | echo -e 'Make sure to re-source this file to regenerate URLs for every Packer build. \033[0m' 146 | -------------------------------------------------------------------------------- /ci-functions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script includes a set of generic CI functions to test Packer Builds. 4 | prepare () { 5 | rm -rf /tmp/packer 6 | curl -o /tmp/packer.zip https://releases.hashicorp.com/packer/${PACKER_VERSION}/packer_${PACKER_VERSION}_linux_amd64.zip 7 | unzip /tmp/packer.zip -d /tmp 8 | chmod +x /tmp/packer 9 | rm -rf /tmp/terraform 10 | curl -o /tmp/terraform.zip https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip 11 | unzip /tmp/terraform.zip -d /tmp 12 | chmod +x /tmp/terraform 13 | } 14 | 15 | validate () { 16 | for TEMPLATE in $*; do 17 | echo "cd into ${TEMPLATE} directory" 18 | cd ${BUILDDIR}/$(echo ${TEMPLATE} | sed 's/-.*//') 19 | echo "Reviewing ${TEMPLATE}.json template..." 20 | 21 | if /tmp/packer validate ${TEMPLATE}.json; then 22 | echo -e "\033[32m\033[1m[PASS]\033[0m" 23 | else 24 | echo -e "\033[31m\033[1m[FAIL]\033[0m" 25 | return 1 26 | fi 27 | 28 | cd - 29 | done 30 | 31 | echo "Reviewing shell scripts..." 32 | if find . -iname \*.sh -exec bash -n {} \; > /dev/null; then 33 | echo -e "\033[32m\033[1m[PASS]\033[0m" 34 | else 35 | echo -e "\033[31m\033[1m[FAIL]\033[0m" 36 | return 1 37 | fi 38 | } 39 | 40 | gpg_import () { 41 | echo ${PGP_SECRET_KEY} | base64 -d | gpg --import 42 | } 43 | 44 | gpg_cleanup () { 45 | echo "Cleaning up GPG Keyring..." 46 | rm -rf .gnupg 47 | } 48 | 49 | presign_ent_url () { 50 | if [ $# -eq 0 ]; then 51 | echo -e "\033[31m\033[1m[FAIL - no variables provided]\033[0m" 52 | return 1 53 | fi 54 | 55 | if [ $1 -eq 0 ]; then 56 | echo -e "\033[31m\033[1m[FAIL - no product name provided]\033[0m" 57 | return 1 58 | fi 59 | 60 | if [ $2 -eq 0 ]; then 61 | echo -e "\033[31m\033[1m[FAIL - no product version provided]\033[0m" 62 | return 1 63 | fi 64 | 65 | _AWS_SECRET_ACCESS_KEY=$(echo $AWS_SECRET_ACCESS_KEY_BINARY | base64 -d | gpg -d -) 66 | _AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID_BINARY} 67 | _REGION="us-east-1" 68 | _PRODUCT=$1 69 | _VERSION=$2 70 | 71 | if [ ${_PRODUCT} = "consul" ]; then 72 | _S3_URL=s3://${S3BUCKET}/consul/prem/${_VERSION}/consul-enterprise_${_VERSION}+prem_linux_amd64.zip 73 | elif [ ${_PRODUCT} = "vault" ]; then 74 | _S3_URL=s3://${S3BUCKET}/vault/prem/${_VERSION}/vault-enterprise_${_VERSION}+prem_linux_amd64.zip 75 | elif [ ${_PRODUCT} = "nomad" ]; then 76 | _S3_URL=s3://${S3BUCKET}/nomad-enterprise/${_VERSION}/nomad-enterprise_${_VERSION}+ent_linux_amd64.zip 77 | else 78 | echo -e "\033[31m\033[1m[FAIL - invalid product selection for S3 enterprise URL]\033[0m" 79 | return 1 80 | fi 81 | 82 | echo "$(AWS_SECRET_ACCESS_KEY=${_AWS_SECRET_ACCESS_KEY} \ 83 | AWS_ACCESS_KEY_ID=${_AWS_ACCESS_KEY_ID} \ 84 | aws s3 presign \ 85 | --region=${_REGION} \ 86 | ${_S3_URL} )" 87 | } 88 | 89 | prepare_ent_urls () { 90 | if [[ ${CONSUL_VERSION} == *"ent"* ]]; then 91 | export CONSUL_VERSION_STRIPPED=${CONSUL_VERSION/"-ent"/} 92 | export CONSUL_ENT_URL=$(presign_ent_url consul ${CONSUL_VERSION_STRIPPED}) 93 | echo "CONSUL_VERSION_STRIPPED: ${CONSUL_VERSION_STRIPPED}" 94 | echo "CONSUL_ENT_URL: ${CONSUL_ENT_URL}" 95 | echo "CONSUL_VERSION: ${CONSUL_VERSION}" 96 | fi 97 | 98 | if [[ ${VAULT_VERSION} == *"ent"* ]]; then 99 | export VAULT_VERSION_STRIPPED=${VAULT_VERSION/"-ent"/} 100 | export VAULT_ENT_URL=$(presign_ent_url vault ${VAULT_VERSION_STRIPPED}) 101 | echo "VAULT_VERSION_STRIPPED: ${VAULT_VERSION_STRIPPED}" 102 | echo "VAULT_ENT_URL: ${VAULT_ENT_URL}" 103 | echo "VAULT_VERSION: ${VAULT_VERSION}" 104 | fi 105 | 106 | if [[ ${NOMAD_VERSION} == *"ent"* ]]; then 107 | export NOMAD_VERSION_STRIPPED=${NOMAD_VERSION/"-ent"/} 108 | export NOMAD_ENT_URL=$(presign_ent_url nomad ${NOMAD_VERSION_STRIPPED}) 109 | echo "NOMAD_VERSION_STRIPPED: ${NOMAD_VERSION_STRIPPED}" 110 | echo "NOMAD_ENT_URL: ${NOMAD_ENT_URL}" 111 | echo "NOMAD_VERSION: ${NOMAD_VERSION}" 112 | fi 113 | } 114 | 115 | build () { 116 | if [ -z ${RELEASE_VERSION} ]; then 117 | # Set RELEASE_VERSION to the current git branch if not specified so it's not empty 118 | export RELEASE_VERSION=${GIT_BRANCH} 119 | fi 120 | 121 | if [ -z ${USER_TRIGGER+x} ]; then 122 | export VCS_NAME="Manual" 123 | else 124 | export VCS_NAME=${GIT_BRANCH} 125 | fi 126 | 127 | echo "Starting build from ${GIT_BRANCH}" 128 | echo "RELEASE_VERSION: ${RELEASE_VERSION}" 129 | echo "VCS_NAME: ${VCS_NAME}" 130 | echo "Building Consul version: ${CONSUL_VERSION}" 131 | echo "Building Vault version: ${VAULT_VERSION}" 132 | echo "Building Nomad version: ${NOMAD_VERSION}" 133 | 134 | for TEMPLATE in $*; do 135 | echo "cd into ${TEMPLATE} directory" 136 | cd ${BUILDDIR}/$(echo ${TEMPLATE} | sed 's/-.*//') 137 | echo "Building ${TEMPLATE}.json Packer template..." 138 | 139 | if /tmp/packer build ${TEMPLATE}.json ; then 140 | echo -e "\033[32m${TEMPLATE} \033[1m[PASS]\033[0m" 141 | else 142 | echo -e "\033[31m${TEMPLATE} \033[1m[FAIL]\033[0m" 143 | return 1 144 | fi 145 | 146 | cd - 147 | done 148 | 149 | echo "Completed build from ${GIT_BRANCH}" 150 | } 151 | 152 | publish () { 153 | # Exit early if not on master branch or RUN_PUBLISH env var not passed 154 | echo "GIT_BRANCH: ${GIT_BRANCH}" 155 | echo "RUN_PUBLISH: ${RUN_PUBLISH}" 156 | 157 | export PATH=$PATH:/tmp 158 | rm -rf guides-image-permissions 159 | git clone --recurse-submodules https://${GITHUB_USERNAME}:${GITHUB_TOKEN}@github.com/hashicorp/guides-image-permissions 160 | cd guides-image-permissions/aws-images 161 | 162 | /tmp/terraform init 163 | 164 | echo "Push variables" 165 | ../tfe-cli/bin/tfe pushvars -hcl-var ${RELEASE_VERSIONS} -overwrite release_versions 166 | ../tfe-cli/bin/tfe pushvars -hcl-var ${CONSUL_VERSIONS} -overwrite consul_versions 167 | ../tfe-cli/bin/tfe pushvars -hcl-var ${VAULT_VERSIONS} -overwrite vault_versions 168 | ../tfe-cli/bin/tfe pushvars -hcl-var ${NOMAD_VERSIONS} -overwrite nomad_versions 169 | 170 | echo "Remove downloaded Terraform modules to prevent TFE error" 171 | rm -rf .terraform/modules/ 172 | 173 | echo "Push config" 174 | ../tfe-cli/bin/tfe pushconfig 175 | } 176 | -------------------------------------------------------------------------------- /consul-template/scripts/install-consul-template.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | echo "Running" 5 | 6 | CONSUL_TEMPLATE_VERSION=${VERSION:-0.19.4} 7 | CONSUL_TEMPLATE_ZIP=consul-template_${CONSUL_TEMPLATE_VERSION}_linux_amd64.zip 8 | CONSUL_TEMPLATE_URL=${URL:-https://releases.hashicorp.com/consul-template/${CONSUL_TEMPLATE_VERSION}/${CONSUL_TEMPLATE_ZIP}} 9 | CONSUL_TEMPLATE_USER=${USER:-consul-template} 10 | CONSUL_TEMPLATE_GROUP=${GROUP:-consul-template} 11 | CONFIG_DIR=/etc/consul-template.d 12 | DATA_DIR=/opt/consul-template/data 13 | DOWNLOAD_DIR=/tmp 14 | 15 | echo "Downloading consul-template ${CONSUL_TEMPLATE_VERSION}" 16 | curl --silent --output ${DOWNLOAD_DIR}/${CONSUL_TEMPLATE_ZIP} ${CONSUL_TEMPLATE_URL} 17 | 18 | echo "Installing consul-template" 19 | sudo unzip -o ${DOWNLOAD_DIR}/${CONSUL_TEMPLATE_ZIP} -d /usr/local/bin/ 20 | sudo chmod 0755 /usr/local/bin/consul-template 21 | sudo chown ${CONSUL_TEMPLATE_USER}:${CONSUL_TEMPLATE_GROUP} /usr/local/bin/consul-template 22 | 23 | echo "/usr/local/bin/consul-template --version: $(/usr/local/bin/consul-template --version)" 24 | 25 | echo "Configuring consul-template" 26 | sudo mkdir -pm 0755 ${CONFIG_DIR} ${DATA_DIR} 27 | sudo chown -R ${CONSUL_TEMPLATE_USER}:${CONSUL_TEMPLATE_GROUP} ${CONFIG_DIR} ${DATA_DIR} 28 | sudo chmod -R 0644 ${CONFIG_DIR}/* 29 | 30 | echo "Complete" 31 | -------------------------------------------------------------------------------- /consul/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Networking 5 | private_ip = ENV['PRIVATE_IP'] || "192.168.50.161" 6 | 7 | # Base box selection 8 | base_box = ENV['BASE_BOX'] || "bento/ubuntu-16.04" 9 | 10 | # Consul variables 11 | consul_host_port = ENV['CONSUL_HOST_PORT'] || 8500 12 | consul_version = ENV['CONSUL_VERSION'] || "1.2.0" 13 | consul_ent_url = ENV['CONSUL_ENT_URL'] 14 | consul_group = "consul" 15 | consul_user = "consul" 16 | consul_comment = "Consul" 17 | consul_home = "/srv/consul" 18 | 19 | # Wetty variables 20 | wetty_host_port = ENV['WETTY_HOST_PORT'] || 3030 21 | wetty_install = ["true", "1"].include?((ENV['WETTY_INSTALL'] || true).to_s.downcase) 22 | wetty_group = ENV['WETTY_GROUP'] || "wetty" 23 | wetty_user = ENV['WETTY_USER'] || "wetty" 24 | wetty_password = ENV['WETTY_PASSWORD'] || "wetty" 25 | wetty_comment = "Wetty Web Terminal SSH user" 26 | 27 | # Tests & cleanup 28 | run_tests = ["true", "1"].include?((ENV['RUN_TESTS'] || false).to_s.downcase) 29 | cleanup = ["true", "1"].include?((ENV['CLEANUP'] || true).to_s.downcase) 30 | 31 | Vagrant.configure("2") do |config| 32 | # Use vagrant insecure public key, comment this out to restrict access 33 | config.ssh.insert_key = false 34 | 35 | # Setup networking 36 | config.vm.network :private_network, ip: private_ip 37 | config.vm.network "private_network", type: "dhcp" 38 | 39 | # Use base_box set at the top of this file 40 | config.vm.box = base_box 41 | config.vm.hostname = "consul" 42 | 43 | # Copy the Consul and shared directories to the vm 44 | config.vm.provision "file", source: "../../guides-configuration", destination: "/tmp" 45 | 46 | # Bootstrap the vm 47 | config.vm.provision "shell", inline: "bash /tmp/shared/scripts/base.sh" 48 | 49 | # Forward Consul port 50 | config.vm.network :forwarded_port, guest: 8500, host: consul_host_port, auto_correct: true 51 | 52 | # Setup Consul user 53 | config.vm.provision "shell", inline: "bash /tmp/shared/scripts/setup-user.sh", 54 | env: { 55 | "GROUP" => consul_group, 56 | "USER" => consul_user, 57 | "COMMENT" => consul_comment, 58 | "HOME" => consul_home, 59 | } 60 | 61 | # Install Consul 62 | config.vm.provision "shell", inline: "bash /tmp/consul/scripts/install-consul.sh", 63 | env: { 64 | "VERSION" => consul_version, 65 | "URL" => consul_ent_url, 66 | "USER" => consul_user, 67 | "GROUP" => consul_group, 68 | } 69 | 70 | config.vm.provision "shell", inline: "bash /tmp/consul/scripts/install-consul-systemd.sh" 71 | 72 | if (wetty_install) 73 | # Forward Wetty port 74 | config.vm.network :forwarded_port, guest: 3030, host: wetty_host_port, auto_correct: true 75 | 76 | # Install Wetty 77 | config.vm.provision "shell", inline: "bash /tmp/shared/scripts/web-terminal.sh" 78 | config.vm.provision "shell", inline: "bash /tmp/shared/scripts/setup-ssh-user.sh", 79 | env: { 80 | "GROUP" => wetty_group, 81 | "USER" => wetty_user, 82 | "PASSWORD" => wetty_password, 83 | "COMMENT" => wetty_comment, 84 | } 85 | end 86 | 87 | # Run tests if `RUN_TESTS` env var is provided 88 | if (run_tests) 89 | config.vm.provision "shell", inline: "cd /tmp && bash /tmp/shared/scripts/setup-testing.sh" 90 | config.vm.provision "shell", inline: "cd /tmp && rake consul:spec" 91 | end 92 | 93 | # Cleanup if `CLEANUP` env var is provided 94 | if (cleanup) 95 | config.vm.provision "shell", inline: "bash /tmp/shared/scripts/cleanup.sh" 96 | end 97 | 98 | # Increase memory for Parallels Desktop 99 | config.vm.provider "parallels" do |p, o| 100 | p.memory = "1024" 101 | end 102 | 103 | # Increase memory for Virtualbox 104 | config.vm.provider "virtualbox" do |vb| 105 | vb.memory = "1024" 106 | end 107 | 108 | # Increase memory for VMware 109 | ["vmware_fusion", "vmware_workstation"].each do |p| 110 | config.vm.provider p do |v| 111 | v.vmx["memsize"] = "1024" 112 | end 113 | end 114 | 115 | config.vm.post_up_message = " 116 | Your Consul dev cluster has been successfully provisioned! 117 | 118 | To SSH into the Consul host, run the below command. 119 | 120 | $ vagrant ssh 121 | 122 | You can now interact with Consul using any of the CLI (https://www.consul.io/docs/commands/index.html) 123 | or API (https://www.consul.io/api/index.html) commands. 124 | 125 | # Use the CLI to retrieve the Consul members, write a key/value, and read that key/value 126 | $ consul members 127 | $ consul kv put cli bar=baz 128 | $ consul kv get cli 129 | 130 | # Use the API to retrieve the Consul members, write a key/value, and read that key/value 131 | $ curl http://127.0.0.1:8500/v1/agent/members | jq '.' 132 | $ curl -X PUT -d 'bar=baz' http://127.0.0.1:8500/v1/kv/api | jq '.' 133 | $ curl http://127.0.0.1:8500/v1/kv/api | jq '.' 134 | 135 | Visit the Consul UI: http://#{private_ip}:#{consul_host_port} 136 | #{wetty_install ? 'Visit the Web Terminal (u: ' + wetty_user + '/p: ' + wetty_password + '): http://' + private_ip + ':' + wetty_host_port.to_s : ''} 137 | 138 | Don't forget to tear your VM down after. 139 | 140 | $ vagrant destroy 141 | " 142 | end 143 | -------------------------------------------------------------------------------- /consul/consul-aws.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "aws_access_key_id": "{{ env `AWS_ACCESS_KEY_ID` }}", 4 | "aws_secret_access_key": "{{ env `AWS_SECRET_ACCESS_KEY` }}", 5 | "aws_region": "{{ env `AWS_REGION` }}", 6 | "release_version": "{{ env `RELEASE_VERSION` }}", 7 | "vcs_name": "{{ env `VCS_NAME` }}", 8 | "consul_version": "{{ env `CONSUL_VERSION` }}", 9 | "consul_ent_url": "{{ env `CONSUL_ENT_URL` }}", 10 | "consul_group": "consul", 11 | "consul_user": "consul", 12 | "consul_comment": "Consul", 13 | "consul_home": "/srv/consul" 14 | }, 15 | "builders": [ 16 | { 17 | "name": "amazon-ebs-rhel-7.3-systemd", 18 | "type": "amazon-ebs", 19 | "access_key": "{{ user `aws_access_key_id` }}", 20 | "secret_key": "{{ user `aws_secret_access_key` }}", 21 | "region": "{{ user `aws_region` }}", 22 | "force_deregister": true, 23 | "force_delete_snapshot": true, 24 | "ssh_pty": true, 25 | "instance_type": "t2.medium", 26 | "associate_public_ip_address": true, 27 | "source_ami_filter": { 28 | "filters": { 29 | "virtualization-type": "hvm", 30 | "name": "*RHEL-7.3_HVM_GA-*", 31 | "root-device-type": "ebs" 32 | }, 33 | "owners": ["309956199498"], 34 | "most_recent": true 35 | }, 36 | "ssh_username": "ec2-user", 37 | "ssh_timeout": "5m", 38 | "ami_virtualization_type": "hvm", 39 | "ami_name": "consul-image_{{ user `release_version` }}_consul_{{ user `consul_version` }}_rhel_7.3", 40 | "ami_description": "HashiCorp Consul Image {{ user `release_version` }}", 41 | "tags": { 42 | "Name": "Consul RHEL 7.3 Image {{ user `release_version` }}: Consul v{{ user `consul_version` }}", 43 | "System": "Consul", 44 | "Product": "Consul", 45 | "Built-By": "{{ user `vcs_name` }}", 46 | "Release-Version": "{{ user `release_version` }}", 47 | "Consul-Version": "{{ user `consul_version` }}", 48 | "Vault-Version": "nil", 49 | "Nomad-Version": "nil", 50 | "OS": "rhel", 51 | "OS-Version": "7.3" 52 | } 53 | }, 54 | { 55 | "name": "amazon-ebs-ubuntu-16.04-systemd", 56 | "type": "amazon-ebs", 57 | "access_key": "{{ user `aws_access_key_id` }}", 58 | "secret_key": "{{ user `aws_secret_access_key` }}", 59 | "region": "{{ user `aws_region` }}", 60 | "force_deregister": true, 61 | "force_delete_snapshot": true, 62 | "ssh_pty": true, 63 | "instance_type": "t2.medium", 64 | "associate_public_ip_address": true, 65 | "source_ami_filter": { 66 | "filters": { 67 | "virtualization-type": "hvm", 68 | "name": "*ubuntu-xenial-16.04-amd64-server-*", 69 | "root-device-type": "ebs" 70 | }, 71 | "owners": ["099720109477"], 72 | "most_recent": true 73 | }, 74 | "ssh_username": "ubuntu", 75 | "ssh_timeout": "10m", 76 | "ami_virtualization_type": "hvm", 77 | "ami_name": "consul-image_{{ user `release_version` }}_consul_{{ user `consul_version` }}_ubuntu_16.04", 78 | "ami_description": "HashiCorp Consul Image {{ user `release_version` }}", 79 | "tags": { 80 | "Name": "Consul Ubuntu 16.04 Image {{ user `release_version` }}: Consul v{{ user `consul_version` }}", 81 | "System": "Consul", 82 | "Product": "Consul", 83 | "Built-By": "{{ user `vcs_name` }}", 84 | "Release-Version": "{{ user `release_version` }}", 85 | "Consul-Version": "{{ user `consul_version` }}", 86 | "Vault-Version": "nil", 87 | "Nomad-Version": "nil", 88 | "OS": "ubuntu", 89 | "OS-Version": "16.04" 90 | } 91 | } 92 | ], 93 | "provisioners": [ 94 | { 95 | "type": "file", 96 | "source": "../", 97 | "destination": "/tmp" 98 | }, 99 | { 100 | "type": "shell", 101 | "inline": [ 102 | "bash /tmp/shared/scripts/base.sh" 103 | ] 104 | }, 105 | { 106 | "type": "shell", 107 | "only": ["amazon-ebs-rhel-7.3-systemd", "amazon-ebs-ubuntu-16.04-systemd"], 108 | "inline": [ 109 | "bash /tmp/shared/scripts/base-aws.sh" 110 | ] 111 | }, 112 | { 113 | "type": "shell", 114 | "environment_vars": [ 115 | "GROUP={{ user `consul_group` }}", 116 | "USER={{ user `consul_user` }}", 117 | "COMMENT={{ user `consul_comment` }}", 118 | "HOME={{ user `consul_home` }}" 119 | ], 120 | "inline": [ 121 | "bash /tmp/shared/scripts/setup-user.sh" 122 | ] 123 | }, 124 | { 125 | "type": "shell", 126 | "environment_vars": [ 127 | "VERSION={{ user `consul_version` }}", 128 | "URL={{ user `consul_ent_url` }}", 129 | "USER={{ user `consul_user` }}", 130 | "GROUP={{ user `consul_group` }}" 131 | ], 132 | "inline": [ 133 | "bash /tmp/consul/scripts/install-consul.sh" 134 | ] 135 | }, 136 | { 137 | "type": "shell", 138 | "only": ["amazon-ebs-rhel-7.3-systemd", "amazon-ebs-ubuntu-16.04-systemd"], 139 | "inline": [ 140 | "bash /tmp/consul/scripts/install-consul-systemd.sh" 141 | ] 142 | }, 143 | { 144 | "type": "shell", 145 | "only": ["amazon-ebs-rhel-7.3-systemd", "amazon-ebs-ubuntu-16.04-systemd"], 146 | "inline": [ 147 | "cd /tmp/shared/scripts && bash /tmp/shared/scripts/setup-testing.sh", 148 | "cd /tmp && rake consul:spec" 149 | ] 150 | }, 151 | { 152 | "type": "shell", 153 | "only": ["amazon-ebs-rhel-7.3-systemd", "amazon-ebs-ubuntu-16.04-systemd"], 154 | "inline": [ 155 | "bash /tmp/shared/scripts/cleanup-aws.sh" 156 | ] 157 | }, 158 | { 159 | "type": "shell", 160 | "inline": [ 161 | "bash /tmp/shared/scripts/cleanup.sh" 162 | ] 163 | } 164 | ] 165 | } 166 | -------------------------------------------------------------------------------- /consul/consul-azure.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "azure_client_id": "{{ env `ARM_CLIENT_ID` }}", 4 | "azure_client_secret": "{{ env `ARM_CLIENT_SECRET` }}", 5 | "azure_subscription_id": "{{ env `ARM_SUBSCRIPTION_ID` }}", 6 | "azure_resource_group": "{{ env `AZURE_RESOURCE_GROUP` }}", 7 | "azure_location": "{{ env `AZURE_LOCATION` }}", 8 | "environment": "{{ env `PACKER_ENVIRONMENT` }}", 9 | "vcs_name": "{{ env `VCS_NAME` }}", 10 | "consul_version": "{{ env `CONSUL_VERSION` }}", 11 | "consul_ent_url": "{{ env `CONSUL_ENT_URL` }}" 12 | }, 13 | "builders": [ 14 | { 15 | "name": "azure-manaaged-image-ubuntu-16.04-systemd", 16 | "type": "azure-arm", 17 | "client_id": "{{ user `azure_client_id` }}", 18 | "client_secret": "{{ user `azure_client_secret` }}", 19 | "subscription_id": "{{ user `azure_subscription_id` }}", 20 | "managed_image_resource_group_name": "{{ user `azure_resource_group` }}", 21 | "location": "{{ user `azure_location` }}", 22 | "image_publisher": "Canonical", 23 | "image_offer": "UbuntuServer", 24 | "image_sku": "16.04-LTS", 25 | "os_type": "Linux", 26 | "ssh_username": "packer", 27 | "managed_image_name": "{{ user `environment` }}-consul-server-{{ user `consul_version` }}-Ubuntu_16.04", 28 | "azure_tags": { 29 | "Name": "Consul Server {{ user `consul_version` }}", 30 | "System": "Consul", 31 | "Product": "Consul", 32 | "Environment": "{{ user `environment` }}", 33 | "Built-By": "{{ user `vcs_name` }}", 34 | "Product-Version": "{{ user `consul_version` }}", 35 | "OS": "Ubuntu", 36 | "OS-Version": "16.04" 37 | } 38 | } 39 | ], 40 | "provisioners": [ 41 | { 42 | "type": "file", 43 | "source": "../shared", 44 | "destination": "/tmp" 45 | }, 46 | { 47 | "type": "file", 48 | "source": "../consul", 49 | "destination": "/tmp" 50 | }, 51 | { 52 | "type": "shell", 53 | "inline": [ 54 | "bash /tmp/shared/scripts/base.sh" 55 | ] 56 | }, 57 | { 58 | "type": "shell", 59 | "only": [ 60 | "azure-manaaged-image-ubuntu-16.04-systemd" 61 | ], 62 | "inline": [ 63 | "bash /tmp/shared/scripts/base-azure.sh" 64 | ] 65 | }, 66 | { 67 | "type": "shell", 68 | "environment_vars": [ 69 | "USER=consul", 70 | "GROUP=consul", 71 | "COMMENT=Consul", 72 | "HOME=/srv/consul" 73 | ], 74 | "inline": [ 75 | "bash /tmp/shared/scripts/setup-user.sh" 76 | ] 77 | }, 78 | { 79 | "type": "shell", 80 | "environment_vars": [ 81 | "VERSION={{ user `consul_version` }}", 82 | "URL={{ user `consul_ent_url` }}" 83 | ], 84 | "inline": [ 85 | "bash /tmp/consul/scripts/install-consul.sh" 86 | ] 87 | }, 88 | { 89 | "type": "shell", 90 | "only": [ 91 | "azure-manaaged-image-ubuntu-16.04-systemd" 92 | ], 93 | "inline": [ 94 | "bash /tmp/consul/scripts/install-consul-systemd.sh" 95 | ] 96 | }, 97 | { 98 | "type": "shell", 99 | "only": [ 100 | "azure-manaaged-image-ubuntu-16.04-systemd" 101 | ], 102 | "inline": [ 103 | "cd /tmp/shared/scripts && bash setup-testing.sh", 104 | "cd /tmp/consul && rake spec" 105 | ] 106 | }, 107 | { 108 | "type": "shell", 109 | "inline": [ 110 | "bash /tmp/shared/scripts/cleanup.sh" 111 | ] 112 | }, 113 | { 114 | "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'", 115 | "inline": [ 116 | "apt-get update -qq -y", 117 | "apt-get upgrade -qq -y", 118 | 119 | "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync" 120 | ], 121 | "inline_shebang": "/bin/sh -x", 122 | "type": "shell" 123 | } 124 | ] 125 | } -------------------------------------------------------------------------------- /consul/init/systemd/consul-online.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Consul Online 3 | Requires=consul.service 4 | After=consul.service 5 | 6 | [Service] 7 | Type=oneshot 8 | ExecStart=/usr/bin/consul-online.sh 9 | User=consul 10 | Group=consul 11 | 12 | [Install] 13 | WantedBy=consul-online.target multi-user.target 14 | -------------------------------------------------------------------------------- /consul/init/systemd/consul-online.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -o pipefail 5 | 6 | CONSUL_HTTP_ADDR=${1:-"http://127.0.0.1:8500"} 7 | 8 | # waitForConsulToBeAvailable loops until the local Consul agent returns a 200 9 | # response at the /v1/operator/raft/configuration endpoint. 10 | # 11 | # Parameters: 12 | # None 13 | function waitForConsulToBeAvailable() { 14 | local consul_http_addr=$1 15 | local consul_leader_http_code 16 | 17 | consul_leader_http_code=$(curl --silent --output /dev/null --write-out "%{http_code}" "${consul_http_addr}/v1/operator/raft/configuration") || consul_leader_http_code="" 18 | 19 | while [ "x${consul_leader_http_code}" != "x200" ] ; do 20 | echo "Waiting for Consul to get a leader..." 21 | sleep 5 22 | consul_leader_http_code=$(curl --silent --output /dev/null --write-out "%{http_code}" "${consul_http_addr}/v1/operator/raft/configuration") || consul_leader_http_code="" 23 | done 24 | } 25 | 26 | waitForConsulToBeAvailable "${CONSUL_HTTP_ADDR}" 27 | -------------------------------------------------------------------------------- /consul/init/systemd/consul-online.target: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Consul Online 3 | RefuseManualStart=true 4 | -------------------------------------------------------------------------------- /consul/init/systemd/consul-snapshot.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Consul Snapshot Agent 3 | Requires=consul-online.target 4 | After=consul-online.target 5 | 6 | [Service] 7 | Restart=on-failure 8 | PermissionsStartOnly=true 9 | ExecStart=/usr/bin/consul snapshot agent -config-dir /etc/consul-snapshot.d 10 | ExecReload=/bin/kill -HUP $MAINPID 11 | KillSignal=SIGTERM 12 | User=consulsnapshot 13 | Group=consulsnapshot 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /consul/init/systemd/consul.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Consul Agent 3 | Requires=network-online.target 4 | After=network-online.target 5 | 6 | [Service] 7 | Restart=on-failure 8 | EnvironmentFile=/etc/consul.d/consul.conf 9 | ExecStart=/usr/local/bin/consul agent -config-dir /etc/consul.d $FLAGS 10 | ExecReload=/bin/kill -HUP $MAINPID 11 | KillSignal=SIGTERM 12 | User=consul 13 | Group=consul 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /consul/scripts/install-consul-systemd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | echo "Running" 5 | 6 | # Detect package management system. 7 | YUM=$(which yum 2>/dev/null) 8 | APT_GET=$(which apt-get 2>/dev/null) 9 | 10 | if [[ ! -z ${YUM} ]]; then 11 | SYSTEMD_DIR="/etc/systemd/system" 12 | echo "Installing consul systemd service for RHEL/CentOS" 13 | elif [[ ! -z ${APT_GET} ]]; then 14 | SYSTEMD_DIR="/lib/systemd/system" 15 | echo "Installing consul systemd service for Debian/Ubuntu" 16 | else 17 | echo "Service not installed due to OS detection failure" 18 | exit 1; 19 | fi 20 | 21 | sudo curl --silent -Lo ${SYSTEMD_DIR}/consul.service https://raw.githubusercontent.com/hashicorp/guides-configuration/master/consul/init/systemd/consul.service 22 | sudo chmod 0664 ${SYSTEMD_DIR}/consul.service 23 | 24 | sudo systemctl enable consul 25 | sudo systemctl start consul 26 | 27 | echo "Complete" 28 | -------------------------------------------------------------------------------- /consul/scripts/install-consul.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | echo "Running" 5 | 6 | CONSUL_VERSION=${VERSION} 7 | CONSUL_ZIP=consul_${CONSUL_VERSION}_linux_amd64.zip 8 | CONSUL_URL=${URL:-https://releases.hashicorp.com/consul/${CONSUL_VERSION}/${CONSUL_ZIP}} 9 | CONSUL_DIR=/usr/local/bin 10 | CONSUL_PATH=${CONSUL_DIR}/consul 11 | CONSUL_CONFIG_DIR=/etc/consul.d 12 | CONSUL_DATA_DIR=/opt/consul/data 13 | CONSUL_TLS_DIR=/opt/consul/tls 14 | CONSUL_ENV_VARS=${CONSUL_CONFIG_DIR}/consul.conf 15 | CONSUL_PROFILE_SCRIPT=/etc/profile.d/consul.sh 16 | 17 | echo "Downloading Consul ${CONSUL_VERSION}" 18 | [ 200 -ne $(curl --write-out %{http_code} --silent --output /tmp/${CONSUL_ZIP} ${CONSUL_URL}) ] && exit 1 19 | 20 | echo "Installing Consul" 21 | sudo unzip -o /tmp/${CONSUL_ZIP} -d ${CONSUL_DIR} 22 | sudo chmod 0755 ${CONSUL_PATH} 23 | sudo chown ${USER}:${GROUP} ${CONSUL_PATH} 24 | echo "$(${CONSUL_PATH} --version)" 25 | 26 | echo "Configuring Consul ${CONSUL_VERSION}" 27 | sudo mkdir -pm 0755 ${CONSUL_CONFIG_DIR} ${CONSUL_DATA_DIR} ${CONSUL_TLS_DIR} 28 | 29 | echo "Start Consul in -dev mode" 30 | sudo tee ${CONSUL_ENV_VARS} > /dev/null < /dev/null </dev/null 46 | 47 | echo "Allow consul sudo access for echo, tee, cat, sed, and systemctl" 48 | sudo tee /etc/sudoers.d/consul > /dev/null </dev/null) 54 | APT_GET=$(which apt-get 2>/dev/null) 55 | 56 | if [[ ! -z ${YUM} ]]; then 57 | echo "Installing dnsmasq via yum" 58 | sudo yum install -q -y dnsmasq 59 | elif [[ ! -z ${APT_GET} ]]; then 60 | echo "Installing dnsmasq via apt-get" 61 | sudo apt-get -qq -y update 62 | sudo apt-get install -qq -y dnsmasq-base dnsmasq 63 | else 64 | echo "Dnsmasq not installed due to OS detection failure" 65 | exit 1; 66 | fi 67 | 68 | echo "Update resolv.conf" 69 | sudo sed -i '1i nameserver 127.0.0.1\n' /etc/resolv.conf 70 | 71 | echo "Configuring dnsmasq to forward .consul requests to consul port 8600" 72 | sudo tee /etc/dnsmasq.d/consul > /dev/null < /dev/null < consul_group, 89 | "USER" => consul_user, 90 | "COMMENT" => consul_comment, 91 | "HOME" => consul_home 92 | } 93 | 94 | # Install Consul 95 | config.vm.provision "shell", inline: "bash /tmp/consul/scripts/install-consul.sh", 96 | env: { 97 | "VERSION" => consul_version, 98 | "URL" => consul_ent_url, 99 | "USER" => consul_user, 100 | "GROUP" => consul_group, 101 | } 102 | 103 | config.vm.provision "shell", inline: "bash /tmp/consul/scripts/install-consul-systemd.sh" 104 | 105 | # Forward Vault port 106 | config.vm.network :forwarded_port, guest: 8200, host: vault_host_port, auto_correct: true 107 | 108 | # Setup Vault user 109 | config.vm.provision "shell", inline: "bash /tmp/shared/scripts/setup-user.sh", 110 | env: { 111 | "GROUP" => vault_group, 112 | "USER" => vault_user, 113 | "COMMENT" => vault_comment, 114 | "HOME" => vault_home, 115 | } 116 | 117 | # Install Vault 118 | config.vm.provision "shell", inline: "bash /tmp/vault/scripts/install-vault.sh", 119 | env: { 120 | "VERSION" => vault_version, 121 | "URL" => vault_ent_url, 122 | "USER" => vault_user, 123 | "GROUP" => vault_group, 124 | } 125 | 126 | config.vm.provision "shell", inline: "bash /tmp/vault/scripts/install-vault-systemd.sh" 127 | 128 | # Forward Nomad port 129 | config.vm.network :forwarded_port, guest: 4646, host: nomad_host_port, auto_correct: true 130 | 131 | # Install Nomad 132 | config.vm.provision "shell", inline: "bash /tmp/nomad/scripts/install-nomad.sh", 133 | env: { 134 | "VERSION" => nomad_version, 135 | "URL" => nomad_ent_url, 136 | "USER" => nomad_user, 137 | "GROUP" => nomad_group, 138 | } 139 | 140 | config.vm.provision "shell", inline: "bash /tmp/nomad/scripts/install-nomad-systemd.sh" 141 | config.vm.provision "shell", inline: $nomad_setup, privileged: false 142 | 143 | if (docker_install) 144 | config.vm.provision "shell", inline: "bash /tmp/nomad/scripts/install-docker.sh" 145 | end 146 | 147 | if (java_install) 148 | config.vm.provision "shell", inline: "bash /tmp/nomad/scripts/install-java.sh" 149 | end 150 | 151 | if (wetty_install) 152 | # Forward Wetty port 153 | config.vm.network :forwarded_port, guest: 3030, host: wetty_host_port, auto_correct: true 154 | 155 | # Install Wetty 156 | config.vm.provision "shell", inline: "bash /tmp/shared/scripts/web-terminal.sh" 157 | config.vm.provision "shell", inline: "bash /tmp/shared/scripts/setup-ssh-user.sh", 158 | env: { 159 | "GROUP" => wetty_group, 160 | "USER" => wetty_user, 161 | "PASSWORD" => wetty_password, 162 | "COMMENT" => wetty_comment, 163 | } 164 | end 165 | 166 | # Run tests if `RUN_TESTS` env var is provided 167 | if (run_tests) 168 | config.vm.provision "shell", inline: "cd /tmp && bash /tmp/shared/scripts/setup-testing.sh" 169 | config.vm.provision "shell", inline: "cd /tmp && rake hashistack:spec" 170 | end 171 | 172 | # Cleanup if `CLEANUP` env var is provided 173 | if (cleanup) 174 | config.vm.provision "shell", inline: "bash /tmp/shared/scripts/cleanup.sh" 175 | end 176 | 177 | # Increase memory for Parallels Desktop 178 | config.vm.provider "parallels" do |p, o| 179 | p.memory = "1024" 180 | end 181 | 182 | # Increase memory for Virtualbox 183 | config.vm.provider "virtualbox" do |vb| 184 | vb.memory = "1024" 185 | end 186 | 187 | # Increase memory for VMware 188 | ["vmware_fusion", "vmware_workstation"].each do |p| 189 | config.vm.provider p do |v| 190 | v.vmx["memsize"] = "1024" 191 | end 192 | end 193 | 194 | config.vm.post_up_message = " 195 | Your HashiStack dev cluster has been successfully provisioned! 196 | 197 | To SSH into the Consul host, run the below command. 198 | 199 | $ vagrant ssh 200 | 201 | You can now interact with Consul using any of the CLI (https://www.consul.io/docs/commands/index.html) 202 | or API (https://www.consul.io/api/index.html) commands. 203 | 204 | # Use the CLI to retrieve the Consul members, write a key/value, and read that key/value 205 | $ consul members 206 | $ consul kv put cli bar=baz 207 | $ consul kv get cli 208 | 209 | # Use the API to retrieve the Consul members, write a key/value, and read that key/value 210 | $ curl http://127.0.0.1:8500/v1/agent/members | jq '.' 211 | $ curl -X PUT -d 'bar=baz' http://127.0.0.1:8500/v1/kv/api | jq '.' 212 | $ curl http://127.0.0.1:8500/v1/kv/api | jq '.' 213 | 214 | You can interact with Vault using any of the CLI (https://www.vaultproject.io/docs/commands/index.html) 215 | or API (https://www.vaultproject.io/api/index.html) commands. 216 | 217 | # The Root token for your Vault -dev instance is set to `root` and placed in /srv/vault/.vault-token, 218 | # the `VAULT_TOKEN` environment variable has already been set for you 219 | $ echo $VAULT_TOKEN 220 | $ sudo cat /srv/vault/.vault-token 221 | 222 | # Use the CLI to write and read a generic secret 223 | $ vault kv put secret/cli foo=bar 224 | $ vault kv get secret/cli 225 | 226 | # Use the API to write and read a generic secret 227 | $ curl -H \"X-Vault-Token: $VAULT_TOKEN\" -X POST -d '{\"data\": {\"bar\":\"baz\"}}' http://127.0.0.1:8200/v1/secret/data/api | jq '.' 228 | $ curl -H \"X-Vault-Token: $VAULT_TOKEN\" http://127.0.0.1:8200/v1/secret/data/api | jq '.' 229 | 230 | You can interact with Nomad using any of the CLI (https://www.nomadproject.io/docs/commands/index.html) 231 | or API (https://www.nomadproject.io/api/index.html) commands. 232 | 233 | $ nomad server-members # Check Nomad's server members 234 | $ nomad node-status # Check Nomad's client nodes 235 | $ nomad init # Create a skeletion job file to deploy a Redis Docker container 236 | 237 | # Use the CLI to deploy a Redis Docker container 238 | $ nomad plan example.nomad # Run a nomad plan on the example job 239 | $ nomad run example.nomad # Run the example job 240 | $ nomad status # Check that the job is running 241 | $ nomad status example # Check job details 242 | $ nomad stop example # Stop the example job 243 | $ nomad status # Check that the job is stopped 244 | 245 | # Use the API to deploy a Redis Docker container 246 | $ nomad run -output example.nomad > example.json # Convert the example Nomad HCL job file to JSON 247 | $ curl -X POST -d @example.json http://127.0.0.1:4646/v1/job/example/plan | jq '.' # Run a nomad plan on the example job 248 | $ curl -X POST -d @example.json http://127.0.0.1:4646/v1/job/example | jq '.' # Run the example job 249 | $ curl -X GET http://127.0.0.1:4646/v1/jobs | jq '.' # Check that the job is running 250 | $ curl -X GET http://127.0.0.1:4646/v1/job/example | jq '.' # Check job details 251 | $ curl -X DELETE http://127.0.0.1:4646/v1/job/example | jq '.' # Stop the example job 252 | $ curl -X GET http://127.0.0.1:4646/v1/jobs | jq '.' # Check that the job is stopped 253 | 254 | Visit the Consul UI: http://#{private_ip}:#{consul_host_port}/ 255 | Visit the Vault UI: http://#{private_ip}:#{vault_host_port}/ 256 | Visit the Nomad UI: http://#{private_ip}:#{nomad_host_port}/ 257 | #{wetty_install ? 'Visit the Web Terminal (u: ' + wetty_user + '/p: ' + wetty_password + '): http://' + private_ip + ':' + wetty_host_port.to_s : ''} 258 | 259 | Don't forget to tear your VM down after. 260 | 261 | $ vagrant destroy 262 | " 263 | end 264 | -------------------------------------------------------------------------------- /hashistack/hashistack-aws.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "aws_access_key_id": "{{ env `AWS_ACCESS_KEY_ID` }}", 4 | "aws_secret_access_key": "{{ env `AWS_SECRET_ACCESS_KEY` }}", 5 | "aws_region": "{{ env `AWS_REGION` }}", 6 | "release_version": "{{ env `RELEASE_VERSION` }}", 7 | "vcs_name": "{{ env `VCS_NAME` }}", 8 | "consul_version": "{{ env `CONSUL_VERSION` }}", 9 | "consul_ent_url": "{{ env `CONSUL_ENT_URL` }}", 10 | "consul_group": "consul", 11 | "consul_user": "consul", 12 | "consul_comment": "Consul", 13 | "consul_home": "/srv/consul", 14 | "vault_version": "{{ env `VAULT_VERSION` }}", 15 | "vault_ent_url": "{{ env `VAULT_ENT_URL` }}", 16 | "vault_group": "vault", 17 | "vault_user": "vault", 18 | "vault_comment": "Vault", 19 | "vault_home": "/srv/vault", 20 | "nomad_version": "{{ env `NOMAD_VERSION` }}", 21 | "nomad_ent_url": "{{ env `NOMAD_ENT_URL` }}", 22 | "wetty_group": "wetty", 23 | "wetty_user": "wetty", 24 | "wetty_password": "{{ env `WETTY_PASSWORD` }}", 25 | "wetty_comment": "Wetty Web Terminal SSH user", 26 | "nomad_group": "root", 27 | "nomad_user": "root" 28 | }, 29 | "builders": [ 30 | { 31 | "name": "amazon-ebs-rhel-7.3-systemd", 32 | "type": "amazon-ebs", 33 | "access_key": "{{ user `aws_access_key_id` }}", 34 | "secret_key": "{{ user `aws_secret_access_key` }}", 35 | "region": "{{ user `aws_region` }}", 36 | "force_deregister": true, 37 | "force_delete_snapshot": true, 38 | "ssh_pty": true, 39 | "instance_type": "t2.medium", 40 | "associate_public_ip_address": true, 41 | "source_ami_filter": { 42 | "filters": { 43 | "virtualization-type": "hvm", 44 | "name": "*RHEL-7.3_HVM_GA-*", 45 | "root-device-type": "ebs" 46 | }, 47 | "owners": ["309956199498"], 48 | "most_recent": true 49 | }, 50 | "ssh_username": "ec2-user", 51 | "ssh_timeout": "5m", 52 | "ami_virtualization_type": "hvm", 53 | "ami_name": "hashistack-image_{{ user `release_version` }}_nomad_{{ user `nomad_version` }}_vault_{{ user `vault_version` }}_consul_{{ user `consul_version` }}_rhel_7.3", 54 | "ami_description": "HashiCorp HashiStack Image {{ user `release_version` }}", 55 | "tags": { 56 | "Name": "HashiStack RHEL 7.3 Image {{ user `release_version` }}: Consul v{{ user `consul_version` }} Vault v{{ user `vault_version` }} Nomad v{{ user `nomad_version` }}", 57 | "System": "HashiStack", 58 | "Product": "HashiStack", 59 | "Built-By": "{{ user `vcs_name` }}", 60 | "Release-Version": "{{ user `release_version` }}", 61 | "Consul-Version": "{{ user `consul_version` }}", 62 | "Vault-Version": "{{ user `vault_version` }}", 63 | "Nomad-Version": "{{ user `nomad_version` }}", 64 | "OS": "rhel", 65 | "OS-Version": "7.3" 66 | } 67 | }, 68 | { 69 | "name": "amazon-ebs-ubuntu-16.04-systemd", 70 | "type": "amazon-ebs", 71 | "access_key": "{{ user `aws_access_key_id` }}", 72 | "secret_key": "{{ user `aws_secret_access_key` }}", 73 | "region": "{{ user `aws_region` }}", 74 | "force_deregister": true, 75 | "force_delete_snapshot": true, 76 | "ssh_pty": true, 77 | "instance_type": "t2.medium", 78 | "associate_public_ip_address": true, 79 | "source_ami_filter": { 80 | "filters": { 81 | "virtualization-type": "hvm", 82 | "name": "*ubuntu-xenial-16.04-amd64-server-*", 83 | "root-device-type": "ebs" 84 | }, 85 | "owners": ["099720109477"], 86 | "most_recent": true 87 | }, 88 | "ssh_username": "ubuntu", 89 | "ssh_timeout": "10m", 90 | "ami_virtualization_type": "hvm", 91 | "ami_name": "hashistack-image_{{ user `release_version` }}_nomad_{{ user `nomad_version` }}_vault_{{ user `vault_version` }}_consul_{{ user `consul_version` }}_ubuntu_16.04", 92 | "ami_description": "HashiCorp HashiStack Image {{ user `release_version` }}", 93 | "tags": { 94 | "Name": "HashiStack Ubuntu 16.04 Image {{ user `release_version` }}: Consul v{{ user `consul_version` }} Vault v{{ user `vault_version` }} Nomad v{{ user `nomad_version` }}", 95 | "System": "HashiStack", 96 | "Product": "HashiStack", 97 | "Built-By": "{{ user `vcs_name` }}", 98 | "Release-Version": "{{ user `release_version` }}", 99 | "Consul-Version": "{{ user `consul_version` }}", 100 | "Vault-Version": "{{ user `vault_version` }}", 101 | "Nomad-Version": "{{ user `nomad_version` }}", 102 | "OS": "ubuntu", 103 | "OS-Version": "16.04" 104 | } 105 | } 106 | ], 107 | "provisioners": [ 108 | { 109 | "type": "file", 110 | "source": "../", 111 | "destination": "/tmp" 112 | }, 113 | { 114 | "type": "shell", 115 | "inline": [ 116 | "bash /tmp/shared/scripts/base.sh" 117 | ] 118 | }, 119 | { 120 | "type": "shell", 121 | "only": ["amazon-ebs-rhel-7.3-systemd", "amazon-ebs-ubuntu-16.04-systemd"], 122 | "inline": [ 123 | "bash /tmp/shared/scripts/base-aws.sh" 124 | ] 125 | }, 126 | { 127 | "type": "shell", 128 | "environment_vars": [ 129 | "GROUP={{ user `consul_group` }}", 130 | "USER={{ user `consul_user` }}", 131 | "COMMENT={{ user `consul_comment` }}", 132 | "HOME={{ user `consul_home` }}" 133 | ], 134 | "inline": [ 135 | "bash /tmp/shared/scripts/setup-user.sh" 136 | ] 137 | }, 138 | { 139 | "type": "shell", 140 | "environment_vars": [ 141 | "VERSION={{ user `consul_version` }}", 142 | "URL={{ user `consul_ent_url` }}", 143 | "USER={{ user `consul_user` }}", 144 | "GROUP={{ user `consul_group` }}" 145 | ], 146 | "inline": [ 147 | "bash /tmp/consul/scripts/install-consul.sh" 148 | ] 149 | }, 150 | { 151 | "type": "shell", 152 | "inline": [ 153 | "bash /tmp/consul-template/scripts/install-consul-template.sh" 154 | ] 155 | }, 156 | { 157 | "type": "shell", 158 | "only": ["amazon-ebs-rhel-7.3-systemd", "amazon-ebs-ubuntu-16.04-systemd"], 159 | "inline": [ 160 | "bash /tmp/consul/scripts/install-consul-systemd.sh" 161 | ] 162 | }, 163 | { 164 | "type": "shell", 165 | "environment_vars": [ 166 | "GROUP={{ user `vault_group` }}", 167 | "USER={{ user `vault_user` }}", 168 | "COMMENT={{ user `vault_comment` }}", 169 | "HOME={{ user `vault_home` }}" 170 | ], 171 | "inline": [ 172 | "bash /tmp/shared/scripts/setup-user.sh" 173 | ] 174 | }, 175 | { 176 | "type": "shell", 177 | "environment_vars": [ 178 | "VERSION={{ user `vault_version` }}", 179 | "URL={{ user `vault_ent_url` }}", 180 | "USER={{ user `vault_user` }}", 181 | "GROUP={{ user `vault_group` }}" 182 | ], 183 | "inline": [ 184 | "bash /tmp/vault/scripts/install-vault.sh" 185 | ] 186 | }, 187 | { 188 | "type": "shell", 189 | "only": ["amazon-ebs-rhel-7.3-systemd", "amazon-ebs-ubuntu-16.04-systemd"], 190 | "inline": [ 191 | "bash /tmp/vault/scripts/install-vault-systemd.sh" 192 | ] 193 | }, 194 | { 195 | "type": "shell", 196 | "environment_vars": [ 197 | "VERSION={{ user `nomad_version` }}", 198 | "URL={{ user `nomad_ent_url` }}", 199 | "USER={{ user `nomad_user` }}", 200 | "GROUP={{ user `nomad_group` }}" 201 | ], 202 | "inline": [ 203 | "bash /tmp/nomad/scripts/install-nomad.sh" 204 | ] 205 | }, 206 | { 207 | "type": "shell", 208 | "only": ["amazon-ebs-rhel-7.3-systemd", "amazon-ebs-ubuntu-16.04-systemd"], 209 | "inline": [ 210 | "bash /tmp/nomad/scripts/install-nomad-systemd.sh" 211 | ] 212 | }, 213 | { 214 | "type": "shell", 215 | "only": ["amazon-ebs-rhel-7.3-systemd", "amazon-ebs-ubuntu-16.04-systemd"], 216 | "inline": [ 217 | "bash /tmp/nomad/scripts/install-docker.sh" 218 | ] 219 | }, 220 | { 221 | "type": "shell", 222 | "inline": [ 223 | "bash /tmp/nomad/scripts/install-java.sh" 224 | ] 225 | }, 226 | { 227 | "type": "shell", 228 | "inline": [ 229 | "bash /tmp/shared/scripts/web-terminal.sh" 230 | ] 231 | }, 232 | { 233 | "type": "shell", 234 | "environment_vars": [ 235 | "GROUP={{ user `wetty_group` }}", 236 | "USER={{ user `wetty_user` }}", 237 | "PASSWORD={{ user `wetty_password` }}", 238 | "COMMENT={{ user `wetty_comment` }}" 239 | ], 240 | "inline": [ 241 | "bash /tmp/shared/scripts/setup-ssh-user.sh" 242 | ] 243 | }, 244 | { 245 | "type": "shell", 246 | "inline": [ 247 | "cd /tmp/shared/scripts && bash /tmp/shared/scripts/setup-testing.sh", 248 | "cd /tmp && rake hashistack:spec" 249 | ] 250 | }, 251 | { 252 | "type": "shell", 253 | "only": ["amazon-ebs-rhel-7.3-systemd", "amazon-ebs-ubuntu-16.04-systemd"], 254 | "inline": [ 255 | "cd /tmp/shared/scripts && bash setup-testing.sh", 256 | "cd /tmp/hashistack && rake spec" 257 | ] 258 | }, 259 | { 260 | "type": "shell", 261 | "only": ["amazon-ebs-rhel-7.3-systemd", "amazon-ebs-ubuntu-16.04-systemd"], 262 | "inline": [ 263 | "bash /tmp/shared/scripts/cleanup-aws.sh" 264 | ] 265 | }, 266 | { 267 | "type": "shell", 268 | "inline": [ 269 | "bash /tmp/shared/scripts/cleanup.sh" 270 | ] 271 | } 272 | ] 273 | } 274 | -------------------------------------------------------------------------------- /hashistack/hashistack-azure.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "azure_client_id": "{{ env `ARM_CLIENT_ID` }}", 4 | "azure_client_secret": "{{ env `ARM_CLIENT_SECRET` }}", 5 | "azure_subscription_id": "{{ env `ARM_SUBSCRIPTION_ID` }}", 6 | "azure_resource_group": "{{ env `AZURE_RESOURCE_GROUP` }}", 7 | "azure_location": "{{ env `AZURE_LOCATION` }}", 8 | "aws_access_key_id": "{{ env `AWS_ACCESS_KEY_ID` }}", 9 | "aws_secret_access_key": "{{ env `AWS_SECRET_ACCESS_KEY` }}", 10 | "aws_region": "{{ env `AWS_REGION` }}", 11 | "environment": "{{ env `PACKER_ENVIRONMENT` }}", 12 | "vcs_name": "{{ env `VCS_NAME` }}", 13 | "consul_version": "{{ env `CONSUL_VERSION` }}", 14 | "consul_ent_url": "{{ env `CONSUL_ENT_URL` }}", 15 | "vault_version": "{{ env `VAULT_VERSION` }}", 16 | "vault_ent_url": "{{ env `VAULT_ENT_URL` }}", 17 | "nomad_version": "{{ env `NOMAD_VERSION` }}", 18 | "nomad_ent_url": "{{ env `NOMAD_ENT_URL` }}", 19 | "distribution": "{{ env `DISTRIBUTION` }}" 20 | }, 21 | "builders": [ 22 | { 23 | "name": "azure-managed-image-RHEL-7.3-systemd", 24 | "type": "azure-arm", 25 | "client_id": "{{ user `azure_client_id` }}", 26 | "client_secret": "{{ user `azure_client_secret` }}", 27 | "subscription_id": "{{ user `azure_subscription_id` }}", 28 | "managed_image_resource_group_name": "{{ user `azure_resource_group` }}", 29 | "location": "{{ user `azure_location` }}", 30 | "image_publisher": "RedHat", 31 | "image_offer": "RHEL", 32 | "image_sku": "7.3", 33 | "os_type": "Linux", 34 | "ssh_username": "packer", 35 | "managed_image_name": "{{ user `environment` }}-hashistack-server-{{ user `distribution` }}-RHEL_7.3-{{timestamp}}", 36 | "azure_tags": { 37 | "Name": "HashiStack Server", 38 | "System": "HashiStack", 39 | "Product": "HashiStack", 40 | "Environment": "{{ user `environment` }}", 41 | "Built-By": "{{ user `vcs_name` }}", 42 | "OS": "RHEL", 43 | "OS-Version": "7.3", 44 | "Consul-Version": "{{ user `consul_version` }}", 45 | "Nomad-Version": "{{ user `nomad_version` }}", 46 | "Vault-Version": "{{ user `vault_version` }}" 47 | } 48 | }, 49 | { 50 | "name": "azure-managed-image-ubuntu-16.04-systemd", 51 | "type": "azure-arm", 52 | "client_id": "{{ user `azure_client_id` }}", 53 | "client_secret": "{{ user `azure_client_secret` }}", 54 | "subscription_id": "{{ user `azure_subscription_id` }}", 55 | "managed_image_resource_group_name": "{{ user `azure_resource_group` }}", 56 | "location": "{{ user `azure_location` }}", 57 | "image_publisher": "Canonical", 58 | "image_offer": "UbuntuServer", 59 | "image_sku": "16.04-LTS", 60 | "os_type": "Linux", 61 | "ssh_username": "packer", 62 | "managed_image_name": "{{ user `environment` }}-hashistack-server-{{ user `distribution` }}-Ubuntu_16.04-{{timestamp}}", 63 | "azure_tags": { 64 | "Name": "HashiStack Server", 65 | "System": "HashiStack", 66 | "Product": "HashiStack", 67 | "Environment": "{{ user `environment` }}", 68 | "Built-By": "{{ user `vcs_name` }}", 69 | "OS": "Ubuntu", 70 | "OS-Version": "16.04", 71 | "Consul-Version": "{{ user `consul_version` }}", 72 | "Nomad-Version": "{{ user `nomad_version` }}", 73 | "Vault-Version": "{{ user `vault_version` }}" 74 | } 75 | } 76 | ], 77 | "provisioners": [ 78 | { 79 | "type": "file", 80 | "source": "../shared", 81 | "destination": "/tmp" 82 | }, 83 | { 84 | "type": "file", 85 | "source": "../consul", 86 | "destination": "/tmp" 87 | }, 88 | { 89 | "type": "file", 90 | "source": "../nomad", 91 | "destination": "/tmp" 92 | }, 93 | { 94 | "type": "file", 95 | "source": "../vault", 96 | "destination": "/tmp" 97 | }, 98 | { 99 | "type": "shell", 100 | "inline": [ 101 | "bash /tmp/shared/scripts/base.sh" 102 | ] 103 | }, 104 | { 105 | "type": "shell", 106 | "only": ["azure-managed-image-RHEL-7.3-systemd", "azure-managed-image-ubuntu-16.04-systemd"], 107 | "inline": [ 108 | "bash /tmp/shared/scripts/base-aws.sh" 109 | ] 110 | }, 111 | { 112 | "type": "shell", 113 | "environment_vars": [ 114 | "USER=consul", 115 | "GROUP=consul", 116 | "COMMENT=Consul", 117 | "HOME=/srv/consul" 118 | ], 119 | "inline": [ 120 | "bash /tmp/shared/scripts/setup-user.sh" 121 | ] 122 | }, 123 | { 124 | "type": "shell", 125 | "environment_vars": [ 126 | "VERSION={{ user `consul_version` }}", 127 | "URL={{ user `consul_ent_url` }}" 128 | ], 129 | "inline": [ 130 | "bash /tmp/consul/scripts/install-consul.sh" 131 | ] 132 | }, 133 | { 134 | "type": "shell", 135 | "only": ["azure-managed-image-RHEL-7.3-systemd", "azure-managed-image-ubuntu-16.04-systemd"], 136 | "inline": [ 137 | "bash /tmp/consul/scripts/install-consul-systemd.sh" 138 | ] 139 | }, 140 | { 141 | "type": "shell", 142 | "environment_vars": [ 143 | "VERSION={{ user `nomad_version` }}", 144 | "URL={{ user `nomad_ent_url` }}" 145 | ], 146 | "inline": [ 147 | "bash /tmp/nomad/scripts/install-nomad.sh" 148 | ] 149 | }, 150 | { 151 | "type": "shell", 152 | "only": ["azure-managed-image-RHEL-7.3-systemd", "azure-managed-image-ubuntu-16.04-systemd"], 153 | "inline": [ 154 | "bash /tmp/nomad/scripts/install-nomad-systemd.sh" 155 | ] 156 | }, 157 | { 158 | "type": "shell", 159 | "only": ["azure-managed-image-ubuntu-16.04-systemd"], 160 | "inline": [ 161 | "bash /tmp/nomad/scripts/install-docker.sh" 162 | ] 163 | }, 164 | { 165 | "type": "shell", 166 | "inline": [ 167 | "bash /tmp/nomad/scripts/install-java.sh" 168 | ] 169 | }, 170 | { 171 | "type": "shell", 172 | "environment_vars": [ 173 | "USER=vault", 174 | "GROUP=vault", 175 | "COMMENT=Vault", 176 | "HOME=/srv/vault" 177 | ], 178 | "inline": [ 179 | "bash /tmp/shared/scripts/setup-user.sh" 180 | ] 181 | }, 182 | { 183 | "type": "shell", 184 | "environment_vars": [ 185 | "VERSION={{ user `vault_version` }}", 186 | "URL={{ user `vault_ent_url` }}" 187 | ], 188 | "inline": [ 189 | "bash /tmp/vault/scripts/install-vault.sh" 190 | ] 191 | }, 192 | { 193 | "type": "shell", 194 | "only": ["azure-managed-image-RHEL-7.3-systemd", "azure-managed-image-ubuntu-16.04-systemd"], 195 | "inline": [ 196 | "bash /tmp/vault/scripts/install-vault-systemd.sh" 197 | ] 198 | }, 199 | { 200 | "type": "shell", 201 | "inline": [ 202 | "cd /tmp/shared/scripts && bash setup-testing.sh" 203 | ] 204 | }, 205 | { 206 | "type": "shell", 207 | "only": ["azure-managed-image-RHEL-7.3-systemd", "azure-managed-image-ubuntu-16.04-systemd"], 208 | "inline": [ 209 | "bash /tmp/shared/scripts/cleanup-aws.sh" 210 | ] 211 | }, 212 | { 213 | "type": "shell", 214 | "inline": [ 215 | "bash /tmp/shared/scripts/disable-firewall.sh" 216 | ] 217 | }, 218 | { 219 | "type": "shell", 220 | "inline": [ 221 | "bash /tmp/shared/scripts/cleanup.sh" 222 | ] 223 | }, 224 | { 225 | "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'", 226 | "inline": [ 227 | "apt-get update -qq -y", 228 | "apt-get upgrade -qq -y", 229 | 230 | "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync" 231 | ], 232 | "inline_shebang": "/bin/sh -x", 233 | "type": "shell" 234 | } 235 | ] 236 | } 237 | -------------------------------------------------------------------------------- /hashistack/hashistack-gcp.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "gcp_account_file": "{{ env `GCP_ACCOUNT_FILE_JSON`}}", 4 | "gcp_zone": "{{ env `GCP_ZONE` }}", 5 | "gcp_project_id": "{{ env `GCP_PROJECT_ID` }}", 6 | "environment": "{{ env `PACKER_ENVIRONMENT` }}", 7 | "vcs_name": "{{ env `VCS_NAME` }}", 8 | "consul_version": "{{ env `CONSUL_VERSION` }}", 9 | "consul_ent_url": "{{ env `CONSUL_ENT_URL` }}", 10 | "vault_version": "{{ env `VAULT_VERSION` }}", 11 | "vault_ent_url": "{{ env `VAULT_ENT_URL` }}", 12 | "nomad_version": "{{ env `NOMAD_VERSION` }}", 13 | "nomad_ent_url": "{{ env `NOMAD_ENT_URL` }}", 14 | "distribution": "{{ env `DISTRIBUTION` }}" 15 | }, 16 | "builders": [ 17 | { 18 | "name": "gcp-ubuntu-16.04-systemd", 19 | "image_description": "Hashicorp HashiStack Server", 20 | "image_name": "{{ (user `environment`) | clean_image_name }}-hashistack-server-{{ (user `distribution`) | clean_image_name }}-ubuntu-16-04", 21 | "type": "googlecompute", 22 | "account_file": "{{ user `gcp_account_file` }}", 23 | "zone": "{{ user `gcp_zone` }}", 24 | "project_id": "{{ user `gcp_project_id` }}", 25 | "source_image_family": "ubuntu-1604-lts", 26 | "machine_type": "n1-standard-1", 27 | "ssh_username": "gcp-user", 28 | "metadata": { 29 | "name": "hashistack server", 30 | "system": "hashistack", 31 | "product": "hashistack", 32 | "environment": "{{ user `environment` | lower}}", 33 | "built-by": "{{ user `vcs_name` | lower}}", 34 | "os": "ubuntu", 35 | "os-version": "v-16.04", 36 | "consul-version": "v-{{ user `consul_version` }}", 37 | "nomad_version": "v-{{ user `nomad_version` }}", 38 | "vault-version": "v-{{ user `vault_version` }}" 39 | } 40 | }, 41 | { 42 | "name": "gcp-rhel-7.3-systemd", 43 | "image_description": "Hashicorp HashiStack Server", 44 | "image_name": "{{ (user `environment`) | clean_image_name }}-hashistack-server-{{ (user `distribution`) | clean_image_name }}-rhel-7-3", 45 | "type": "googlecompute", 46 | "account_file": "{{ user `gcp_account_file` }}", 47 | "zone": "{{ user `gcp_zone` }}", 48 | "project_id": "{{ user `gcp_project_id` }}", 49 | "source_image_family": "rhel-7", 50 | "machine_type": "n1-standard-1", 51 | "ssh_username": "gcp-user", 52 | "metadata": { 53 | "name": "hashistack server", 54 | "system": "hashistack", 55 | "product": "hashistack", 56 | "environment": "{{ user `environment` | lower}}", 57 | "built-by": "{{ user `vcs_name` | lower}}", 58 | "os": "rhel", 59 | "os-version": "v-7-3", 60 | "consul-version": "v-{{ user `consul_version` }}", 61 | "nomad_version": "v-{{ user `nomad_version` }}", 62 | "vault-version": "v-{{ user `vault_version` }}" 63 | } 64 | } 65 | ], 66 | "provisioners": [ 67 | { 68 | "type": "file", 69 | "source": "../shared", 70 | "destination": "/tmp" 71 | }, 72 | { 73 | "type": "file", 74 | "source": "../consul", 75 | "destination": "/tmp" 76 | }, 77 | { 78 | "type": "file", 79 | "source": "../nomad", 80 | "destination": "/tmp" 81 | }, 82 | { 83 | "type": "file", 84 | "source": "../vault", 85 | "destination": "/tmp" 86 | }, 87 | { 88 | "type": "shell", 89 | "inline": [ 90 | "bash /tmp/shared/scripts/base.sh" 91 | ] 92 | }, 93 | { 94 | "type": "shell", 95 | "environment_vars": [ 96 | "USER=consul", 97 | "GROUP=consul", 98 | "COMMENT=Consul", 99 | "HOME=/srv/consul" 100 | ], 101 | "inline": [ 102 | "bash /tmp/shared/scripts/setup-user.sh" 103 | ] 104 | }, 105 | { 106 | "type": "shell", 107 | "environment_vars": [ 108 | "VERSION={{ user `consul_version` }}", 109 | "URL={{ user `consul_ent_url` }}" 110 | ], 111 | "inline": [ 112 | "bash /tmp/consul/scripts/install-consul.sh" 113 | ] 114 | }, 115 | { 116 | "type": "shell", 117 | "only": [ 118 | "gcp-ubuntu-16.04-systemd", 119 | "gcp-rhel-7.3-systemd" 120 | ], 121 | "inline": [ 122 | "bash /tmp/consul/scripts/install-consul-systemd.sh" 123 | ] 124 | }, 125 | { 126 | "type": "shell", 127 | "environment_vars": [ 128 | "VERSION={{ user `nomad_version` }}", 129 | "URL={{ user `nomad_ent_url` }}" 130 | ], 131 | "inline": [ 132 | "bash /tmp/nomad/scripts/install-nomad.sh" 133 | ] 134 | }, 135 | { 136 | "type": "shell", 137 | "only": [ 138 | "gcp-ubuntu-16.04-systemd", 139 | "gcp-rhel-7.3-systemd" 140 | ], 141 | "inline": [ 142 | "bash /tmp/nomad/scripts/install-nomad-systemd.sh" 143 | ] 144 | }, 145 | { 146 | "type": "shell", 147 | "only": [ 148 | "gcp-ubuntu-16.04-systemd" 149 | ], 150 | "inline": [ 151 | "bash /tmp/nomad/scripts/install-docker.sh" 152 | ] 153 | }, 154 | { 155 | "type": "shell", 156 | "inline": [ 157 | "bash /tmp/nomad/scripts/install-java.sh" 158 | ] 159 | }, 160 | { 161 | "type": "shell", 162 | "environment_vars": [ 163 | "USER=vault", 164 | "GROUP=vault", 165 | "COMMENT=Vault", 166 | "HOME=/srv/vault" 167 | ], 168 | "inline": [ 169 | "bash /tmp/shared/scripts/setup-user.sh" 170 | ] 171 | }, 172 | { 173 | "type": "shell", 174 | "environment_vars": [ 175 | "VERSION={{ user `vault_version` }}", 176 | "URL={{ user `vault_ent_url` }}" 177 | ], 178 | "inline": [ 179 | "bash /tmp/vault/scripts/install-vault.sh" 180 | ] 181 | }, 182 | { 183 | "type": "shell", 184 | "only": [ 185 | "gcp-ubuntu-16.04-systemd", 186 | "gcp-rhel-7.3-systemd" 187 | ], 188 | "inline": [ 189 | "bash /tmp/vault/scripts/install-vault-systemd.sh" 190 | ] 191 | }, 192 | { 193 | "type": "shell", 194 | "inline": [ 195 | "cd /tmp/shared/scripts && bash setup-testing.sh" 196 | ] 197 | }, 198 | { 199 | "type": "shell", 200 | "inline": [ 201 | "bash /tmp/shared/scripts/cleanup.sh" 202 | ] 203 | } 204 | ], 205 | "post-processors" : [ 206 | { 207 | "type": "googlecompute-export", 208 | "only": ["gcp-ubuntu-16.04-systemd"], 209 | "paths": [ 210 | "gs://hc-se-image-store/{{ user `environment` }}/consul-{{ user `consul_version`}}-nomad-{{ user `nomad_version`}}-vault-{{ user `vault_version`}}/hashistack-server-ubuntu-16-04.tar.gz" 211 | ], 212 | "keep_input_artifact": false 213 | }, 214 | { 215 | "type": "googlecompute-export", 216 | "only": ["gcp-rhel-7.3-systemd"], 217 | "paths": [ 218 | "gs://hc-se-image-store/{{ user `environment` }}/consul-{{ user `consul_version`}}-nomad-{{ user `nomad_version`}}-vault-{{ user `vault_version`}}/hashistack-server-rhel-7-3.tar.gz" 219 | ], 220 | "keep_input_artifact": false 221 | } 222 | ] 223 | } 224 | -------------------------------------------------------------------------------- /nomad/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Networking 5 | private_ip = ENV['PRIVATE_IP'] || "192.168.50.163" 6 | 7 | # Base box selection 8 | base_box = ENV['BASE_BOX'] || "bento/ubuntu-16.04" 9 | 10 | # Consul variables 11 | consul_install = ["true", "1"].include?((ENV['CONSUL_INSTALL'] || true).to_s.downcase) 12 | consul_host_port = ENV['CONSUL_HOST_PORT'] || 8500 13 | consul_version = ENV['CONSUL_VERSION'] || "1.2.0" 14 | consul_ent_url = ENV['CONSUL_ENT_URL'] 15 | consul_group = "consul" 16 | consul_user = "consul" 17 | consul_comment = "Consul" 18 | consul_home = "/srv/consul" 19 | 20 | # Vault variables 21 | vault_install = ["true", "1"].include?((ENV['VAULT_INSTALL'] || true).to_s.downcase) 22 | vault_host_port = ENV['VAULT_HOST_PORT'] || 8200 23 | vault_version = ENV['VAULT_VERSION'] || "0.10.3" 24 | vault_ent_url = ENV['VAULT_ENT_URL'] 25 | vault_group = "vault" 26 | vault_user = "vault" 27 | vault_comment = "Vault" 28 | vault_home = "/srv/vault" 29 | 30 | # Nomad variables 31 | nomad_host_port = ENV['NOMAD_HOST_PORT'] || 4646 32 | nomad_version = ENV['NOMAD_VERSION'] || "0.8.4" 33 | nomad_ent_url = ENV['NOMAD_ENT_URL'] 34 | nomad_group = "root" 35 | nomad_user = "root" 36 | docker_install = ["true", "1"].include?((ENV['DOCKER_INSTALL'] || true).to_s.downcase) 37 | java_install = ["true", "1"].include?((ENV['JAVA_INSTALL'] || true).to_s.downcase) 38 | 39 | # Wetty variables 40 | wetty_host_port = ENV['WETTY_HOST_PORT'] || 3030 41 | wetty_install = ["true", "1"].include?((ENV['WETTY_INSTALL'] || true).to_s.downcase) 42 | wetty_group = ENV['WETTY_GROUP'] || "wetty" 43 | wetty_user = ENV['WETTY_USER'] || "wetty" 44 | wetty_password = ENV['WETTY_PASSWORD'] || "wetty" 45 | wetty_comment = "Wetty Web Terminal SSH user" 46 | 47 | # Tests & cleanup 48 | run_tests = ["true", "1"].include?((ENV['RUN_TESTS'] || false).to_s.downcase) 49 | cleanup = ["true", "1"].include?((ENV['CLEANUP'] || true).to_s.downcase) 50 | 51 | $nomad_setup = <