From 9a32c3b71c5aa0f02d5bacd9bf3ff3cdf00ce668 Mon Sep 17 00:00:00 2001 From: Brian Menges Date: Fri, 15 Jul 2016 15:32:24 -0700 Subject: [PATCH] Initial commit v0.1.0 --- .gitignore | 6 + CHANGELOG.md | 13 + CONTRIBUTING.md | 75 ++ LICENSE | 201 +++++ README.md | 201 +++++ files/attributes-json.tpl | 13 + files/chef-backend/.gitignore | 46 + files/chef-backend/.kitchen.yml | 21 + files/chef-backend/.rubocop.yml | 31 + files/chef-backend/.travis.yml | 28 + files/chef-backend/Berksfile | 3 + files/chef-backend/CHANGELOG.md | 13 + files/chef-backend/CONTRIBUTING.md | 2 + files/chef-backend/Gemfile | 29 + files/chef-backend/LICENSE | 201 +++++ files/chef-backend/MAINTAINERS.md | 16 + files/chef-backend/MAINTAINERS.toml | 27 + files/chef-backend/README.md | 124 +++ files/chef-backend/Rakefile | 61 ++ files/chef-backend/TESTING.md | 2 + files/chef-backend/attributes/default.rb | 35 + files/chef-backend/chefignore | 99 +++ files/chef-backend/libraries/helpers.rb | 23 + files/chef-backend/metadata.rb | 19 + files/chef-backend/recipes/default.rb | 22 + files/chef-backend/recipes/follower.rb | 39 + files/chef-backend/recipes/leader.rb | 39 + files/chef-backend/spec/spec_helper.rb | 4 + .../spec/unit/recipes/default_spec.rb | 13 + files/chef-backend/tasks/maintainers.rb | 76 ++ files/chef-cookbooks.sh | 17 + files/chef-server-cookbooks.sh | 11 + files/chef-server-creds.tpl | 7 + files/configuring.bash | 101 +++ files/disable_firewall.sh | 9 + files/follower-attributes-json.tpl | 23 + files/frontend-attributes-json.tpl | 13 + files/knife-rb.tpl | 11 + files/leader-attributes-json.tpl | 21 + main.tf | 812 ++++++++++++++++++ outputs.tf | 28 + terraform.tfvars.example | 44 + variables.tf | 234 +++++ 43 files changed, 2813 insertions(+) create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 files/attributes-json.tpl create mode 100644 files/chef-backend/.gitignore create mode 100644 files/chef-backend/.kitchen.yml create mode 100644 files/chef-backend/.rubocop.yml create mode 100644 files/chef-backend/.travis.yml create mode 100644 files/chef-backend/Berksfile create mode 100644 files/chef-backend/CHANGELOG.md create mode 100644 files/chef-backend/CONTRIBUTING.md create mode 100644 files/chef-backend/Gemfile create mode 100644 files/chef-backend/LICENSE create mode 100644 files/chef-backend/MAINTAINERS.md create mode 100644 files/chef-backend/MAINTAINERS.toml create mode 100644 files/chef-backend/README.md create mode 100644 files/chef-backend/Rakefile create mode 100644 files/chef-backend/TESTING.md create mode 100644 files/chef-backend/attributes/default.rb create mode 100644 files/chef-backend/chefignore create mode 100644 files/chef-backend/libraries/helpers.rb create mode 100644 files/chef-backend/metadata.rb create mode 100644 files/chef-backend/recipes/default.rb create mode 100644 files/chef-backend/recipes/follower.rb create mode 100644 files/chef-backend/recipes/leader.rb create mode 100644 files/chef-backend/spec/spec_helper.rb create mode 100644 files/chef-backend/spec/unit/recipes/default_spec.rb create mode 100644 files/chef-backend/tasks/maintainers.rb create mode 100644 files/chef-cookbooks.sh create mode 100644 files/chef-server-cookbooks.sh create mode 100644 files/chef-server-creds.tpl create mode 100755 files/configuring.bash create mode 100644 files/disable_firewall.sh create mode 100644 files/follower-attributes-json.tpl create mode 100644 files/frontend-attributes-json.tpl create mode 100644 files/knife-rb.tpl create mode 100644 files/leader-attributes-json.tpl create mode 100644 main.tf create mode 100644 outputs.tf create mode 100644 terraform.tfvars.example create mode 100644 variables.tf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..00d54b4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +terraform.tfstate +terraform.tfvars +.terraform +*.swp* +.chef +logfiles diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..a2b2bf8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,13 @@ +tf_hachef CHANGELOG +=================== + +This file is used to list changes made in each version of the tf_hachef Terraform plan. + +v0.1.0 (2016-07-15) +------------------- +- [Brian Menges] - Initial commit + +- - - +Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. + +The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..b6261e6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,75 @@ +Contributing to tf_chef_server +============================== + +All contributors are welcome to submit patches but please keep the following in mind: + +- [Coding Standards](#coding-standards) +- [Testing](#testing) +- [Prerequisites](#prerequisites) + +Please also keep in mind: + +- Be patient as not all items will be tested or reviewed immediately by the core team. +- 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. +- Be understanding + +If you're looking to contribute but aren't sure where to start, check out the open issues. + +Will Not Merge +-------------- +This details Pull Requests that we will **not** be merged. + +- New features without accompanying tests or proof of operation +- New features without accompanying usage documentation + +Coding Standards +---------------- +The submitted code should be compatible with the following standards + +- 2-space indentation style +- First curl brace on the same line as the method +- Closing curl brace on its own aligned newline +- Variable and value assignment does not need to be aligned with assignment operator +- Where possible, avoid HEREDOC in favor of script or templates + +Testing +------- +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. + +Prerequisites +------------- +Familiarize yourself with Terraform and be well versed in its interpolations. + +- [Terraform](https://www.terraform.io/docs/index.html) + +Familiarize yourself with Chef and the operation of the chef-server cookbook + +- [chef-server](https://github.com/chef-cookbooks/chef-server) cookbook + +Familiarize yourself with Chef Backend and the installation documentation. + +- [chef-backend](https://docs.chef.io/install_server_ha.html) + +Process +------- +1. Fork the git repository from GitHub: + +3. Create a branch for your changes: + + $ git checkout -b my_bug_fix + +4. Make any changes + +5. Write tests to support those changes. + +6. Run the tests (if included) + +7. Assuming the tests pass, open a Pull Request on GitHub and add results + + +Do's and Don't's +---------------- +- **Do** include tests for your contribution +- **Do** request feedback via GitHub issues or other contact +- **Do NOT** break existing behavior (unless intentional) +- **Do NOT** modify the [CHANGELOG](CHANGELOG) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8dada3e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7cde757 --- /dev/null +++ b/README.md @@ -0,0 +1,201 @@ +# tf_hachef +Terraform module to setup a Chef Server in a HA architecture using +chef-server-core and chef-backend. Once the cluster is up and running, +recommend you use Chef to configure your Chef Server to suit your needs. + + +## Assumptions + +* Requires: + * AWS (duh!) + * Route53 internal and external zones + * Uploaded to AWS a SSL certificate (wildcard preferred) + * SSL certificate/key for created instance (local files to upload to instances) + * Terraform >= 0.6.14 +* Uses public IPs and public DNS +* Creates default security group as follows: + * Frontend: + * 443/tcp: HTTPS + * 80/tcp: HTTP + * Backend: + * ALL: inside security group + * 2379/tcp: from Frontend SG + * 5432/tcp: from Frontend SG + * 7331/tcp: from Frontend SG + * 9200/tcp: from Frontend SG + * SSH Security Group: + * 22/tcp: Default from anywhere, restrict with `${allowed_cidrs}` +* Understand Terraform and ability to read the source + + +## Usage + + +### Module + +Due to the extensive use of maps this isn't module compatible at this time. +Terraform has planned better support for maps passed to modules in version +0.7.0 but at the time of writing it is not available. + + +### Directly + +1. Clone this repo: `git clone https://github.com/mengesb/tf_hachef.git` +2. Make a local terraform.tfvars file: `cp terraform.tfvars.example terraform.tfvars` +3. Edit `terraform.tfvars` with your editor of choice, ensuring `accept_license` is set to `true` +4. Get dependencies: `terraform get` +5. Test the plan: `terraform plan` +6. Apply the plan: `terraform apply` + + +## Supported OSes +All supported OSes are 64-bit and HVM (though PV should be supported) + +* Ubuntu 12.04 LTS +* Ubuntu 14.04 LTS (default) +* Ubuntu 16.04 LTS (pending) +* CentOS 6 +* CentOS 7 (pending) +* Others (here be dragons! Please see Map Variables) + + +## AWS + +These resources will incur charges on your AWS bill. It is your responsibility to delete the resources. + + +## Input variables + + +### AWS variables (including AWS maps) + +* `aws_settings`: AWS provisioner settings map + * `access_key`: Your AWS key, usually referred to as `AWS_ACCESS_KEY_ID` + * `secret_key`: Your secret for your AWS key, usually referred to as `AWS_SECRET_ACCESS_KEY` + * `region`: AWS region you want to deploy to. Default: `us-east-1` +* `aws_vpc`: AWS VPC settings map + * `cidr_block`: CIDR block for VPC creation. Default: `10.20.30.0/24` + * `instance_tenancy`: AWS instance tenancy. Default: `default` + * `enable_dns_support`: Support DNS in VPC (required). Default: `true` + * `enable_dns_hostnames`: Support DNS hostnames (required). Default: `true` + * `tags_name`: AWS Name tag for VPC. Default: `Chef HA VPC` +* `aws_subnets`: AWS map to create subnets in VPC + * `KEY`: You create the key labeled as the availability zone (i.e us-east-1a) + * Default keys: `us-east-1a`, `us-east-1c`, `us-east-1d`, `us-east-1e` + * `VALUE`: Value is the CIDR subnet to create in that availability zone + * Default values: `10.20.30.0/26`, `10.20.30.64/26`, `10.20.30.128/26`, `10.20.30.192/26` +* `aws_subnet_map`: Subnet map defaulting the public IP assignment in that availability zone's subnet + * `KEY`: Must have the same keys as `aws_subnets`. Default: reference `aws_subnets` + * `VALUE`: Can be `true` or `false`. Default: `true` +* `aws_route53`: Map for internal and external Route53 zone IDs + * `internal`: Route53 internal zone ID + * `external`: Route53 external zone ID +* `aws_elb_certificate`: AWS identifier for uploaded SSL certificate to use with AWS ELB +* `aws_flavor`: The AWS instance type. Default: `c3.xlarge` +* `aws_key_name`: The private key pair name on AWS to use (String) +* `aws_private_key_file`: The full path to the private kye matching `aws_key_name` public key on AWS + + +### tf_hachef specific variables + +* `accept_license`: [Chef MLSA license](https://www.chef.io/online-master-agreement/) agreement. Default: `false`; change to `true` to indicate agreement +* `allowed_cidrs`: The comma seperated list of addresses in CIDR format to allow SSH access. Default: `0.0.0.0/0` +* `be_hostname`: Base hostname to generate backend hostnames. Default: `localhostbe` +* `chef_clientv`: Chef client version. Default: `12.12.15` +* `chef_serverv`: Chef Server version to install. Default `12.8.0` +* `chef_orgl`: Chef organization long name. Default: `Chef Organization` +* `chef_orgs`: Chef organization to create. Default: `chef` +* `chef_usre`: Chef Server user's e-mail address. Default: `chef@domain.tld` +* `chef_usrf`: Chef Server user's first name. Default: `Chef` +* `chef_usrl`: Chef Server user's last name. Default: `User` +* `chef_usrn`: First Chef Server user. Default: `chef` +* `domain`: Server's basename. Default: `localhost` +* `fe_hostname`: Base hostname to generate frontend hostnames. Default: `localhostfe` +* `hostname`: Chef server's API hostname. Default: `localhost` +* `log_to_file`: Log chef-client to file. Default: `true` +* `public_ip`: Associate public IP to instance. Default `true` +* `root_delete_termination`: Delete root device on VM termination. Default: `true` +* `root_volume_size`: Size of the root volume in GB. Default: `20` +* `root_volume_type`: Type of root volume. Supports `gp2` and `standard`. Default: `standard` +* `route53_ttl`: Default Route53 record TTL. Default: `180` +* `ssl_cert`: SSL certificate in PEM format +* `ssl_key`: SSL certificate key +* `tag_description`: AWS instance Name tag. Default `Created using Terraform` + + +### Map variables + +The below mapping variables construct selection criteria + +* `ami_map`: AMI selection map comprised of `ami_os` and `aws_region` +* `ami_usermap`: Default username selection map based off `ami_os` + +The `ami_map` is a combination of `ami_os` and `aws_region` which declares the +AMI selected. To override this pre-declared AMI, define + +``` +ami_map.- = "value" +``` + +Variable `ami_os` should be one of the following: + +* centos6 +* centos7 +* ubuntu12 +* ubuntu14 (default) +* ubuntu16 + +Variable `aws_region` should be one of the following: + +* us-east-1 (default) +* us-west-2 +* us-west-1 +* eu-central-1 +* eu-west-1 +* ap-southeast-1 +* ap-southeast-2 +* ap-northeast-1 +* ap-northeast-2 +* sa-east-1 +* Custom (must be an AWS region, requires setting `ami_map` and setting AMI value) + +Map `ami_usermap` uses `ami_os` to look the default username for interracting +with the instance. To override this pre-declared user, define + +``` +ami_usermap. = "value" +``` + + +## Outputs + +* `credentials`: Formatted text output with details about the Chef Server + + +## Contributors + +* [Brian Menges](https://github.com/mengesb) + + +## Runtime sample + +Unavailable at this time + + +## Contributing + +Please understand that this is a work in progress and is subject to change +rapidly. Be sure to keep up to date with the repo should you fork, and feel +free to contact me regarding development and suggested direction. Familiarize +yoursef with the [contributing](CONTRIBUTING.md) before making/submitting changes. + + +## CHANGELOG + +Please refer to the [`CHANGELOG.md`](CHANGELOG.md) + + +## License + +This is licensed under [the Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). + diff --git a/files/attributes-json.tpl b/files/attributes-json.tpl new file mode 100644 index 0000000..30737fe --- /dev/null +++ b/files/attributes-json.tpl @@ -0,0 +1,13 @@ +{ + "fqdn": "${host}.${domain}", + "chef_client": { + "init_style": "none" + }, + "system": { + "delay_network_restart": false, + "domain_name": "${domain}", + "manage_hostsfile": true, + "short_hostname": "${host}" + }, + "tags": [] +} diff --git a/files/chef-backend/.gitignore b/files/chef-backend/.gitignore new file mode 100644 index 0000000..80da1cd --- /dev/null +++ b/files/chef-backend/.gitignore @@ -0,0 +1,46 @@ +*.gem +.zero-knife.rb +*.rbc +.bundle +.config +coverage +InstalledFiles +lib/bundler/man +pkg +rdoc +spec/reports +test/tmp +test/version_tmp +tmp +Gemfile.lock +_Store +*~ +*# +.#* +\#*# +.*.sw[a-z] +*.un~ +*.tmp +*.bk +*.bkup +.ruby-version +.ruby-gemset +.rvmrc + +# YARD artifacts +.yardoc +_yardoc +doc/ +.idea + +#chef stuff +Berksfile.lock +.kitchen +.kitchen.local.yml +vendor/ +.coverage/ + +#vagrant stuff +.vagrant/ +.vagrant.d/ +.kitchen/ diff --git a/files/chef-backend/.kitchen.yml b/files/chef-backend/.kitchen.yml new file mode 100644 index 0000000..d1e2874 --- /dev/null +++ b/files/chef-backend/.kitchen.yml @@ -0,0 +1,21 @@ +--- +driver: + name: vagrant + customize: + memory: 2048 + cpus: 4 + +provisioner: + name: chef_solo + +platforms: + - name: ubuntu-14.04 + +suites: + - name: default + run_list: + - recipe[chef-backend] + attributes: + chef-backend: + accept_license: true + leader: true diff --git a/files/chef-backend/.rubocop.yml b/files/chef-backend/.rubocop.yml new file mode 100644 index 0000000..8a3657b --- /dev/null +++ b/files/chef-backend/.rubocop.yml @@ -0,0 +1,31 @@ +AllCops: + Exclude: + - vendor/**/* + - Guardfile + +AlignParameters: + Enabled: false +ClassLength: + Enabled: false +CyclomaticComplexity: + Enabled: false +Documentation: + Enabled: false +Encoding: + Enabled: false +Style/FileName: + Enabled: false +LineLength: + Enabled: false +MethodLength: + Enabled: false +Metrics/AbcSize: + Enabled: false +PerceivedComplexity: + Enabled: false +SpaceBeforeFirstArg: + Enabled: false +Style/ClassAndModuleChildren: + Enabled: false +Style/FileName: + Enabled: false diff --git a/files/chef-backend/.travis.yml b/files/chef-backend/.travis.yml new file mode 100644 index 0000000..165812a --- /dev/null +++ b/files/chef-backend/.travis.yml @@ -0,0 +1,28 @@ +# Use Travis's cointainer based infrastructure +sudo: false +addons: + apt: + sources: + - chef-current-trusty + packages: + - chefdk + +# Don't `bundle install` +install: echo "skip bundle install" + +branches: + only: + - master + +# Ensure we make ChefDK's Ruby the default +before_script: + - eval "$(/opt/chefdk/bin/chef shell-init bash)" + # We have to install chef-sugar for ChefSpec + - /opt/chefdk/embedded/bin/chef gem install chef-sugar +script: + - /opt/chefdk/embedded/bin/chef --version + - /opt/chefdk/embedded/bin/rubocop --version + - /opt/chefdk/embedded/bin/rubocop + - /opt/chefdk/embedded/bin/foodcritic --version + - /opt/chefdk/embedded/bin/foodcritic . --exclude spec + - /opt/chefdk/embedded/bin/rspec spec diff --git a/files/chef-backend/Berksfile b/files/chef-backend/Berksfile new file mode 100644 index 0000000..34fea21 --- /dev/null +++ b/files/chef-backend/Berksfile @@ -0,0 +1,3 @@ +source 'https://supermarket.chef.io' + +metadata diff --git a/files/chef-backend/CHANGELOG.md b/files/chef-backend/CHANGELOG.md new file mode 100644 index 0000000..c46e773 --- /dev/null +++ b/files/chef-backend/CHANGELOG.md @@ -0,0 +1,13 @@ +chef-backend CHANGELOG +====================== + +This file is used to list changes made in each version of the chef-backend cookbook. + +0.1.0 +----- +- [Brian Menges](https://github.com/mengesb) - Initial release of chef-backend + +- - - +Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. + +The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/files/chef-backend/CONTRIBUTING.md b/files/chef-backend/CONTRIBUTING.md new file mode 100644 index 0000000..ef2f2b8 --- /dev/null +++ b/files/chef-backend/CONTRIBUTING.md @@ -0,0 +1,2 @@ +Please refer to +https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD diff --git a/files/chef-backend/Gemfile b/files/chef-backend/Gemfile new file mode 100644 index 0000000..3653c3c --- /dev/null +++ b/files/chef-backend/Gemfile @@ -0,0 +1,29 @@ +source 'https://rubygems.org' + +group :rake do + gem 'rake' + gem 'tomlrb' +end + +group :lint do + gem 'foodcritic', '~> 5.0' + gem 'rubocop', '~> 0.34' +end + +group :unit do + gem 'berkshelf', '~> 4.0' + gem 'chefspec', '~> 4.4' +end + +group :kitchen_common do + gem 'test-kitchen', '~> 1.4' +end + +group :kitchen_vagrant do + gem 'kitchen-vagrant', '~> 0.19' +end + +group :kitchen_cloud do + gem 'kitchen-digitalocean' + gem 'kitchen-ec2' +end diff --git a/files/chef-backend/LICENSE b/files/chef-backend/LICENSE new file mode 100644 index 0000000..1b91cbb --- /dev/null +++ b/files/chef-backend/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2008-2015 Chef Software Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/files/chef-backend/MAINTAINERS.md b/files/chef-backend/MAINTAINERS.md new file mode 100644 index 0000000..46caca5 --- /dev/null +++ b/files/chef-backend/MAINTAINERS.md @@ -0,0 +1,16 @@ + + +# Maintainers +This file lists how this cookbook project is maintained. When making changes to the system, this +file tells you who needs to review your patch - you need a simple majority of maintainers +for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need +to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) +for details on the process and how to become a maintainer or the project lead. + +# Project Maintainer +* [Brian Menges](https://github.com/mengesb) + +# Maintainers +* None diff --git a/files/chef-backend/MAINTAINERS.toml b/files/chef-backend/MAINTAINERS.toml new file mode 100644 index 0000000..1f860cf --- /dev/null +++ b/files/chef-backend/MAINTAINERS.toml @@ -0,0 +1,27 @@ +# +# This file is structured to be consumed by both humans and computers. +# It is a TOML document containing Markdown +# +[Preamble] + title = "Maintainers" + text = """ +This file lists how this cookbook project is maintained. When making changes to the system, this +file tells you who needs to review your patch - you need a simple majority of maintainers +for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need +to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) +for details on the process and how to become a maintainer or the project lead. +""" + +[Org] + [Org.Components] + [Org.Components.Core] + title = "Project Maintainer" + + lieutenant = 'mengesb' + +[people] + [people.mengesb] + name = "Brian Menges" + github = "mengesb" diff --git a/files/chef-backend/README.md b/files/chef-backend/README.md new file mode 100644 index 0000000..6fa7118 --- /dev/null +++ b/files/chef-backend/README.md @@ -0,0 +1,124 @@ +chef-backend Cookbook +======================= + +[![Build Status](https://travis-ci.org/mengesb/chef-backend.svg?branch=master)](https://travis-ci.org/mengesb/chef-backend) +[![Cookbook Version](https://img.shields.io/cookbook/v/chef-backend.svg)](https://supermarket.chef.io/cookbooks/chef-backend) + +This cookbook configures a system to be a Chef backend Server. It will install +the appropriate platform-specific backend Omnibus package from Package Cloud +and perform the initial configuration. + + +Requirements +------------ +This cookbook is tested with Chef (client) 12. It may work with or +without modification on earlier versions of Chef, but Chef 12 is +recommended. + +## Cookbooks + +* chef-ingredient cookbook + +## Platform + +This cookbook is tested on the following platforms using the +[Test Kitchen](http://kitchen.ci) `.kitchen.yml` in the repository. + +- Ubuntu 14.04 64-bit + +By default this cookbook is designed to setup and create the leader node for +the chef backend cluster. To setup a follower node of the cluster, update +the following options: + +* `node['chef-backend']['leader_ipaddress']` +* `node['chef-backend']['secrets_file']` +* `node['chef-backend']['leader'] = false` + +Of course be sure to accept the Chef MLSA license agreement. + +Attributes +---------- + +#### chef-backend::default + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyTypeDescriptionDefault
['chef-backend']['accept_license']BooleanIndication that you accept the Chef MLSAfalse
['chef-backend']['channel']SymbolRepo channel to source package from:stable
['chef-backend']['ipaddress']StringThis node's IP addressnode['ipaddress']
['chef-backend ']['leader']BooleanLeader node for initial configurationtrue
['chef-backend']['leader_ipaddress']StringLeader node's IP addressnil
['chef-backend']['package_source']StringAnything other than package cloudnil
['chef-backend']['secrets_file']StringPath to chef-backend-secrets.json filenil
['chef-backend']['version']StringWhat version of backend to installnil
+ +Usage +----- +#### chef-backend::default + +Add chef-backend to your run list and accept the license agreement by setting +`node['chef-backend']['accept_license'] = true` + +# License and Authors + +* Author: Brian Menges +* Copyright 2016, Brian Menges + +```text +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` diff --git a/files/chef-backend/Rakefile b/files/chef-backend/Rakefile new file mode 100644 index 0000000..3c52bbb --- /dev/null +++ b/files/chef-backend/Rakefile @@ -0,0 +1,61 @@ +require 'rspec/core/rake_task' +require 'rubocop/rake_task' +require 'foodcritic' +require 'kitchen' + +require_relative 'tasks/maintainers' + +# Style tests. Rubocop and Foodcritic +namespace :style do + desc 'Run Ruby style checks' + RuboCop::RakeTask.new(:ruby) + + desc 'Run Chef style checks' + FoodCritic::Rake::LintTask.new(:chef) do |t| + t.options = { + fail_tags: ['any'], + tags: ['~FC005'] + } + end +end + +desc 'Run all style checks' +task style: ['style:chef', 'style:ruby'] + +# Rspec and ChefSpec +desc 'Run ChefSpec examples' +RSpec::Core::RakeTask.new(:spec) + +# Integration tests. Kitchen.ci +namespace :integration do + desc 'Run Test Kitchen with Vagrant' + task :vagrant do + Kitchen.logger = Kitchen.default_file_logger + Kitchen::Config.new.instances.each do |instance| + instance.test(:always) + end + end + + desc 'Run Test Kitchen with cloud plugins' + task :cloud do + run_kitchen = true + if ENV['TRAVIS'] == 'true' && ENV['TRAVIS_PULL_REQUEST'] != 'false' + run_kitchen = false + end + + if run_kitchen + Kitchen.logger = Kitchen.default_file_logger + @loader = Kitchen::Loader::YAML.new(project_config: './.kitchen.cloud.yml') + config = Kitchen::Config.new(loader: @loader) + config.instances.each do |instance| + instance.test(:always) + end + end + end +end + +desc 'Run all tests on Travis' +task travis: ['style', 'spec', 'integration:cloud'] + +# Default +task default: ['style', 'spec', 'integration:vagrant'] diff --git a/files/chef-backend/TESTING.md b/files/chef-backend/TESTING.md new file mode 100644 index 0000000..ca524ab --- /dev/null +++ b/files/chef-backend/TESTING.md @@ -0,0 +1,2 @@ +Please refer to +https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/TESTING.MD diff --git a/files/chef-backend/attributes/default.rb b/files/chef-backend/attributes/default.rb new file mode 100644 index 0000000..813aa65 --- /dev/null +++ b/files/chef-backend/attributes/default.rb @@ -0,0 +1,35 @@ +# +# Cookbook Name:: chef-backend +# Attributes:: default +# +# Copyright:: Copyright (c) 2016 Brian Menges +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +default['chef-backend']['accept_license'] = false +default['chef-backend']['channel'] = :stable +default['chef-backend']['ipaddress'] = node['ipaddress'] +default['chef-backend']['leader'] = true +default['chef-backend']['leader_ipaddress'] = nil +default['chef-backend']['package_source'] = nil +default['chef-backend']['secrets_file'] = nil +default['chef-backend']['version'] = nil + +# +# Tunables +# +# For a complete list see: +# https://docs.chef.io/install_backend.html +# +default['chef-backend']['configuration'] = nil diff --git a/files/chef-backend/chefignore b/files/chef-backend/chefignore new file mode 100644 index 0000000..75d2251 --- /dev/null +++ b/files/chef-backend/chefignore @@ -0,0 +1,99 @@ +# Put files/directories that should be ignored in this file when uploading +# or sharing to the community site. +# Lines that start with '# ' are comments. + +# OS generated files # +###################### +.DS_Store +Icon? +nohup.out +ehthumbs.db +Thumbs.db + +# SASS # +######## +.sass-cache + +# EDITORS # +########### +\#* +.#* +*~ +*.sw[a-z] +*.bak +REVISION +TAGS* +tmtags +*_flymake.* +*_flymake +*.tmproj +.project +.settings +mkmf.log + +## COMPILED ## +############## +a.out +*.o +*.pyc +*.so +*.com +*.class +*.dll +*.exe +*/rdoc/ + +# Testing # +########### +.watchr +.rspec +spec/* +spec/fixtures/* +test/* +features/* +examples/* +Guardfile +Procfile +test/* +spec/* + +# SCM # +####### +.git +*/.git +.gitignore +.gitmodules +.gitconfig +.gitattributes +.svn +*/.bzr/* +*/.hg/* +*/.svn/* + +# Berkshelf # +############# +Berksfile +Berksfile.lock +cookbooks/* +tmp + +# Cookbooks # +############# +CONTRIBUTING +CHANGELOG* + +# Strainer # +############ +Colanderfile +Strainerfile +.colander +.strainer + +# Vagrant # +########### +.vagrant +Vagrantfile + +# Travis # +########## +.travis.yml diff --git a/files/chef-backend/libraries/helpers.rb b/files/chef-backend/libraries/helpers.rb new file mode 100644 index 0000000..fc60dae --- /dev/null +++ b/files/chef-backend/libraries/helpers.rb @@ -0,0 +1,23 @@ +# Reference: https://github.com/chef-cookbooks/chef-server/blob/master/libraries/helpers.rb +module ChefBackendCookbook + module Helpers + def api_fqdn_available? + return false if node['chef-backend'].nil? + return false if node['chef-backend']['api_fqdn'].nil? + !node['chef-backend']['api_fqdn'].empty? + end + + def api_fqdn_resolves? + ChefIngredientCookbook::Helpers.fqdn_resolves?( + node['chef-backend']['api_fqdn'] + ) + end + + def repair_api_fqdn + fe = Chef::Util::FileEdit.new('/etc/hosts') + fe.insert_line_if_no_match(/#{node['chef-backend']['api_fqdn']}/, + "127.0.0.1 #{node['chef-backend']['api_fqdn']}") + fe.write_file + end + end +end diff --git a/files/chef-backend/metadata.rb b/files/chef-backend/metadata.rb new file mode 100644 index 0000000..daee1f6 --- /dev/null +++ b/files/chef-backend/metadata.rb @@ -0,0 +1,19 @@ +name 'chef-backend' +maintainer 'Brian Menges' +maintainer_email 'mengesb@users.noreply.github.com' +license 'Apache 2.0' +description 'Installs/Configures chef-backend' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' + +depends 'chef-ingredient', '>= 0.18.4' + +recipe 'leader', 'Installs chef-backend leader node' +recipe 'follower', 'Installs chef-backend follower node (requires leader)' + +%w(redhat centos debian ubuntu amazon).each do |os| + supports os +end + +source_url 'https://github.com/mengesb/chef-backend' if respond_to?(:source_url) +issues_url 'https://github.com/mengesb/chef-backend/issues' if respond_to?(:issues_url) diff --git a/files/chef-backend/recipes/default.rb b/files/chef-backend/recipes/default.rb new file mode 100644 index 0000000..5c28731 --- /dev/null +++ b/files/chef-backend/recipes/default.rb @@ -0,0 +1,22 @@ +# +# Copyright:: Copyright (c) 2016 Brian Menges +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +case node['chef-backend']['leader'] +when true + include_recipe 'chef-backend::leader' # ~FC007 +when false + include_recipe 'chef-backend::follower' # ~FC007 +end diff --git a/files/chef-backend/recipes/follower.rb b/files/chef-backend/recipes/follower.rb new file mode 100644 index 0000000..6ce5d7f --- /dev/null +++ b/files/chef-backend/recipes/follower.rb @@ -0,0 +1,39 @@ +# +# Copyright:: Copyright (c) 2016 Brian Menges +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +chef_ingredient 'chef-backend' do + channel node['chef-backend']['channel'].to_sym + version node['chef-backend']['version'] unless node['chef-backend']['version'].nil? + package_source node['chef-backend']['package_source'] + accept_license node['chef-backend']['accept_license'] + config <<-EOS +publish_address "#{node['chef-backend']['ipaddress']}" +#{node['chef-backend']['configuration']} +EOS + action :upgrade +end + +execute 'join_cluster' do + command "chef-backend-ctl join-cluster #{node['chef-backend']['leader_ipaddress']} -s #{node['chef-backend']['secrets_file']} --accept-license --yes" + action :nothing + only_if { node['chef-backend']['accept_license'] == true } + not_if { File.exist?("#{Chef::Config[:file_cache_path]}/chef-backend-secrets.json") } +end + +ingredient_config 'chef-backend' do + notifies :run, 'execute[join_cluster]', :immediately + notifies :reconfigure, 'chef_ingredient[chef-backend]', :immediately +end diff --git a/files/chef-backend/recipes/leader.rb b/files/chef-backend/recipes/leader.rb new file mode 100644 index 0000000..f5051d1 --- /dev/null +++ b/files/chef-backend/recipes/leader.rb @@ -0,0 +1,39 @@ +# +# Copyright:: Copyright (c) 2016 Brian Menges +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +chef_ingredient 'chef-backend' do + channel node['chef-backend']['channel'].to_sym + version node['chef-backend']['version'] unless node['chef-backend']['version'].nil? + package_source node['chef-backend']['package_source'] + accept_license node['chef-backend']['accept_license'] + config <<-EOS +publish_address "#{node['chef-backend']['ipaddress']}" +#{node['chef-backend']['configuration']} +EOS + action :upgrade +end + +execute 'create_cluster' do + command 'chef-backend-ctl create-cluster --accept-license --yes' + action :nothing + only_if { node['chef-backend']['accept_license'] == true } + not_if { File.exist?("#{Chef::Config[:file_cache_path]}/chef-backend-secrets.json") } +end + +ingredient_config 'chef-backend' do + notifies :run, 'execute[create_cluster]', :immediately + notifies :reconfigure, 'chef_ingredient[chef-backend]', :immediately +end diff --git a/files/chef-backend/spec/spec_helper.rb b/files/chef-backend/spec/spec_helper.rb new file mode 100644 index 0000000..4e00004 --- /dev/null +++ b/files/chef-backend/spec/spec_helper.rb @@ -0,0 +1,4 @@ +require 'chefspec' +require 'chefspec/berkshelf' + +at_exit { ChefSpec::Coverage.report! } diff --git a/files/chef-backend/spec/unit/recipes/default_spec.rb b/files/chef-backend/spec/unit/recipes/default_spec.rb new file mode 100644 index 0000000..60275bd --- /dev/null +++ b/files/chef-backend/spec/unit/recipes/default_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' + +describe 'default recipe on Ubuntu 14.04' do + let(:chef_run) do + ChefSpec::ServerRunner.new do |node| + node.automatic[:lsb][:codename] = 'trusty' + end.converge('chef-compliance::default') + end + + it 'converges successfully' do + expect { :chef_run }.to_not raise_error + end +end diff --git a/files/chef-backend/tasks/maintainers.rb b/files/chef-backend/tasks/maintainers.rb new file mode 100644 index 0000000..7e99633 --- /dev/null +++ b/files/chef-backend/tasks/maintainers.rb @@ -0,0 +1,76 @@ +# +# Copyright:: Copyright (c) 2015 Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'rake' + +SOURCE = File.join(File.dirname(__FILE__), '..', 'MAINTAINERS.toml') +TARGET = File.join(File.dirname(__FILE__), '..', 'MAINTAINERS.md') + +begin + require 'tomlrb' + task default: 'maintainers:generate' + + namespace :maintainers do + desc 'Generate MarkDown version of MAINTAINERS file' + task :generate do + @toml = Tomlrb.load_file SOURCE + out = "\n\n" + + out << preamble + out << project_lieutenant + out << all_maintainers + + File.open(TARGET, 'w') do |fn| + fn.write out + end + end + end + +rescue LoadError + STDERR.puts "\n*** TomlRb not available.\n\n" +end + +private + +def preamble + <<-EOL +# #{@toml['Preamble']['title']} +#{@toml['Preamble']['text']} +EOL +end + +def project_lieutenant + <<-EOL +# #{@toml['Org']['Components']['Core']['title']} +#{github_link(@toml['Org']['Components']['Core']['lieutenant'])} + +EOL +end + +def all_maintainers + text = "# Maintainers\n" + @toml['Org']['Components']['Core']['maintainers'].each do |m| + text << "#{github_link(m)}\n" + end + text +end + +def github_link(person) + name = @toml['people'][person]['name'] + github = @toml['people'][person]['github'] + "* [#{name}](https://github.com/#{github})" +end diff --git a/files/chef-cookbooks.sh b/files/chef-cookbooks.sh new file mode 100644 index 0000000..62a8297 --- /dev/null +++ b/files/chef-cookbooks.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +sudo rm -rf /var/chef/cookbooks ; sudo mkdir -p /var/chef/cookbooks +sudo rm -rf /var/chef/cache ; sudo mkdir -p /var/chef/cache +sudo rm -rf /var/chef/ssl ; sudo mkdir -p /var/chef/ssl + +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 +for DEP in chef_handler chef-ingredient ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done +for DEP in chef-server chef-sugar ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done +for DEP in compat_resource cron ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done +for DEP in firewall hostsfile logrotate ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done +for DEP in packagecloud system yum ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done +for DEP in yum-chef windows ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done + +sudo chown -R root:root /var/chef + +exit 0 diff --git a/files/chef-server-cookbooks.sh b/files/chef-server-cookbooks.sh new file mode 100644 index 0000000..fb581e3 --- /dev/null +++ b/files/chef-server-cookbooks.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +sudo rm -rf /var/chef/cookbooks ; sudo mkdir -p /var/chef/cookbooks +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 +for DEP in chef_handler chef-ingredient ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done +for DEP in chef-server chef-sugar ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done +for DEP in compat_resource cron ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done +for DEP in firewall hostsfile logrotate ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done +for DEP in packagecloud system yum ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done +for DEP in yum-chef windows ; do curl -sL https://supermarket.chef.io/cookbooks/${DEP}/download | sudo tar xzC /var/chef/cookbooks; done +sudo chown -R root:root /var/chef/cookbooks +echo Finished diff --git a/files/chef-server-creds.tpl b/files/chef-server-creds.tpl new file mode 100644 index 0000000..17a79e3 --- /dev/null +++ b/files/chef-server-creds.tpl @@ -0,0 +1,7 @@ + +Username: ${user} +Password: ${pass} +User PEM: ${user_p} +Organization: ${org} +Org Validator: ${pem} +Web login: https://${fqdn}/organizations/${org} diff --git a/files/configuring.bash b/files/configuring.bash new file mode 100755 index 0000000..29a3fa1 --- /dev/null +++ b/files/configuring.bash @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +#set -x # Debugging + +# ----------------------------------------------------------------------------- +VERSION=1.0 +AUTHOR="Brian Menges" +AUTHOR_EMAIL="mengesb@gmail.com" +LICENSE="Apache 2.0" +LICENSE_URL="http://www.apache.org/licenses/LICENSE-2.0" +# ----------------------------------------------------------------------------- + +# Usage +usage() +{ + cat < + Version: ${VERSION} + Licensed under ${LICENSE} (${LICENSE_URL}) + + This script is designed to establish a lock only after all other locks of a + similar type have been released. This script doesn't release the lock so you + are left to solve that segment of the problem. This script is designed to + sleep until a lock can be stablished + + OPTIONAL OPTIONS: + -d Destination directory ex. /tmp (default) + -f Filename (this should be unique) + -h This help message + -v Verbose output +EOF +} + +# Generate random number +rand() +{ + local MIN=$1 + local MAX=$2 + local NUM=0 + + while [ "$NUM" -le $MIN ] + do + NUM=$RANDOM + let "NUM %= $MAX" + done + + echo $NUM +} + +# Requirements check +d_directory=/tmp +VAR=$(echo "$BASH_VERSION") +[[ $? -ne 0 ]] && echo "Unable to determine BASH version installed, exiting." && usage && exit 1 +[[ "${BASH_VERSION}" =~ ^[0-3] ]] && echo "Script requires a BASH version 4.x or higher, found ${BASH_VERSION}" && usage && exit 1 +[[ -z "$(grep --version)" ]] && echo "Program 'grep' not found in PATH!" && usage && exit 1 + +# Options parsing +while getopts ":f:d:hv" OPTION; do + case "$OPTION" in + f) + f_filename=${OPTARG} + ;; + d) + if [[ -d ${OPTARG} ]]; then + d_directory=${OPTARG} + fi + ;; + h) + usage && exit 0 + ;; + v) + VERBOSE=1 + ;; + *) + usage && exit 1 + ;; + ?) + usage && exit 1 + ;; + esac +done + +# +# Main +# + +sleep $(rand 5 31) +C=$(ls $d_directory | grep -Ec 'configuring\.') + +while [ "$C" -gt 0 ] +do + number=$(rand 5 20) + echo "Waiting for $C proccesses to complete; sleeping $number seconds" && sleep $number + C=$(ls $d_directory | grep -Ec 'configuring\.') +done + +touch ${d_directory}/configuring.${f_filename} + +exit 0 + diff --git a/files/disable_firewall.sh b/files/disable_firewall.sh new file mode 100644 index 0000000..aa1657b --- /dev/null +++ b/files/disable_firewall.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +[ $EUID -ne 0 ] && PREPEND="sudo" || PREPEND="" +$PREPEND service iptables stop +$PREPEND chkconfig iptables off +$PREPEND ufw disable + +echo "Attempted to stop iptables/ufw" +exit 0 diff --git a/files/follower-attributes-json.tpl b/files/follower-attributes-json.tpl new file mode 100644 index 0000000..959de9b --- /dev/null +++ b/files/follower-attributes-json.tpl @@ -0,0 +1,23 @@ +{ + "fqdn": "${host}.${domain}", + "chef_client": { + "init_style": "none" + }, + "chef-backend": { + "accept_license": ${license}, + "leader": false, + "leader_ipaddress": "${leader}", + "secrets_file": "${secrets}" + }, + "firewall": { + "allow_established": true, + "allow_ssh": true + }, + "system": { + "delay_network_restart": false, + "domain_name": "${domain}", + "manage_hostsfile": true, + "short_hostname": "${host}" + }, + "tags": [] +} diff --git a/files/frontend-attributes-json.tpl b/files/frontend-attributes-json.tpl new file mode 100644 index 0000000..30737fe --- /dev/null +++ b/files/frontend-attributes-json.tpl @@ -0,0 +1,13 @@ +{ + "fqdn": "${host}.${domain}", + "chef_client": { + "init_style": "none" + }, + "system": { + "delay_network_restart": false, + "domain_name": "${domain}", + "manage_hostsfile": true, + "short_hostname": "${host}" + }, + "tags": [] +} diff --git a/files/knife-rb.tpl b/files/knife-rb.tpl new file mode 100644 index 0000000..c725027 --- /dev/null +++ b/files/knife-rb.tpl @@ -0,0 +1,11 @@ +current_dir = File.dirname(__FILE__) +log_level :info +log_location STDOUT +node_name '${user}' +client_key "#{current_dir}/${user}.pem" +validation_client_name '${org}-validator' +validation_key "#{current_dir}/${org}-validator.pem" +chef_server_url 'https://${fqdn}/organizations/${org}' +cache_type 'BasicFile' +cache_options( :path => "#{current_dir}/checksums" ) +cookbook_path ["#{current_dir}/local-mode-cache/cache/cookbooks"] diff --git a/files/leader-attributes-json.tpl b/files/leader-attributes-json.tpl new file mode 100644 index 0000000..57ce548 --- /dev/null +++ b/files/leader-attributes-json.tpl @@ -0,0 +1,21 @@ +{ + "fqdn": "${host}.${domain}", + "chef_client": { + "init_style": "none" + }, + "chef-backend": { + "accept_license": ${license}, + "leader": ${leader} + }, + "firewall": { + "allow_established": true, + "allow_ssh": true + }, + "system": { + "delay_network_restart": false, + "domain_name": "${domain}", + "manage_hostsfile": true, + "short_hostname": "${host}" + }, + "tags": [] +} diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..e3f23af --- /dev/null +++ b/main.tf @@ -0,0 +1,812 @@ +# +# AWS Provider +# +provider "aws" { + access_key = "${lookup(var.aws_settings, "access_key")}" + region = "${lookup(var.aws_settings, "region")}" + secret_key = "${lookup(var.aws_settings, "secret_key")}" +} +# +# AWS VPC setup +# +resource "aws_vpc" "chef-ha-vpc" { + cidr_block = "${lookup(var.aws_vpc, "cidr_block")}" + enable_dns_hostnames = "${lookup(var.aws_vpc, "enable_dns_hostnames")}" + enable_dns_support = "${lookup(var.aws_vpc, "enable_dns_support")}" + instance_tenancy = "${lookup(var.aws_vpc, "instance_tenancy")}" + tags { + Name = "${lookup(var.aws_vpc, "tags_name")}" + } +} +# +# AWS Route53 Zone Association +# +resource "aws_route53_zone_association" "chef-ha-vpc" { + zone_id = "${lookup(var.aws_route53, "internal")}" + vpc_id = "${aws_vpc.chef-ha-vpc.id}" +} +# +# AWS Subnet setup +# +resource "aws_subnet" "chef-ha-subnet" { + count = "${length(keys(var.aws_subnets))}" + vpc_id = "${aws_vpc.chef-ha-vpc.id}" + availability_zone = "${element(keys(var.aws_subnets), count.index)}" + cidr_block = "${element(values(var.aws_subnets), count.index)}" + map_public_ip_on_launch = "${lookup(var.aws_subnet_map, element(keys(var.aws_subnets), count.index))}" + tags { + Name = "Chef HA Subnet ${element(values(var.aws_subnets), count.index)} (${element(keys(var.aws_subnets), count.index)})" + } +} +# +# AWS GW setup +# +resource "aws_internet_gateway" "chef-ha-gw" { + vpc_id = "${aws_vpc.chef-ha-vpc.id}" + tags { + Name = "${lookup(var.aws_vpc, "tags_name")} GW" + } +} +# +# AWS Route Table setup +# +# Grant the VPC internet access on its main route table +resource "aws_route" "default_gateway" { + route_table_id = "${aws_vpc.chef-ha-vpc.main_route_table_id}" + destination_cidr_block = "0.0.0.0/0" + gateway_id = "${aws_internet_gateway.chef-ha-gw.id}" +} +# Associate subnets to main routing table +resource "aws_route_table_association" "subnet_routes" { + count = "${length(keys(var.aws_subnets))}" + subnet_id = "${element(aws_subnet.chef-ha-subnet.*.id, count.index)}" + route_table_id = "${aws_vpc.chef-ha-vpc.main_route_table_id}" +} +# +# AWS Security Group setup - private services +# Chef Server AWS security group - https://docs.chef.io/server_firewalls_and_ports.html +resource "aws_security_group" "chef-ha-ssh" { + name = "${var.hostname}.${var.domain} SSH SG" + description = "${var.hostname}.${var.domain} SSH SG" + vpc_id = "${aws_vpc.chef-ha-vpc.id}" + tags { + Name = "${var.hostname}.${var.domain} SSH SG" + } +} +# SSH +resource "aws_security_group_rule" "chef-ha-ssh_22_tcp_restricted" { + type = "ingress" + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["${split(",", var.allowed_cidrs)}"] + security_group_id = "${aws_security_group.chef-ha-ssh.id}" +} +# Egress: ALL +resource "aws_security_group_rule" "chef-ha-ssh_allow_egress" { + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + security_group_id = "${aws_security_group.chef-ha-ssh.id}" +} +# +# AWS Security Group setup - public services +# +resource "aws_security_group" "chef-ha-frontend" { + name = "${var.hostname}.${var.domain} Frontend SG" + description = "${var.hostname}.${var.domain} Frontend SG" + vpc_id = "${aws_vpc.chef-ha-vpc.id}" + tags { + Name = "${var.hostname}.${var.domain} Frontend SG" + } +} +# HTTP (nginx) +resource "aws_security_group_rule" "chef-ha-frontend_80_tcp" { + type = "ingress" + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + security_group_id = "${aws_security_group.chef-ha-frontend.id}" +} +# HTTPS (nginx) +resource "aws_security_group_rule" "chef-ha-frontend_443_tcp" { + type = "ingress" + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + security_group_id = "${aws_security_group.chef-ha-frontend.id}" +} +# Egress: ALL +resource "aws_security_group_rule" "chef-ha-frontend_allow_egress" { + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + security_group_id = "${aws_security_group.chef-ha-frontend.id}" +} +# +# AWS Security Group setup - backend services +# +resource "aws_security_group" "chef-ha-backend" { + name = "${var.hostname}.${var.domain} Backend SG" + description = "${var.hostname}.${var.domain} Backend SG" + vpc_id = "${aws_vpc.chef-ha-vpc.id}" + tags { + Name = "${var.hostname}.${var.domain} Backend SG" + } +} +# inner security group communication +resource "aws_security_group_rule" "chef-ha-backend_sg_all" { + type = "ingress" + from_port = 0 + to_port = 0 + protocol = "-1" + source_security_group_id = "${aws_security_group.chef-ha-backend.id}" + security_group_id = "${aws_security_group.chef-ha-backend.id}" +} +# etcd +resource "aws_security_group_rule" "chef-ha-backend_2379_tcp" { + type = "ingress" + from_port = 2379 + to_port = 2379 + protocol = "tcp" + source_security_group_id = "${aws_security_group.chef-ha-frontend.id}" + security_group_id = "${aws_security_group.chef-ha-backend.id}" +} +# postgresql +resource "aws_security_group_rule" "chef-ha-backend_5432_tcp" { + type = "ingress" + from_port = 5432 + to_port = 5432 + protocol = "tcp" + source_security_group_id = "${aws_security_group.chef-ha-frontend.id}" + security_group_id = "${aws_security_group.chef-ha-backend.id}" +} +# leaderl +resource "aws_security_group_rule" "chef-ha-backend_7331_tcp" { + type = "ingress" + from_port = 7331 + to_port = 7331 + protocol = "tcp" + source_security_group_id = "${aws_security_group.chef-ha-frontend.id}" + security_group_id = "${aws_security_group.chef-ha-backend.id}" +} +# elasticsearch +resource "aws_security_group_rule" "chef-ha-backend_9200_tcp" { + type = "ingress" + from_port = 9200 + to_port = 9200 + protocol = "tcp" + source_security_group_id = "${aws_security_group.chef-ha-frontend.id}" + security_group_id = "${aws_security_group.chef-ha-backend.id}" +} +# Egress: ALL +resource "aws_security_group_rule" "chef-ha-backend_allow_egress" { + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + security_group_id = "${aws_security_group.chef-ha-backend.id}" +} +# +# AWS ELB Setup +# +resource "aws_elb" "chef-ha-frontend" { + name = "${var.hostname}-${replace(var.domain,".","-")}-ELB" + #access_logs { + #} + #availability_zones = ["${join(",",aws_subnet.chef-ha-subnet.*.availability_zone)}"] + security_groups = ["${aws_security_group.chef-ha-frontend.id}"] + subnets = ["${aws_subnet.chef-ha-subnet.*.id}"] + instances = ["${aws_instance.chef-frontend.id}","${aws_instance.chef-frontends.*.id}"] + internal = false + listener { + instance_port = 80 + instance_protocol = "http" + lb_port = 80 + lb_protocol = "http" + } + listener { + instance_port = 443 + instance_protocol = "https" + lb_port = 443 + lb_protocol = "https" + ssl_certificate_id = "${var.aws_elb_certificate}" + } + health_check { + healthy_threshold = 2 + unhealthy_threshold = 2 + timeout = 3 + target = "HTTPS:443/login" + interval = 30 + } + cross_zone_load_balancing = true + idle_timeout = 60 + connection_draining = true + connection_draining_timeout = 60 + tags { + Name = "${var.hostname}.${var.domain} Frontend ELB" + } +} +resource "aws_app_cookie_stickiness_policy" "chef-manage" { + name = "chef-manage-cookie" + load_balancer = "${aws_elb.chef-ha-frontend.id}" + lb_port = 443 + cookie_name = "chef-manage" +} +# Local prep +resource "null_resource" "chef-prep" { + provisioner "local-exec" { + command = <<-EOF + rm -rf .chef && mkdir -p .chef + openssl rand -base64 512 | tr -d '\r\n' > .chef/encrypted_data_bag_secret + echo "Local prep complete" + EOF + } +} +# Chef provisiong attributes_json and dna.json templating +resource "template_file" "be-leader-attributes-json" { + template = "${file("${path.module}/files/leader-attributes-json.tpl")}" + vars { + domain = "${var.domain}" + host = "${format("%s-%03d", var.be_hostname, count.index + 1)}" + license = "${var.accept_license}" + leader = "true" + } +} +# Chef provisiong attributes_json and dna.json templating +resource "template_file" "be-follower-attributes-json" { + count = "${length(keys(var.aws_subnets)) - 1}" + template = "${file("${path.module}/files/follower-attributes-json.tpl")}" + vars { + domain = "${var.domain}" + host = "${format("%s-%03d", var.be_hostname, count.index + 2)}" + license = "${var.accept_license}" + leader = "${aws_instance.chef-backend.private_ip}" + secrets = "/tmp/chef-backend-secrets.json" + } +} +# +# Provision servers +# Backend: chef-backend +resource "aws_instance" "chef-backend" { + ami = "${lookup(var.ami_map, "${var.ami_os}-${lookup(var.aws_settings, "region")}")}" + instance_type = "${var.aws_flavor}" + associate_public_ip_address = "${var.public_ip}" + subnet_id = "${aws_subnet.chef-ha-subnet.0.id}" + vpc_security_group_ids = ["${aws_security_group.chef-ha-backend.id}","${aws_security_group.chef-ha-ssh.id}"] + key_name = "${var.aws_key_name}" + tags = { + Name = "${format("%s-%03d.%s", var.be_hostname, count.index + 1, var.domain)}" + Description = "${var.tag_description}" + } + root_block_device { + delete_on_termination = "${var.root_delete_termination}" + volume_size = "${var.root_volume_size}" + volume_type = "${var.root_volume_type}" + } + connection { + host = "${self.public_ip}" + user = "${lookup(var.ami_usermap, var.ami_os)}" + private_key = "${var.aws_private_key_file}" + } + # Setup + provisioner "remote-exec" { + script = "${path.module}/files/disable_firewall.sh" + } + provisioner "remote-exec" { + inline = [ + "mkdir -p /var/chef/cookbooks", + "curl -L https://omnitruck.chef.io/install.sh | sudo bash -s -- -v ${var.chef_clientv}", + "echo 'Version ${var.chef_clientv} of chef-client installed'" + ] + } + # Get cookbooks + provisioner "remote-exec" { + script = "files/chef-cookbooks.sh" + } + # Put cookbook there + provisioner "file" { + source = "${path.module}/files/chef-backend" + destination = "chef-backend" + } + provisioner "remote-exec" { + inline = [ + "sudo mv chef-backend /var/chef/cookbooks/chef-backend", + "sudo chown -R root:root /var/chef/cookbooks" + ] + } + # Write dna.json for chef-solo run + provisioner "remote-exec" { + inline = [ + "cat > /tmp/dna.json < /tmp/dna.json < /tmp/chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 1, var.domain)}", + "sudo chown ${lookup(var.ami_usermap, var.ami_os)} /tmp/chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 1, var.domain)}", + "echo \"api_fqdn ${format("'%s.%s'", var.hostname, var.domain)}\" > file.out", + "sed -i '/fqdn/ r file.out' /tmp/chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 1, var.domain)}", + "rm -f file.out", + ] + } + # Get generated configuration file + # TODO: Replace chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 1, var.domain)} with chef-server.rb.${sha256(self.id)} + provisioner "local-exec" { + command = "scp -r -o stricthostkeychecking=no -i ${var.aws_private_key_file} ${lookup(var.ami_usermap, var.ami_os)}@${aws_instance.chef-backend.public_ip}:/tmp/chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 1, var.domain)} .chef/chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 1, var.domain)}" + } + # Delete chef frontend configuration + provisioner "remote-exec" { + connection { + host = "${aws_instance.chef-backend.public_ip}" + user = "${lookup(var.ami_usermap, var.ami_os)}" + private_key = "${var.aws_private_key_file}" + } + # TODO: Replace chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 1, var.domain)} with chef-server.rb.${sha256(self.id)} + inline = [ + "sudo rm -f /tmp/chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 1, var.domain)}", + ] + } + # Setup + provisioner "remote-exec" { + script = "${path.module}/files/disable_firewall.sh" + } + provisioner "remote-exec" { + script = "${path.module}/files/chef-server-cookbooks.sh" + } + # Write dna.json for chef-solo run + provisioner "remote-exec" { + inline = [ + "cat > /tmp/dna.json < /tmp/chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 2, var.domain)}", + "sudo chown ${lookup(var.ami_usermap, var.ami_os)} /tmp/chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 2, var.domain)}", + "echo \"api_fqdn ${format("'%s.%s'", var.hostname, var.domain)}\" > file.out", + "sed -i '/fqdn/ r file.out' /tmp/chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 2, var.domain)}", + "rm -f file.out", + ] + } + # Get generated configuration file + # TODO: Replace chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 1, var.domain)} with chef-server.rb.${sha256(self.id)} + provisioner "local-exec" { + command = "scp -r -o stricthostkeychecking=no -i ${var.aws_private_key_file} ${lookup(var.ami_usermap, var.ami_os)}@${aws_instance.chef-backend.public_ip}:/tmp/chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 2, var.domain)} .chef/chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 2, var.domain)}" + } + # Delete chef frontend configuration + provisioner "remote-exec" { + connection { + host = "${aws_instance.chef-backend.public_ip}" + user = "${lookup(var.ami_usermap, var.ami_os)}" + private_key = "${var.aws_private_key_file}" + } + # TODO: Replace chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 1, var.domain)} with chef-server.rb.${sha256(self.id)} + inline = [ + "sudo rm -f /tmp/chef-server.rb.${format("%s-%03d.%s", var.fe_hostname, count.index + 2, var.domain)}", + ] + } + # Setup + provisioner "remote-exec" { + script = "${path.module}/files/disable_firewall.sh" + } + provisioner "remote-exec" { + script = "${path.module}/files/chef-server-cookbooks.sh" + } + # Write dna.json for chef-solo run + provisioner "remote-exec" { + inline = [ + "cat > /tmp/dna.json < .chef/knife.rb <