├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md └── providers └── aws └── route53_ssl ├── README.md ├── etcd_configs └── .gitkeep ├── files ├── backend-attributes-json.tpl ├── chef-cookbooks.sh ├── chef_mlsa.bash ├── configuring.bash ├── disable_firewall.sh ├── etcd_template.bash.tpl ├── frontend-attributes-json.tpl ├── instance_store.bash └── knife-rb.tpl ├── main.tf ├── outputs.tf ├── terraform.tfvars.example └── variables.tf /.gitignore: -------------------------------------------------------------------------------- 1 | terraform.tfstate* 2 | terraform.tfvars 3 | .terraform 4 | *.swp* 5 | .chef 6 | logfiles 7 | etcd_configs 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | tf_hachef CHANGELOG 2 | =================== 3 | 4 | This file is used to list changes made in each version of the tf_hachef Terraform plan. 5 | 6 | v0.2.10 (2017-02-23) 7 | -------------------- 8 | - Fixed typo in a warning message relating to accepting Chef license 9 | 10 | v0.2.9 (2016-10-29) 11 | ------------------- 12 | - Added ETCD tunable variables and implementation 13 | - Update `private_key` for `connection` to use `${file()}` interpolation 14 | 15 | v0.2.8 (2016-10-28) 16 | ------------------- 17 | - Updated repo structure to prepare for multiple providers and plans per provider feature set. 18 | - Documentation updates 19 | 20 | v0.2.7 (2016-09-20) 21 | ------------------- 22 | - Updated chef-cookbook script to pin system cookbook to `0.11.0`: xhost-cookbooks/system#49 23 | - Update syntax; `template_file` resource is deprecated, updated to `data` source 24 | 25 | v0.2.6 (2016-08-11) 26 | ------------------- 27 | - Updated root device to use gp2 on backends 28 | - Added map `instance_store` with reasonable defaults 29 | - Now using local node instance storage for backends 30 | - Large documentation overhaul 31 | 32 | v0.2.5 (2016-08-10) 33 | ------------------- 34 | - Adding `postgresql.md5_auth_cidr_addresses` to `chef-backend.rb` before 35 | joining cluster no longer breaks chef-backend 36 | - attributes-json.tpl -> backend-attributes-json.tpl for consistency 37 | 38 | v0.2.4 (2016-08-10) 39 | ------------------- 40 | - Fix for #14 41 | 42 | v0.2.3 (2016-08-10) 43 | ------------------- 44 | - Breakup `chef` map into `chef_backend`, `chef_client`, `chef_mlsa`, 45 | `chef_org`, `chef_server`, and `chef_user` variables 46 | - Changes to supporting documentation 47 | 48 | v0.2.2 (2016-08-09) 49 | ------------------- 50 | - Fix for #7 51 | - Fix for #8 52 | 53 | v0.2.1 (2016-08-08) 54 | ------------------- 55 | - Clarification in [README.md](README.md) 56 | - Multiple AZs are not required, however server counts ARE required 57 | 58 | v0.2.0 (2016-08-08) 59 | ------------------- 60 | - Overhaul on code (nearly complete re-write) 61 | - Updated syntax for (most) Terraform 0.7.0 constructs 62 | - NOTE: Leaving `template` in place of `data` source due to `count` absence on 63 | `data` source 64 | - Removed a number of files 65 | 66 | v0.1.1 (2016-07-15) 67 | ------------------- 68 | - Documentation work 69 | - Fix [.gitignore](.gitignore) to ignore all `terraform.tfstate*` files 70 | 71 | v0.1.0 (2016-07-15) 72 | ------------------- 73 | - Initial commit 74 | 75 | - - - 76 | Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. 77 | 78 | The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. 79 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing to tf_chef_server 2 | ============================== 3 | 4 | All contributors are welcome to submit patches but please keep the following in mind: 5 | 6 | - [Coding Standards](#coding-standards) 7 | - [Testing](#testing) 8 | - [Prerequisites](#prerequisites) 9 | 10 | Please also keep in mind: 11 | 12 | - Be patient as not all items will be tested or reviewed immediately by the core team. 13 | - Be receptive and responsive to feedback about your additions or changes. The myself and/or other community members may make suggestions or ask questions about your change. This is part of the review process, and helps everyone to understand what is happening, why it is happening, and potentially optimizes your code. 14 | - Be understanding 15 | 16 | If you're looking to contribute but aren't sure where to start, check out the open issues. 17 | 18 | Will Not Merge 19 | -------------- 20 | This details Pull Requests that we will **not** be merged. 21 | 22 | - New features without accompanying tests or proof of operation 23 | - New features without accompanying usage documentation 24 | 25 | Coding Standards 26 | ---------------- 27 | The submitted code should be compatible with the following standards 28 | 29 | - 2-space indentation style 30 | - First curl brace on the same line as the method 31 | - Closing curl brace on its own aligned newline 32 | - Variable and value assignment does not need to be aligned with assignment operator 33 | - Where possible, avoid HEREDOC in favor of script or templates 34 | 35 | Testing 36 | ------- 37 | Please indicate the results of your tests in a comment along with the pull request. Supplying tests and the method used to run/validate the changes are highly encouraged. 38 | 39 | Prerequisites 40 | ------------- 41 | Familiarize yourself with Terraform and be well versed in its interpolations. 42 | 43 | - [Terraform](https://www.terraform.io/docs/index.html) 44 | 45 | Familiarize yourself with Chef and the operation of the chef-server cookbook 46 | 47 | - [chef-server](https://github.com/chef-cookbooks/chef-server) cookbook 48 | 49 | Familiarize yourself with Chef Backend and the installation documentation. 50 | 51 | - [chef-backend](https://docs.chef.io/install_server_ha.html) 52 | 53 | Process 54 | ------- 55 | 1. Fork the git repository from GitHub: 56 | 57 | 3. Create a branch for your changes: 58 | 59 | $ git checkout -b my_bug_fix 60 | 61 | 4. Make any changes 62 | 63 | 5. Write tests to support those changes. 64 | 65 | 6. Run the tests (if included) 66 | 67 | 7. Assuming the tests pass, open a Pull Request on GitHub and add results 68 | 69 | 70 | Do's and Don't's 71 | ---------------- 72 | - **Do** include tests for your contribution 73 | - **Do** request feedback via GitHub issues or other contact 74 | - **Do NOT** break existing behavior (unless intentional) 75 | - **Do NOT** modify the [CHANGELOG](CHANGELOG) 76 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tf_hachef 2 | 3 | This terraform plan makes use of chef-backend and chef-server-core to create a 4 | Chef HA architecture. In order to support multiple providers and various 5 | feature sets based upon provider this repo has a tree structure to help you 6 | choose the right plan based on certain assumptions. 7 | 8 | 9 | # Providers 10 | 11 | The following providers are currently supported: 12 | 13 | * AWS 14 | 15 | 16 | # Plans 17 | 18 | The following plans exist in this repo: 19 | 20 | * AWS w/valid SSL and Route53 internal/external zones - [providers/aws/route53_ssl/README.md](providers/aws/route53_ssl/README.md) 21 | 22 | 23 | # Tree navigation 24 | 25 | * providers 26 | * aws 27 | * route53_ssl 28 | * ... future provider 29 | * ... future feature set 30 | 31 | 32 | ## Usage 33 | 34 | 35 | ### Module 36 | 37 | Usage as a module has not been tested, however in Terraform 0.7.0+ many things 38 | are first-class which were not before. Choose to run this way at your own risk 39 | 40 | 41 | ### Directly 42 | 43 | 1. Clone this repo: `git clone https://github.com/mengesb/tf_hachef.git` 44 | 2. Navigate to the correct plan in the provider tree. 45 | 3. Make a local terraform.tfvars file: `cp terraform.tfvars.example terraform.tfvars` 46 | 4. Edit `terraform.tfvars` with your editor of choice, ensuring 47 | `var.chef["accept_mlsa"]` is set to `true` 48 | 5. Test the plan: `terraform plan` 49 | 6. Apply the plan: `terraform apply` 50 | 51 | 52 | ## Recommendations 53 | 54 | The defaults set forth in the `variables.tf` file have been set for good reason. 55 | Please note that a good amount of testing went into defining these defaults and 56 | necessary inputs are defined, for your convenience in `terraform.tfvars.example` 57 | per plan. 58 | 59 | 60 | ## Contributors 61 | 62 | * [Brian Menges](https://github.com/mengesb) 63 | * [Kevin Dickerson, Loom](https://loom.technology) 64 | 65 | ## Runtime sample 66 | 67 | You can view a runtime output sample here: [tf_hachef_runtime.txt](https://gist.github.com/mengesb/0771c38a64d3dd7aa609dc31f5933bba) 68 | 69 | 70 | ## Contributing 71 | 72 | Please understand that this is a work in progress and is subject to change 73 | rapidly. Be sure to keep up to date with the repo should you fork, and feel 74 | free to contact me regarding development and suggested direction. Familiarize 75 | yoursef with the [contributing](CONTRIBUTING.md) before making/submitting changes. 76 | 77 | 78 | ## CHANGELOG 79 | 80 | Please refer to the [CHANGELOG.md](CHANGELOG.md) 81 | 82 | 83 | ## License 84 | 85 | This is licensed under [the Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). 86 | -------------------------------------------------------------------------------- /providers/aws/route53_ssl/README.md: -------------------------------------------------------------------------------- 1 | # tf_hachef 2 | 3 | This terraform plan makes use of chef-backend and chef-server-core to create a 4 | Chef HA architecture spread across multiple AWS availability zones within one 5 | AWS region. Cross region deployment is not supported with this plan or with 6 | chef-backend at this time. 7 | 8 | By default, this terraform plan will create a VPC, subnets, security groups, 9 | security group rules, frontend nodes (chef-server-core), backend nodes 10 | (chef-backend), and an AWS ELB comprised of the frontend nodes. 11 | 12 | This plan is rather large and complex. Be sure to read through the 13 | [README](README.md) in full. 14 | 15 | 16 | ## Assumptions 17 | 18 | This terraform plan is designed for near-production use. Please take note as 19 | the requirements are extensive 20 | 21 | * Requires: 22 | * AWS (duh!) 23 | * Route53 internal and external zones 24 | * Uploaded to AWS a SSL certificate (wildcard preferred) 25 | * SSL certificate/key for created instance (local files to upload to instances) 26 | * Terraform >= 0.7.3 27 | * Uses public IPs and public DNS 28 | * Creates default security group as follows: 29 | * Frontend: 30 | * 443/tcp: HTTPS from anywhere 31 | * 80/tcp: HTTP from anywhere 32 | * Backend: 33 | * ALL: inside security group 34 | * 2379/tcp: etcd from Frontend SG 35 | * 5432/tcp: PostgreSQL from Frontend SG 36 | * 7331/tcp: leaderl from Frontend SG 37 | * 9200/tcp: Elasticsearch from Frontend SG 38 | * SSH Security Group: 39 | * 22/tcp: SSH from anywhere (default), restrict with `${ssh_cidrs}` list 40 | * Creates subnets spread across AWS AZs 41 | * Minimum three (3) chef-backend instances required (`chef["backend_count"]`) 42 | * Minimum two (2) chef-server-core instances required (`chef["frontend_count"]`) 43 | * Understand Terraform and ability to read the source 44 | 45 | 46 | ## Usage 47 | 48 | 49 | ### Module 50 | 51 | Usage as a module has not been tested, however in Terraform 0.7.0 many things 52 | are first-class which were not before. Choose to run this way at your own risk 53 | 54 | 55 | ### Directly 56 | 57 | 1. Clone this repo: `git clone https://github.com/mengesb/tf_hachef.git` 58 | 2. Make a local terraform.tfvars file: `cp terraform.tfvars.example terraform.tfvars` 59 | 3. Edit `terraform.tfvars` with your editor of choice, ensuring 60 | `var.chef["accept_mlsa"]` is set to `true` 61 | 4. Test the plan: `terraform plan` 62 | 5. Apply the plan: `terraform apply` 63 | 64 | 65 | ## Supported OSes 66 | 67 | All supported OSes are 64-bit and HVM (though PV should be supported) 68 | 69 | * Ubuntu 12.04 LTS 70 | * Ubuntu 14.04 LTS (default) 71 | * Ubuntu 16.04 LTS (pending) 72 | * CentOS 6 73 | * CentOS 7 (pending) 74 | * Others (here be dragons! Please see Map Variables) 75 | 76 | 77 | ## AWS 78 | 79 | These resources will incur charges on your AWS bill. It is your responsibility 80 | to delete the resources. 81 | 82 | 83 | ## Recommendations 84 | 85 | The defaults set forth in the [variables.tf](variables.tf) file have been set 86 | for good reasons. Please note that a good amount of testing went into defining 87 | these defaults and necessary inputs are defined, for your convenience in 88 | [terraform.tfvars.example](terraform.tfvars.example) 89 | 90 | 91 | ## Input variables 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 |
VariableKeyDescriptionTypeDefault Value
providerAWS provider mapmap
access_keyAWS access keystring
regionAWS region for deploymentstringus-east-1
secret_keyAWS secretstring
vpcAWS VPC settings mapmap
cidrCIDR block for VPCstring10.20.30.0/24
dns_hostnamesSupport DNS hostnames (required)booleantrue
dns_supportSupport DNS in VPC (required)booleantrue
tags_descDescription tagstringChef HA VPC
tenancyAWS instance tenancystringdefault
subnetsAWS subnet settingsmap
`key`AWS AZ to create subnetstringus-east-1a
us-east-1c
us-east-1d
us-east-1e
`value`Subnet to configure for `key`string10.20.30.0/26
10.20.30.64/26
10.20.30.128/26
10.20.30.192/26
ssh_cidrsList of CIDRs allowing SSHlist0.0.0.0/0
amiAWS AMI mapmap
`key`Key comprised of of os-type-regionstringView [variables.tf](variables.tf)
`value`AWS AMI identifierstringView [variables.tf](variables.tf)
osAWS AMI operating systemstringubuntu14
ami_userMapping of AMI OS to AMI usernamemapubuntu
`key`AMI OSstringcentos7
centos6
ubuntu16
ubuntu14
ubuntu12
`value`Username for `key`stringcentos
centos
ubuntu
ubuntu
ubuntu
ssl_certificateSSL certificate informationmap
cert_fileFull path to SSL certificate filestring
key_fileFull path to SSL certificate key filestring
elbAWS ELB settingsmap
certificateAWS identifier for SSL certificatestring
hostnameBase hostname for AWS ELBstringchefelb
tags_descDescription tagstringCreated using Terraform
chef_backendChef backend settingsmap
countCount of chef-backend instancesinteger3
versionVersion of chef-backend to installstring1.1.2
chef_clientVersion of chef-client to installstring12.12.15
chef_mlsaChef MLSA licese acceptancestringfalse
chef_orgChef server organization settingsmap
shortChef server organization short namestringchef
longChef server organization long nameChef Organizationstring
chef_serverChef server core settingsmap
countCount of chef-server-core instancesinteger2
versionVersion of chef-server-core to installstring12.8.0
chef_userChef initial user settingsmap
emailChef user e-mail addressstringchef@domain.tld
first_nameChef user first namestringChef
last_nameChef user last namestringUser
usernameChef user usernamestringchef
instanceAWS instance settingsmap
backend_flavorAWS instance type for chef-backendstringr3.xlarge
backend_iopsRoot volume IOPs on chef-backend instance (`io1`)integer0
backend_publicAssociate public IP to chef-backend instancebooleantrue
backend_sizeRoot volume size (GB) on chef-backend instanceinteger40
backend_termRoot volume delete on chef-backend instance terminationbooleantrue
backend_typeRoot volume type on chef-backend instancestringgp2
ebs_optimizedDeploy EBS optimized root volumebooleantrue
frontend_flavorAWS instance type for chef-server-corestringm4.large
frontend_iopsRoot volume IOPs on chef-server-core instance (`io1`).integer0
frontend_publicAssociate public IP to chef-server-core instancetrue
frontend_sizeRoot volume size (GB) on chef-server-core instanceinteger40
frontend_termRoot volume delete on chef-server-core instance terminationtrue
frontend_typeRoot volume type on chef-server-core instancestringgp2
tags_descDescription name tag for instances.Created using Terraform
instance_hostnameAWS instance base hostnamemap
backendChef backend base hostnamestringchefbe
frontendChef server core base hostnamestringchefbe
instance_keysAWS SSH key settingsmap
key_nameAWS key pairstring
key_fileFull path to matching private keystring
instance_storeAWS instance store settingsmap
deviceAWS instance store device namestringxvdb
enabledUse AWS instance storebooleantrue
filesystemAWS instance store filesystemstringext4
mountAWS instance store mount pointstring/mnt/xvdb
mount_optionsAWS instance store mount optionsstringdefaults,noatime,errors=remount-ro
domainDomain namestringlocaldomain
r53_zonesAWS Route53 zone settingsmap
internalAWS Route53 internal zone IDstring
externalAWS Route53 external zone IDstring
r53_ttlsAWS Route53 TTL settingsmap
internalInternal record TTL settinginteger180
externalExternal record TTL settinginteger180
etcd_pathPath to configure ETCD settings`/opt/chef-backend/service/etcd/env`
etcd_settingsMap of settings for ETCD configuration. Key is setting name, value is the valueETCD_HEARTBEAT_INTERVAL = 600
ETCD_ELECTION_TIMEOUT = 6000
ETCD_SNAPSHOT_COUNT = 5000
etcd_restart_cmdCommand issued to restart ETCD servicesudo chef-backend-ctl restart etcd
667 | 668 | 669 | ### AMI map customization 670 | 671 | There following variables work in concert with each other to set a number of 672 | required settings ffor this plan to succeed. 673 | 674 | * `ami`: Map of `os`-`instance[..._type]`-`provider[region]` to AMI ID 675 | * `ami_user`: Map of AMI OS to default AMI username 676 | * `os`: String containing OS+Version (i.e. Ubuntu 14.04.x LTS = `ubuntu14`) 677 | * `provider[region]`: AWS region 678 | 679 | Normally you will not interract with the `ami` map directly, however if you 680 | want to override the AMI selected take note of the following example. 681 | 682 | Example: Use newer AMI for default `ubuntu14` requires a simple `ami` override: 683 | 684 | ```hcl 685 | ami = { 686 | ubuntu14-gp2-us-east-1 = "ami-ffffffff" 687 | } 688 | ``` 689 | 690 | Example: Custom AMI user with custom AMI image 691 | 692 | ```hcl 693 | os = "myos" 694 | ami = { 695 | myos-gp2-us-east-1 = "ami-ffffffff" 696 | } 697 | ami_user = { 698 | myos = "someuser" 699 | } 700 | ``` 701 | 702 | Example: Using existing AMIs but with an io1 root volume on chef-backend 703 | 704 | ```hcl 705 | instance = { 706 | backend_flavor = "r3.xlarge" 707 | backend_iops = 6000 708 | backend_public = true 709 | backend_size = 200 710 | backend_term = true 711 | backend_type = "io1" 712 | ebs_optimized = true 713 | frontend_flavor = "m4.large" 714 | frontend_iops = 0 715 | frontend_public = true 716 | frontend_size = 40 717 | frontend_term = true 718 | frontend_type = "gp2" 719 | tags_desc = "Created using Terraform" 720 | } 721 | ``` 722 | 723 | Defaults in `ami_user` map: 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 |
KeyValue
centos7centos
centos6centos
ubuntu16ubuntu
ubuntu14ubuntu
ubuntu12ubuntu
751 | 752 | 753 | ## Outputs 754 | 755 | * `chef_manage_url`: URL of the chef server's management interface 756 | * `chef_username`: Username for the chef user created 757 | * `chef_user_password`: Password for the chef user created 758 | * `knife_rb`: Path to the knife.rb file 759 | 760 | 761 | ## Contributors 762 | 763 | * [Brian Menges](https://github.com/mengesb) 764 | 765 | 766 | ## Runtime sample 767 | 768 | You can view a runtime output sample here: [tf_hachef_runtime.txt](https://gist.github.com/mengesb/0771c38a64d3dd7aa609dc31f5933bba) 769 | 770 | 771 | ## Contributing 772 | 773 | Please understand that this is a work in progress and is subject to change 774 | rapidly. Be sure to keep up to date with the repo should you fork, and feel 775 | free to contact me regarding development and suggested direction. Familiarize 776 | yoursef with the [contributing](CONTRIBUTING.md) before making/submitting changes. 777 | 778 | 779 | ## CHANGELOG 780 | 781 | Please refer to the [CHANGELOG.md](CHANGELOG.md) 782 | 783 | 784 | ## License 785 | 786 | This is licensed under [the Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). 787 | 788 | -------------------------------------------------------------------------------- /providers/aws/route53_ssl/etcd_configs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengesb/tf_hachef/030d643e6139e6a609d3634e93b1b37527f573da/providers/aws/route53_ssl/etcd_configs/.gitkeep -------------------------------------------------------------------------------- /providers/aws/route53_ssl/files/backend-attributes-json.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "fqdn": "${host}.${domain}", 3 | "chef_client": { 4 | "init_style": "none" 5 | }, 6 | "system": { 7 | "delay_network_restart": false, 8 | "domain_name": "${domain}", 9 | "manage_hostsfile": true, 10 | "short_hostname": "${host}" 11 | }, 12 | "tags": [] 13 | } 14 | -------------------------------------------------------------------------------- /providers/aws/route53_ssl/files/chef-cookbooks.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | sudo rm -rf /var/chef/cookbooks ; sudo mkdir -p /var/chef/cookbooks 4 | sudo rm -rf /var/chef/cache ; sudo mkdir -p /var/chef/cache 5 | sudo rm -rf /var/chef/ssl ; sudo mkdir -p /var/chef/ssl 6 | 7 | for DEP in apt apt-chef chef-client ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done 8 | for DEP in chef_handler chef-ingredient ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done 9 | for DEP in chef-server chef-sugar ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done 10 | for DEP in compat_resource cron ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done 11 | for DEP in firewall hostsfile logrotate ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done 12 | for DEP in packagecloud yum ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done 13 | for DEP in yum-chef windows ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done 14 | 15 | curl -sL https://supermarket.chef.io/cookbooks/system/versions/0.11.0/download | sudo tar xzC /var/chef/cookbooks 16 | 17 | sudo chown -R root:root /var/chef 18 | 19 | exit 0 20 | -------------------------------------------------------------------------------- /providers/aws/route53_ssl/files/chef_mlsa.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | case ${1,,} in 3 | true) exit 0 ;; 4 | 5 | 1) exit 0 ;; 6 | 7 | false) echo "Please set accept_license = \"true\" in terraform.tfvars" 8 | exit 1 ;; 9 | 10 | 0) echo "Please set accept_license = \"true\" in terraform.tfvars" 11 | exit 1 ;; 12 | 13 | *) echo "Please set accept_license = \"true\" in terraform.tfvars" 14 | exit 1 ;; 15 | esac 16 | -------------------------------------------------------------------------------- /providers/aws/route53_ssl/files/configuring.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #set -x # Debugging 3 | 4 | # ----------------------------------------------------------------------------- 5 | VERSION=1.0 6 | AUTHOR="Brian Menges" 7 | AUTHOR_EMAIL="mengesb@gmail.com" 8 | LICENSE="Apache 2.0" 9 | LICENSE_URL="http://www.apache.org/licenses/LICENSE-2.0" 10 | # ----------------------------------------------------------------------------- 11 | 12 | # Usage 13 | usage() 14 | { 15 | cat < 19 | Version: ${VERSION} 20 | Licensed under ${LICENSE} (${LICENSE_URL}) 21 | 22 | This script is designed to establish a lock only after all other locks of a 23 | similar type have been released. This script doesn't release the lock so you 24 | are left to solve that segment of the problem. This script is designed to 25 | sleep until a lock can be stablished 26 | 27 | OPTIONAL OPTIONS: 28 | -d Destination directory ex. /tmp (default) 29 | -f Filename (this should be unique) 30 | -h This help message 31 | -v Verbose output 32 | EOF 33 | } 34 | 35 | # Generate random number 36 | rand() 37 | { 38 | local MIN=$1 39 | local MAX=$2 40 | local NUM=0 41 | 42 | while [ "$NUM" -le $MIN ] 43 | do 44 | NUM=$RANDOM 45 | let "NUM %= $MAX" 46 | done 47 | 48 | echo $NUM 49 | } 50 | 51 | # Requirements check 52 | d_directory=/tmp 53 | VAR=$(echo "$BASH_VERSION") 54 | [[ $? -ne 0 ]] && echo "Unable to determine BASH version installed, exiting." && usage && exit 1 55 | [[ "${BASH_VERSION}" =~ ^[0-3] ]] && echo "Script requires a BASH version 4.x or higher, found ${BASH_VERSION}" && usage && exit 1 56 | [[ -z "$(grep --version)" ]] && echo "Program 'grep' not found in PATH!" && usage && exit 1 57 | 58 | # Options parsing 59 | while getopts ":f:d:hv" OPTION; do 60 | case "$OPTION" in 61 | f) 62 | f_filename=${OPTARG} 63 | ;; 64 | d) 65 | if [[ -d ${OPTARG} ]]; then 66 | d_directory=${OPTARG} 67 | fi 68 | ;; 69 | h) 70 | usage && exit 0 71 | ;; 72 | v) 73 | VERBOSE=1 74 | ;; 75 | *) 76 | usage && exit 1 77 | ;; 78 | ?) 79 | usage && exit 1 80 | ;; 81 | esac 82 | done 83 | 84 | # 85 | # Main 86 | # 87 | 88 | sleep $(rand 5 31) 89 | C=$(ls $d_directory | grep -Ec 'configuring\.') 90 | 91 | while [ "$C" -gt 0 ] 92 | do 93 | number=$(rand 5 20) 94 | echo "Waiting for $C proccesses to complete; sleeping $number seconds" && sleep $number 95 | C=$(ls $d_directory | grep -Ec 'configuring\.') 96 | done 97 | 98 | touch ${d_directory}/configuring.${f_filename} 99 | 100 | exit 0 101 | 102 | -------------------------------------------------------------------------------- /providers/aws/route53_ssl/files/disable_firewall.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | [ $EUID -ne 0 ] && PREPEND="sudo" || PREPEND="" 4 | $PREPEND service iptables stop 5 | $PREPEND chkconfig iptables off 6 | $PREPEND ufw disable 7 | 8 | echo "Attempted to stop iptables/ufw" 9 | exit 0 10 | -------------------------------------------------------------------------------- /providers/aws/route53_ssl/files/etcd_template.bash.tpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | [[ -f ${path}/${file} ]] && sudo mv ${path}/${file} ${path}/${file}.bak 4 | echo ${input} | sudo tee -a ${path}/${file} 5 | -------------------------------------------------------------------------------- /providers/aws/route53_ssl/files/frontend-attributes-json.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "fqdn": "${host}.${domain}", 3 | "chef_client": { 4 | "init_style": "none" 5 | }, 6 | "system": { 7 | "delay_network_restart": false, 8 | "domain_name": "${domain}", 9 | "manage_hostsfile": true, 10 | "short_hostname": "${host}" 11 | }, 12 | "tags": [] 13 | } 14 | -------------------------------------------------------------------------------- /providers/aws/route53_ssl/files/instance_store.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # ----------------------------------------------------------------------------- 4 | VERSION=1.0 5 | AUTHOR="Brian Menges" 6 | AUTHOR_EMAIL="mengesb@gmail.com" 7 | LICENSE="Apache 2.0" 8 | LICENSE_URL="http://www.apache.org/licenses/LICENSE-2.0" 9 | # ----------------------------------------------------------------------------- 10 | 11 | PROTECTED_ROOT=$(mount|grep ' / '|cut -d' ' -f 1|sed 's,/dev/,,') 12 | 13 | # Usage 14 | usage() 15 | { 16 | cat < 34 | Version: ${VERSION} 35 | 36 | EOF 37 | } 38 | 39 | while getopts ":d:e:f:m:ohv" OPTION; do 40 | case "$OPTION" in 41 | d) 42 | DEV=${OPTARG} 43 | ;; 44 | e) 45 | case ${OPTARG} in 46 | true) 47 | ENABLED=1 48 | ;; 49 | 1) 50 | ENABLED=1 51 | ;; 52 | esac 53 | ;; 54 | f) 55 | FS=${OPTARG} 56 | ;; 57 | h) 58 | usage && exit 0 59 | ;; 60 | m) 61 | MNT=${OPTARG} 62 | ;; 63 | o) 64 | OPT=${OPTARG} 65 | ;; 66 | v) 67 | set -x 68 | VERBOSE=1 69 | ;; 70 | *) 71 | usage && exit 1 72 | ;; 73 | ?) 74 | usage && exit 1 75 | ;; 76 | esac 77 | done 78 | 79 | # Defaults 80 | [[ -z $DEV ]] && DEV=xvdb 81 | [[ -z $FS ]] && FS=ext4 82 | [[ -z $MNT ]] && MNT=/mnt/$DEV 83 | [[ -z $OPT ]] && OPT='defaults,noatime,errors=remount-ro' 84 | 85 | # Requirements check 86 | [[ -z $ENABLED ]] && echo "The safety is still on" && exit 0 87 | 88 | [[ $EUID -ne 0 ]] && echo "$0 must be ran as root" && exit 1 89 | 90 | if [[ ! -b /dev/$DEV ]] 91 | then 92 | echo "ERROR: Device not a block device: /dev/$DEV" && exit 1 93 | fi 94 | 95 | if [[ $DEV =~ $PROTECTED_ROOT ]] 96 | then 97 | echo "ERROR: Cannot use root device" && exit 1 98 | fi 99 | 100 | # Main 101 | 102 | # Setup instance store device 103 | mkfs -t $FS /dev/$DEV 104 | 105 | # Mount point setup 106 | mkdir -p ${MNT} /opt /var/opt /var/cache/chef /var/log/chef-backend 107 | mount /dev/${DEV} ${MNT} 108 | mkdir -p /mnt/${DEV}/var/opt /mnt/${DEV}/var/log/chef-backend /mnt/${DEV}/opt /mnt/${DEV}/var/cache/chef 109 | umount /dev/${DEV} 110 | 111 | # Update /etc/fstab 112 | sed -i "/$DEV/d" /etc/fstab 113 | echo " 114 | /dev/${DEV} ${MNT} auto ${OPT} 0 0 115 | /mnt/${DEV}/opt /opt auto defaults,bind 0 0 116 | /mnt/${DEV}/var/cache/chef /var/cache/chef auto defaults,bind 0 0 117 | /mnt/${DEV}/var/log/chef-backend /var/log/chef-backend auto defaults,bind 0 0 118 | /mnt/${DEV}/var/opt /var/opt auto defaults,bind 0 0 119 | " | tee -a /etc/fstab 120 | 121 | # Mount 122 | mount -a 123 | -------------------------------------------------------------------------------- /providers/aws/route53_ssl/files/knife-rb.tpl: -------------------------------------------------------------------------------- 1 | current_dir = File.dirname(__FILE__) 2 | log_level :info 3 | log_location STDOUT 4 | node_name '${user}' 5 | client_key "#{current_dir}/${user}.pem" 6 | validation_client_name '${org}-validator' 7 | validation_key "#{current_dir}/${org}-validator.pem" 8 | chef_server_url 'https://${fqdn}/organizations/${org}' 9 | cache_type 'BasicFile' 10 | cache_options( :path => "#{current_dir}/checksums" ) 11 | cookbook_path ["#{current_dir}/local-mode-cache/cache/cookbooks"] 12 | -------------------------------------------------------------------------------- /providers/aws/route53_ssl/main.tf: -------------------------------------------------------------------------------- 1 | # 2 | # Chef MLSA License Enforcement 3 | # 4 | resource "null_resource" "chef_mlsa" { 5 | provisioner "local-exec" { 6 | command = "bash ${path.module}/files/chef_mlsa.bash ${var.chef_mlsa}" 7 | } 8 | } 9 | # 10 | # AWS Provider 11 | # 12 | provider "aws" { 13 | access_key = "${var.provider["access_key"]}" 14 | region = "${var.provider["region"]}" 15 | secret_key = "${var.provider["secret_key"]}" 16 | } 17 | # 18 | # AWS VPC setup 19 | # 20 | resource "aws_vpc" "chef-ha-vpc" { 21 | depends_on = ["null_resource.chef_mlsa"] 22 | cidr_block = "${var.vpc["cidr"]}" 23 | enable_dns_hostnames = "${var.vpc["dns_hostnames"]}" 24 | enable_dns_support = "${var.vpc["dns_support"]}" 25 | instance_tenancy = "${var.vpc["tenancy"]}" 26 | tags { 27 | Name = "${var.vpc["tags_desc"]}" 28 | } 29 | } 30 | # 31 | # AWS GW setup 32 | # 33 | resource "aws_internet_gateway" "chef-ha-gw" { 34 | vpc_id = "${aws_vpc.chef-ha-vpc.id}" 35 | tags { 36 | Name = "${var.gateway}" 37 | } 38 | } 39 | # 40 | # AWS Subnet setup 41 | # 42 | resource "aws_subnet" "chef-ha-subnet" { 43 | count = "${length(keys(var.subnets))}" 44 | vpc_id = "${aws_vpc.chef-ha-vpc.id}" 45 | availability_zone = "${element(keys(var.subnets), count.index)}" 46 | cidr_block = "${element(values(var.subnets), count.index)}" 47 | map_public_ip_on_launch = "${lookup(var.subnets_public, element(keys(var.subnets), count.index))}" 48 | tags { 49 | Name = "Chef HA Subnet ${element(values(var.subnets), count.index)} (${element(keys(var.subnets), count.index)})" 50 | } 51 | } 52 | # 53 | # AWS Route Table setup 54 | # Grant the VPC internet access on its main route table 55 | resource "aws_route" "default_gateway" { 56 | route_table_id = "${aws_vpc.chef-ha-vpc.main_route_table_id}" 57 | destination_cidr_block = "0.0.0.0/0" 58 | gateway_id = "${aws_internet_gateway.chef-ha-gw.id}" 59 | } 60 | # 61 | # Associate subnets to main routing table 62 | # 63 | resource "aws_route_table_association" "subnet_routes" { 64 | count = "${length(keys(var.subnets))}" 65 | subnet_id = "${element(aws_subnet.chef-ha-subnet.*.id, count.index)}" 66 | route_table_id = "${aws_vpc.chef-ha-vpc.main_route_table_id}" 67 | } 68 | # 69 | # AWS Route53 Zone Association 70 | # 71 | resource "aws_route53_zone_association" "chef-ha-vpc" { 72 | zone_id = "${var.r53_zones["internal"]}" 73 | vpc_id = "${aws_vpc.chef-ha-vpc.id}" 74 | } 75 | # 76 | # AWS Security Group setup - private services 77 | # Chef Server AWS security group - https://docs.chef.io/server_firewalls_and_ports.html 78 | resource "aws_security_group" "chef-ha-ssh" { 79 | name = "${var.elb["hostname"]}.${var.domain} SSH SG" 80 | description = "${var.elb["hostname"]}.${var.domain} SSH SG" 81 | vpc_id = "${aws_vpc.chef-ha-vpc.id}" 82 | tags { 83 | Name = "${var.elb["hostname"]}.${var.domain} SSH SG" 84 | } 85 | } 86 | # SSH 87 | resource "aws_security_group_rule" "chef-ha-ssh_22_tcp_restricted" { 88 | type = "ingress" 89 | from_port = 22 90 | to_port = 22 91 | protocol = "tcp" 92 | cidr_blocks = "${var.ssh_cidrs}" 93 | security_group_id = "${aws_security_group.chef-ha-ssh.id}" 94 | } 95 | # Egress: ALL 96 | resource "aws_security_group_rule" "chef-ha-ssh_allow_egress" { 97 | type = "egress" 98 | from_port = 0 99 | to_port = 0 100 | protocol = "-1" 101 | cidr_blocks = ["0.0.0.0/0"] 102 | security_group_id = "${aws_security_group.chef-ha-ssh.id}" 103 | } 104 | # 105 | # AWS Security Group setup - public services 106 | # 107 | resource "aws_security_group" "chef-ha-frontend" { 108 | name = "${var.elb["hostname"]}.${var.domain} Frontend SG" 109 | description = "${var.elb["hostname"]}.${var.domain} Frontend SG" 110 | vpc_id = "${aws_vpc.chef-ha-vpc.id}" 111 | tags { 112 | Name = "${var.elb["hostname"]}.${var.domain} Frontend SG" 113 | } 114 | } 115 | # HTTP (nginx) 116 | resource "aws_security_group_rule" "chef-ha-frontend_80_tcp" { 117 | type = "ingress" 118 | from_port = 80 119 | to_port = 80 120 | protocol = "tcp" 121 | cidr_blocks = ["0.0.0.0/0"] 122 | security_group_id = "${aws_security_group.chef-ha-frontend.id}" 123 | } 124 | # HTTPS (nginx) 125 | resource "aws_security_group_rule" "chef-ha-frontend_443_tcp" { 126 | type = "ingress" 127 | from_port = 443 128 | to_port = 443 129 | protocol = "tcp" 130 | cidr_blocks = ["0.0.0.0/0"] 131 | security_group_id = "${aws_security_group.chef-ha-frontend.id}" 132 | } 133 | # Egress: ALL 134 | resource "aws_security_group_rule" "chef-ha-frontend_allow_egress" { 135 | type = "egress" 136 | from_port = 0 137 | to_port = 0 138 | protocol = "-1" 139 | cidr_blocks = ["0.0.0.0/0"] 140 | security_group_id = "${aws_security_group.chef-ha-frontend.id}" 141 | } 142 | # 143 | # AWS Security Group setup - backend services 144 | # 145 | resource "aws_security_group" "chef-ha-backend" { 146 | name = "${var.elb["hostname"]}.${var.domain} Backend SG" 147 | description = "${var.elb["hostname"]}.${var.domain} Backend SG" 148 | vpc_id = "${aws_vpc.chef-ha-vpc.id}" 149 | tags { 150 | Name = "${var.elb["hostname"]}.${var.domain} Backend SG" 151 | } 152 | } 153 | # inner security group communication 154 | resource "aws_security_group_rule" "chef-ha-backend_sg_all" { 155 | type = "ingress" 156 | from_port = 0 157 | to_port = 0 158 | protocol = "-1" 159 | source_security_group_id = "${aws_security_group.chef-ha-backend.id}" 160 | security_group_id = "${aws_security_group.chef-ha-backend.id}" 161 | } 162 | # etcd 163 | resource "aws_security_group_rule" "chef-ha-backend_2379_tcp" { 164 | type = "ingress" 165 | from_port = 2379 166 | to_port = 2379 167 | protocol = "tcp" 168 | source_security_group_id = "${aws_security_group.chef-ha-frontend.id}" 169 | security_group_id = "${aws_security_group.chef-ha-backend.id}" 170 | } 171 | # postgresql 172 | resource "aws_security_group_rule" "chef-ha-backend_5432_tcp" { 173 | type = "ingress" 174 | from_port = 5432 175 | to_port = 5432 176 | protocol = "tcp" 177 | source_security_group_id = "${aws_security_group.chef-ha-frontend.id}" 178 | security_group_id = "${aws_security_group.chef-ha-backend.id}" 179 | } 180 | # leaderl 181 | resource "aws_security_group_rule" "chef-ha-backend_7331_tcp" { 182 | type = "ingress" 183 | from_port = 7331 184 | to_port = 7331 185 | protocol = "tcp" 186 | source_security_group_id = "${aws_security_group.chef-ha-frontend.id}" 187 | security_group_id = "${aws_security_group.chef-ha-backend.id}" 188 | } 189 | # elasticsearch 190 | resource "aws_security_group_rule" "chef-ha-backend_9200_tcp" { 191 | type = "ingress" 192 | from_port = 9200 193 | to_port = 9200 194 | protocol = "tcp" 195 | source_security_group_id = "${aws_security_group.chef-ha-frontend.id}" 196 | security_group_id = "${aws_security_group.chef-ha-backend.id}" 197 | } 198 | # Egress: ALL 199 | resource "aws_security_group_rule" "chef-ha-backend_allow_egress" { 200 | type = "egress" 201 | from_port = 0 202 | to_port = 0 203 | protocol = "-1" 204 | cidr_blocks = ["0.0.0.0/0"] 205 | security_group_id = "${aws_security_group.chef-ha-backend.id}" 206 | } 207 | # Local prep 208 | resource "null_resource" "chef-prep" { 209 | depends_on = ["null_resource.chef_mlsa"] 210 | provisioner "local-exec" { 211 | command = <<-EOF 212 | rm -rf .chef && mkdir -p .chef 213 | openssl rand -base64 512 | tr -d '\r\n' > .chef/encrypted_data_bag_secret 214 | EOF 215 | } 216 | } 217 | # Chef provisiong backend attributes_json and dna.json templating 218 | data "template_file" "backend-attributes-json" { 219 | count = "${var.chef_backend["count"]}" 220 | template = "${file("${path.module}/files/backend-attributes-json.tpl")}" 221 | vars { 222 | domain = "${var.domain}" 223 | host = "${format("%s-%03d", var.instance_hostname["backend"], count.index + 1)}" 224 | } 225 | } 226 | # 227 | # Provision servers 228 | # Backend: chef-backend 229 | resource "aws_instance" "chef-backends" { 230 | count = "${var.chef_backend["count"]}" 231 | ami = "${lookup(var.ami, "${var.os}-${var.instance["backend_type"]}-${var.provider["region"]}")}" 232 | ebs_optimized = "${var.instance["ebs_optimized"]}" 233 | instance_type = "${var.instance["backend_flavor"]}" 234 | associate_public_ip_address = "${var.instance["backend_public"]}" 235 | subnet_id = "${element(aws_subnet.chef-ha-subnet.*.id, count.index % length(keys(var.subnets)))}" 236 | vpc_security_group_ids = ["${aws_security_group.chef-ha-backend.id}","${aws_security_group.chef-ha-ssh.id}"] 237 | key_name = "${var.instance_keys["key_name"]}" 238 | tags = { 239 | Name = "${format("%s-%03d.%s", var.instance_hostname["backend"], count.index + 1, var.domain)}" 240 | Description = "${var.instance["tags_desc"]}" 241 | } 242 | root_block_device { 243 | delete_on_termination = "${var.instance["backend_term"]}" 244 | volume_size = "${var.instance["backend_size"]}" 245 | volume_type = "${var.instance["backend_type"]}" 246 | iops = "${var.instance["backend_iops"]}" 247 | } 248 | connection { 249 | host = "${self.public_ip}" 250 | user = "${var.ami_user[var.os]}" 251 | private_key = "${file("${var.instance_keys["key_file"]}")}" 252 | } 253 | # Setup 254 | provisioner "remote-exec" { 255 | script = "${path.module}/files/disable_firewall.sh" 256 | } 257 | # Setup instance storage 258 | provisioner "file" { 259 | source = "${path.module}/files/instance_store.bash" 260 | destination = "/tmp/instance_store.bash" 261 | } 262 | provisioner "remote-exec" { 263 | inline = [ 264 | "#!/usr/bin/env bash", 265 | "sudo chmod a+x /tmp/instance_store.bash", 266 | "sudo cp /etc/fstab /tmp/fstab.before", 267 | "sudo /tmp/instance_store.bash -d ${var.instance_store["device"]} -e ${var.instance_store["enabled"]} -f ${var.instance_store["filesystem"]} -m ${var.instance_store["mount"]} -o '${var.instance_store["mount_options"]}' -v", 268 | "cp /etc/fstab /tmp/fstab.after", 269 | ] 270 | } 271 | # Put cookbooks 272 | provisioner "remote-exec" { 273 | script = "${path.module}/files/chef-cookbooks.sh" 274 | } 275 | # Write dna.json for chef-solo run 276 | provisioner "remote-exec" { 277 | inline = [ 278 | "cat > /tmp/dna.json < /tmp/dna.json < /tmp/chef-server.rb.${sha256(element(aws_instance.chef-frontends.*.tags.Name, count.index))}", 530 | "sudo chown ${var.ami_user[var.os]} /tmp/chef-server.rb.${sha256(element(aws_instance.chef-frontends.*.tags.Name, count.index))}", 531 | "echo \"api_fqdn ${format("'%s.%s'", var.elb["hostname"], var.domain)}\" > file.out", 532 | "sed -i '/fqdn/ r file.out' /tmp/chef-server.rb.${sha256(element(aws_instance.chef-frontends.*.tags.Name, count.index))}", 533 | "rm -f file.out", 534 | ] 535 | } 536 | # Get generated configuration file 537 | provisioner "local-exec" { 538 | command = "scp -r -o stricthostkeychecking=no -i ${var.instance_keys["key_file"]} ${var.ami_user[var.os]}@${aws_instance.chef-backends.0.public_ip}:/tmp/chef-server.rb.${sha256(element(aws_instance.chef-frontends.*.tags.Name, count.index))} .chef/" 539 | } 540 | # Delete chef frontend configuration 541 | provisioner "remote-exec" { 542 | connection { 543 | host = "${aws_instance.chef-backends.0.public_ip}" 544 | user = "${var.ami_user[var.os]}" 545 | private_key = "${file("${var.instance_keys["key_file"]}")}" 546 | } 547 | inline = [ 548 | "sudo rm -f /tmp/chef-server.rb.${sha256(element(aws_instance.chef-frontends.*.tags.Name, count.index))}", 549 | ] 550 | } 551 | # Put chef-server.rb on frontend 552 | provisioner "file" { 553 | connection { 554 | host = "${element(aws_instance.chef-frontends.*.public_ip, count.index)}" 555 | user = "${var.ami_user[var.os]}" 556 | private_key = "${file("${var.instance_keys["key_file"]}")}" 557 | } 558 | source = ".chef/chef-server.rb.${sha256(element(aws_instance.chef-frontends.*.tags.Name, count.index))}" 559 | destination = "/tmp/chef-server.rb.${sha256(element(aws_instance.chef-frontends.*.tags.Name, count.index))}" 560 | } 561 | } 562 | resource "null_resource" "first_frontend" { 563 | count = 1 564 | depends_on = ["null_resource.generate_frontend_cfg"] 565 | connection { 566 | host = "${element(aws_instance.chef-frontends.*.public_ip, count.index)}" 567 | user = "${var.ami_user[var.os]}" 568 | private_key = "${file("${var.instance_keys["key_file"]}")}" 569 | } 570 | provisioner "remote-exec" { 571 | inline = [ 572 | "sudo mv /tmp/chef-server.rb.* /etc/opscode/chef-server.rb", 573 | "sudo mv /tmp/${var.elb["hostname"]}.${var.domain}.key /var/opt/opscode/nginx/ca/", 574 | "sudo mv /tmp/${var.elb["hostname"]}.${var.domain}.crt /var/opt/opscode/nginx/ca/", 575 | "sudo chown -R root:root /etc/opscode /var/opt/opscode", 576 | "sudo chef-server-ctl reconfigure", 577 | "sudo chef-server-ctl install chef-manage", 578 | "sudo chef-manage-ctl reconfigure", 579 | "sudo cp /etc/opscode/private-chef-secrets.json /etc/opscode/webui_priv.pem /etc/opscode/webui_pub.pem /etc/opscode/pivotal.pem /var/opt/opscode/upgrades/migration-level /tmp", 580 | "cd /tmp && sudo tar -czf chef-frontend.tgz migration-level private-chef-secrets.json webui_priv.pem webui_pub.pem pivotal.pem", 581 | "sudo chown ${var.ami_user[var.os]} /tmp/chef-frontend.tgz", 582 | ] 583 | } 584 | provisioner "local-exec" { 585 | command = "scp -r -o stricthostkeychecking=no -i ${var.instance_keys["key_file"]} ${var.ami_user[var.os]}@${element(aws_instance.chef-frontends.*.public_ip, count.index)}:/tmp/chef-frontend.tgz .chef/chef-frontend.tgz" 586 | } 587 | } 588 | resource "null_resource" "other_frontends" { 589 | count = "${var.chef_server["count"] - 1}" 590 | depends_on = ["null_resource.first_frontend"] 591 | connection { 592 | host = "${element(aws_instance.chef-frontends.*.public_ip, count.index + 1)}" 593 | user = "${var.ami_user[var.os]}" 594 | private_key = "${file("${var.instance_keys["key_file"]}")}" 595 | } 596 | # Put chef-frontend.tgz 597 | provisioner "file" { 598 | source = ".chef/chef-frontend.tgz" 599 | destination = "/tmp/chef-frontend.tgz" 600 | } 601 | # TODO: Investigate replacing this with a remote-exec script 602 | provisioner "remote-exec" { 603 | inline = [ 604 | "sudo mkdir -p /etc/opscode /var/opt/opscode/nginx/ca /var/opt/opscode/upgrades /var/opt/chef-manage", 605 | "sudo touch /var/opt/chef-manage/.license.accepted", 606 | "sudo touch /var/opt/opscode/bootstrapped", 607 | "sudo mv /tmp/chef-server.rb.* /etc/opscode/chef-server.rb", 608 | "sudo mv /tmp/${var.elb["hostname"]}.${var.domain}.key /var/opt/opscode/nginx/ca/", 609 | "sudo mv /tmp/${var.elb["hostname"]}.${var.domain}.crt /var/opt/opscode/nginx/ca/", 610 | "sudo tar -xf /tmp/chef-frontend.tgz -C /etc/opscode", 611 | "sudo rm -f /tmp/chef-frontend.tgz", 612 | "sudo mv /etc/opscode/migration-level /var/opt/opscode/upgrades/migration-level", 613 | "sudo chown -R root:root /etc/opscode /var/opt/opscode /var/opt/chef-manage", 614 | "sudo chef-server-ctl reconfigure", 615 | "sudo chef-server-ctl install chef-manage", 616 | "sudo chef-manage-ctl reconfigure", 617 | ] 618 | } 619 | } 620 | resource "aws_route53_record" "chef-ha-elb" { 621 | zone_id = "${var.r53_zones["external"]}" 622 | name = "${var.elb["hostname"]}.${var.domain}" 623 | type = "CNAME" 624 | ttl = "${var.r53_ttls["external"]}" 625 | records = ["${aws_elb.chef-ha-frontend.dns_name}"] 626 | } 627 | # knife.rb templating 628 | data "template_file" "knife-rb" { 629 | depends_on = ["null_resource.chef-prep"] 630 | template = "${file("${path.module}/files/knife-rb.tpl")}" 631 | vars { 632 | user = "${var.chef_user["username"]}" 633 | fqdn = "${var.elb["hostname"]}.${var.domain}" 634 | org = "${var.chef_org["short"]}" 635 | } 636 | } 637 | # Setting up Chef Server 638 | resource "null_resource" "chef-setup" { 639 | depends_on = ["null_resource.first_frontend"] 640 | connection { 641 | host = "${aws_instance.chef-frontends.0.public_ip}" 642 | user = "${var.ami_user[var.os]}" 643 | private_key = "${file("${var.instance_keys["key_file"]}")}" 644 | } 645 | # TODO: Maybe create parametertized script to run these commands (wrapping chef-server-ctl) 646 | provisioner "remote-exec" { 647 | inline = [ 648 | "sudo chef-server-ctl user-create ${var.chef_user["username"]} ${var.chef_user["first_name"]} ${var.chef_user["last_name"]} ${var.chef_user["email"]} ${base64sha256(aws_instance.chef-frontends.0.id)} -f /tmp/${var.chef_user["username"]}.pem", 649 | "sudo chef-server-ctl org-create ${var.chef_org["short"]} '${var.chef_org["long"]}' --association_user ${var.chef_user["username"]} --filename /tmp/${var.chef_org["short"]}-validator.pem", 650 | "sudo chown ${var.ami_user[var.os]} /tmp/${var.chef_user["username"]}.pem /tmp/${var.chef_org["short"]}-validator.pem", 651 | ] 652 | } 653 | # Copy back files 654 | provisioner "local-exec" { 655 | command = <<-EOC 656 | rm -f .chef/${var.chef_org["short"]}-validator.pem .chef/${var.chef_user["username"]}.pem 657 | scp -r -o stricthostkeychecking=no -i ${var.instance_keys["key_file"]} ${var.ami_user[var.os]}@${aws_instance.chef-frontends.0.public_ip}:/tmp/${var.chef_org["short"]}-validator.pem .chef/${var.chef_org["short"]}-validator.pem 658 | scp -r -o stricthostkeychecking=no -i ${var.instance_keys["key_file"]} ${var.ami_user[var.os]}@${aws_instance.chef-frontends.0.public_ip}:/tmp/${var.chef_user["username"]}.pem .chef/${var.chef_user["username"]}.pem 659 | EOC 660 | } 661 | } 662 | # 663 | # AWS ELB Setup 664 | # 665 | resource "aws_elb" "chef-ha-frontend" { 666 | name = "${var.elb["hostname"]}-${replace(var.domain,".","-")}-ELB" 667 | #access_logs { 668 | #} 669 | #availability_zones = ["${join(",",aws_subnet.chef-ha-subnet.*.availability_zone)}"] 670 | security_groups = ["${aws_security_group.chef-ha-frontend.id}"] 671 | subnets = ["${aws_subnet.chef-ha-subnet.*.id}"] 672 | instances = ["${aws_instance.chef-frontends.*.id}"] 673 | internal = false 674 | listener { 675 | instance_port = 80 676 | instance_protocol = "http" 677 | lb_port = 80 678 | lb_protocol = "http" 679 | } 680 | listener { 681 | instance_port = 443 682 | instance_protocol = "https" 683 | lb_port = 443 684 | lb_protocol = "https" 685 | ssl_certificate_id = "${var.elb["certificate"]}" 686 | } 687 | health_check { 688 | healthy_threshold = 2 689 | unhealthy_threshold = 2 690 | timeout = 3 691 | target = "HTTPS:443/login" 692 | interval = 30 693 | } 694 | cross_zone_load_balancing = true 695 | idle_timeout = 60 696 | connection_draining = true 697 | connection_draining_timeout = 60 698 | tags { 699 | Name = "${var.elb["hostname"]}.${var.domain} Frontend ELB" 700 | } 701 | } 702 | resource "aws_app_cookie_stickiness_policy" "chef-manage" { 703 | name = "chef-manage-cookie" 704 | load_balancer = "${aws_elb.chef-ha-frontend.id}" 705 | lb_port = 443 706 | cookie_name = "chef-manage" 707 | } 708 | resource "null_resource" "knife-rb" { 709 | # Generate knife.rb 710 | provisioner "local-exec" { 711 | command = <<-EOC 712 | [ -f .chef/knife.rb ] && rm -rf .chef/knife.rb || echo OK 713 | tee .chef/knife.rb <