terra_boi 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2e07549528cc229186be4d0024ebff13717dffe397b4da9611c2bc9e6601a21a
4
+ data.tar.gz: e3ea9d7cae1344535ecbcf33a7a22b24679e8b668980f8b4bd0e7d27eabd5551
5
+ SHA512:
6
+ metadata.gz: 9722cee6653bf1790d6ca23f957d32b42098feae3783c7b95cf0337250b6c8dcc7ea43c0fdc66bceece9aaa65ea49fdaf63d57e451c450ebc5bce110fdb581a6
7
+ data.tar.gz: 3ce672b519f3d22ec25fc71d89b149f8974e8aadc541c7d409343f0fabad56f0866a6cea04cd96050a86225dd045d787a79b0a42e6ca2127ffe8a8a69692b9fc
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2019
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,231 @@
1
+ # TerraBoi
2
+
3
+ This gem was created to get rails applications deployed into production as quickly and easily as possible.
4
+
5
+ **Raison d'etre**: creating basic infrastructure to house production SaaS applications on AWS is tedious and boring. It's often a similar process every time, and every time it sucks.
6
+
7
+ List of items created by this gem's generators:
8
+ - Dockerfile
9
+ - Rails initializer file (for setting up config.hosts)
10
+ - Packer repository (for creating AMIs)
11
+ - Terraform repository (for creating infrastructure as code to immediately deploy staging / prod infrastructure as well as rolling out application updates)
12
+
13
+ **Note**: generated Terraform files create / support remote state locking, load-balancing, auto-scaling, zero-downtime web app deployments, DBs, and S3 buckets.
14
+
15
+ **Note**: after infrastructure files are generated, you will be ready to deploy your application to staging / production on AWS. If you have more advanced infrastructure needs (e.g. Redis / Solr instances), you may add to the generated Terraform files to support this.
16
+
17
+
18
+
19
+ ## Pre-requisites
20
+
21
+ * [Terraform](https://www.terraform.io/) installed on your computer
22
+ * [Packer](https://www.packer.io/downloads.html) installed on your computer
23
+ * [Amazon Web Services (AWS) account](http://aws.amazon.com/)
24
+
25
+
26
+
27
+ ## Installation
28
+
29
+ **Note**: below installation steps should be completed in order.
30
+
31
+ ### Installation - gem
32
+
33
+ Add this line to your (Rails) application's Gemfile:
34
+
35
+ ```ruby
36
+ gem 'terra_boi'
37
+ ```
38
+
39
+ And then execute:
40
+
41
+ ```bash
42
+ $ bundle
43
+ ```
44
+
45
+ ### Installation - AWS access
46
+
47
+ Set up your [AWS access / secret access
48
+ keys](http://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) in `~/.zprofile` (or equivalent file for your shell if not using .zsh) as environment variables:
49
+
50
+ ```
51
+ export AWS_ACCESS_KEY_ID=your_access_key_id
52
+ export AWS_SECRET_ACCESS_KEY=your_secret_access_key
53
+ ```
54
+
55
+ Then run `source ~/.zprofile` (or equivalent command for your shell if not using .zsh)
56
+
57
+ ### Installation - generate infrastructure code
58
+
59
+ To generate boilerplate infrastructure code (config.host initializer filer, Dockerfile, Packer repository, and terraform repository):
60
+
61
+ `rails generate terra_boi:boilerplate --domain_name DOMAIN.COM --ruby_version 2.5.1`
62
+
63
+ ### Installation - Packer (creating web server AMIs)
64
+
65
+ **A. Create private DockerHub repository**
66
+
67
+ Create private DockerHub repository for your rails application (if possible, use the exact same name as your rails application).
68
+
69
+ **Note**: packer generator will assume your DockerHub repository has the same name as your rails application folder. If this isn't true, update generated Packer `ami_build.json` file after it is generated.
70
+
71
+ **B. Setup DockerHub access:**
72
+
73
+ Add DockerHub username and access key to `~/.zprofile` (or equivalent file for your shell if not using .zsh) as environment variables (if your image is in a private repository):
74
+
75
+ ```
76
+ DOCKERHUB_USERNAME=myname
77
+ DOCKERHUB_ACCESS_TOKEN=myAccessToken
78
+ export DOCKERHUB_USERNAME DOCKERHUB_ACCESS_TOKEN
79
+ ```
80
+
81
+ Then run `source ~/.zprofile` (or equivalent command for your shell if not using .zsh)
82
+
83
+ **Note**: DockerHub access key can be found at https://hub.docker.com/settings/security
84
+
85
+ ### Installation - Terraform (deploying DBs + web server AMIs)
86
+
87
+ **A. Set up remote state:**
88
+
89
+ `cd terraform/state`
90
+
91
+ Run `terraform init` and then `terraform apply` to set up s3 bucket and dynamoDB for remote state and locking (this will work for both prod and staging).
92
+
93
+ **B. Set up DB / S3:**
94
+
95
+ `cd terraform/[ENV]/data`
96
+
97
+ Set terraform data-related environment variables in .zprofile (or your respective shell dotfile)
98
+
99
+ ```
100
+ TF_VAR_db_password=your_password
101
+ TF_VAR_db_username=your_username
102
+ ```
103
+
104
+ To deploy infrastructure to AWS:
105
+
106
+ ```
107
+ terraform init # IF NOT ALREADY RUN
108
+ terraform apply
109
+ ```
110
+
111
+ **C. Set up web servers:**
112
+
113
+ `cd terraform/[ENV]/web_servers`
114
+
115
+ To deploy infrastructure to AWS:
116
+
117
+ ```
118
+ terraform init # IF NOT ALREADY RUN
119
+ terraform apply
120
+ ```
121
+
122
+ While aws_acm_certificate_validation.cert is creating (it will hang if you don't add CNAME verification record in ACM):
123
+
124
+ i. Log into AWS console, go to certificate management, and add the created CNAME record specified to the DNS configuration for your domain
125
+ ii. Redirect domain name to Application load balancer:
126
+ - Go to your domain registrar of choice
127
+ - Create alias record that points to the dns name of the application load balancer (use subdomain in alias record like STAGING.example.com for staging)
128
+ - Create URL redirect record for prod (redirect www.site.com to site.com)
129
+
130
+ After these changes propogate (should take about an hour or two locally), your webservers should be set up, https should be working, and you should be good to go!
131
+
132
+
133
+
134
+ ## Usage
135
+
136
+ **Note**: below usage steps should be completed in order
137
+
138
+ ### Usage - Packer (creating web server AMIs)
139
+
140
+ **A. Push latest application image to DockerHub**
141
+
142
+ You can automatically trigger DockerHub image builds when new code is pushed to a repository's master branch using DockerHub's free Github integration.
143
+
144
+ Otherwise, `docker push [DOCKER_USERNAME]/[APPLICATION_NAME]:latest`. Make sure you are pushing to a private repository.
145
+
146
+ **B. Create Packer AMI:**
147
+
148
+ ```
149
+ cd packer
150
+
151
+ packer build -var DOCKERHUB_ACCESS_TOKEN=$DOCKERHUB_ACCESS_TOKEN -var DOCKERHUB_USERNAME=$DOCKERHUB_USERNAME application.json
152
+ ```
153
+
154
+ **C. Clean up:**
155
+
156
+ Every so often you'll want to remove old AMIs created by Packer (unless you want to be charged a couple cents a month).
157
+
158
+ To remove them, deregister them on the [AWS AMI management page](https://us-east-2.console.aws.amazon.com/ec2/v2/home?region=us-east-2#Images:sort=name), then delete the associated snapshot on the [AWS snapshot management page](https://us-east-2.console.aws.amazon.com/ec2/home?region=us-east-2#Snapshots:sort=snapshotId).
159
+
160
+ ### Usage - Terraform (update web server AMIs)
161
+
162
+ **A. Update Terraform web server AMIs:**
163
+
164
+ `cd terraform/[ENV]/web_servers`
165
+
166
+ To deploy infrastructure to AWS:
167
+
168
+ ```
169
+ terraform init # IF NOT ALREADY RUN
170
+ terraform apply
171
+ ```
172
+
173
+
174
+
175
+ ## Infrastructure created
176
+
177
+ The aforementioned generators create a `terraform` directory with `state`, `prod`, and `staging` subdirectories.
178
+
179
+ The `state` directory contains an S3 bucket and a DynamoDB table to store and lock state (for both prod and staging).
180
+
181
+ The `prod` and `staging` subdirectories contain `data` (DB + S3) and `web_servers` (SSL cert, load balancing, autoscaling, EC2) directories.
182
+
183
+
184
+
185
+ ## Running tests
186
+
187
+ From the root directory:
188
+
189
+ ```
190
+ rake test
191
+ ```
192
+
193
+
194
+
195
+ ## Other tips
196
+
197
+ Clean up terraform infrastructure when no longer planning to use (DANGER FOR PROD, WILL DESTROY INFRASTRUCTURE):
198
+
199
+ `terraform destroy`
200
+
201
+ **For extra security in staging:** update Terraform web_servers `main.tf` file to only allow ingress web_server connections from your IP / your team's IPs
202
+
203
+
204
+
205
+ ## Contributing
206
+
207
+ This gem is currently not actively accepting contributions.
208
+
209
+ With that in mind, if you'd like to make a fix / change, please create a pull request (and when I have a moment - probably in a couple weeks time - I'll have a look)!
210
+
211
+
212
+
213
+ ## License
214
+
215
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
216
+
217
+
218
+
219
+ ## Updating gem version (for maintainers)
220
+
221
+ **1. Update version**
222
+
223
+ In `lib/terra_boi/version.rb` update version.
224
+
225
+ **2. Build gem**
226
+
227
+ `gem build terra_boi.gemspec`
228
+
229
+ **3. Push gem**
230
+
231
+ `gem push terra_boi-X.X.X.gem` (replace X's with version)
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'TerraBoi'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ require 'bundler/gem_tasks'
18
+
19
+ require 'rake/testtask'
20
+
21
+ Rake::TestTask.new(:test) do |t|
22
+ t.libs << 'test'
23
+ t.pattern = 'test/**/*_test.rb'
24
+ t.verbose = false
25
+ end
26
+
27
+ task default: :test
@@ -0,0 +1,29 @@
1
+ module TerraBoi
2
+ module GeneratorHelpers
3
+ # https://api.rubyonrails.org/classes/Rails/Generators/NamedBase.html#method-i-application_name
4
+ def generate_application_name
5
+ if defined?(Rails) && Rails.application
6
+ Rails.application.class.name.split("::").first.underscore
7
+ else
8
+ "application"
9
+ end
10
+ end
11
+
12
+ def generate_terraform_files(args)
13
+ args[:env].each do |env|
14
+ template(args[:template],
15
+ "terraform/#{env}/#{args[:file_path]}",
16
+ {
17
+ env: env,
18
+ domain_name: class_options[:domain_name]
19
+ }
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ class Rails::Generators::Base
27
+ include TerraBoi::GeneratorHelpers
28
+ end
29
+
@@ -0,0 +1,35 @@
1
+ module TerraBoi
2
+ class BoilerplateGenerator < Rails::Generators::Base
3
+ attr_accessor :application_name, :class_options
4
+ class_option :ruby_version, type: :string, default: "2.5.1"
5
+ class_option :domain_name, type: :string, default: 'example.com'
6
+ source_root File.expand_path('templates', __dir__)
7
+
8
+ desc (<<-EOF
9
+ This generator runs the terra_boi web_servers, data,
10
+ and state generators. It sets up all boilerplate
11
+ terraform infrastructure needed for a standard web app:
12
+ DB + load balancer + zero downtime, scalable web app
13
+ launch config + S3 bucket.
14
+
15
+ To execute, run rails generate terra_boi:boilerplate --domain_name example.com
16
+ EOF
17
+ .gsub(/[\t]/, '')
18
+ )
19
+
20
+ def init
21
+ self.class_options = options
22
+ puts application_name
23
+ end
24
+
25
+ def run_other_generators
26
+ generate "terra_boi:web_servers --domain_name #{class_options[:domain_name]}"
27
+ generate "terra_boi:data"
28
+ generate "terra_boi:state"
29
+ generate "terra_boi:dockerfile --ruby_version #{class_options[:ruby_version]}"
30
+ generate "terra_boi:host_initializer --domain_name #{class_options[:domain_name]}"
31
+ generate "terra_boi:packer"
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,38 @@
1
+ require "generators/extensions"
2
+
3
+ module TerraBoi
4
+ class DataGenerator < Rails::Generators::Base
5
+ attr_accessor :application_name, :class_options
6
+ source_root File.expand_path('templates', __dir__)
7
+
8
+ desc (<<-EOF
9
+ Generate staging and production DB and S3 bucket
10
+
11
+ To execute, run rails generate terra_boi:data
12
+ EOF
13
+ .gsub(/\t/, '')
14
+ )
15
+
16
+ def init
17
+ # defined in lib/generators/extensions
18
+ self.application_name = generate_application_name
19
+ self.class_options = options
20
+ end
21
+
22
+ def create_main_terraform_file
23
+ generate_terraform_files({
24
+ template: 'data_main.erb',
25
+ file_path: 'data/main.tf',
26
+ env: ['staging', 'prod']
27
+ })
28
+ end
29
+
30
+ def create_output_terraform_file
31
+ generate_terraform_files({
32
+ template: 'data_output.erb',
33
+ file_path: 'data/output.tf',
34
+ env: ['staging', 'prod']
35
+ })
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,28 @@
1
+ require "generators/extensions"
2
+
3
+ module TerraBoi
4
+ class DockerfileGenerator < Rails::Generators::Base
5
+ attr_accessor :application_name, :class_options
6
+ class_option :ruby_version, type: :string, default: "2.5.1"
7
+ source_root File.expand_path('templates', __dir__)
8
+
9
+ desc (<<-EOF
10
+ Generate Dockerfile for rails app
11
+
12
+ To execute, run rails generate terra_boi:dockerfile
13
+
14
+ Can pass in --ruby_version command line argument. Defaults to 2.5.1.
15
+ EOF
16
+ .gsub(/\t/, '')
17
+ )
18
+
19
+ def init
20
+ self.application_name = generate_application_name
21
+ self.class_options = options
22
+ end
23
+
24
+ def create_dockerfile
25
+ template "Dockerfile.erb", "Dockerfile"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ require "generators/extensions"
2
+
3
+ module TerraBoi
4
+ class HostInitializerGenerator < Rails::Generators::Base
5
+ attr_accessor :application_name, :class_options
6
+ class_option :domain_name, type: :string
7
+ source_root File.expand_path('templates', __dir__)
8
+
9
+ desc (<<-EOF
10
+ Generate host initializer rails file
11
+
12
+ To execute, run rails generate terra_boi:host_initializer --domain_name example.com
13
+ EOF
14
+ .gsub(/\t/, '')
15
+ )
16
+
17
+ def init
18
+ # defined in lib/generators/extensions
19
+ self.application_name = generate_application_name
20
+ self.class_options = options
21
+ end
22
+
23
+ def create_host_initializer_file
24
+ template "host_initializer.erb", "config/initializers/hosts.rb"
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ require "generators/extensions"
2
+
3
+ module TerraBoi
4
+ class PackerGenerator < Rails::Generators::Base
5
+ attr_accessor :application_name
6
+ source_root File.expand_path('templates', __dir__)
7
+
8
+ desc (<<-EOF
9
+ Generate packer files for building AWS EC2 AMI
10
+
11
+ To execute, run rails generate terra_boi:packer
12
+ EOF
13
+ .gsub(/\t/, '')
14
+ )
15
+
16
+ def init
17
+ # defined in lib/generators/extensions
18
+ self.application_name = generate_application_name
19
+ end
20
+
21
+ def create_packer_files
22
+ template "packer_ami_build.erb", "packer/ami_build.sh"
23
+ template "packer_application.erb", "packer/application.json"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ require "generators/extensions"
2
+
3
+ module TerraBoi
4
+ class StateGenerator < Rails::Generators::Base
5
+ attr_accessor :application_name, :class_options
6
+ source_root File.expand_path('templates', __dir__)
7
+
8
+ desc (<<-EOF
9
+ Generate DB and S3 bucket for storing and locking terraform state
10
+
11
+ To execute, run rails generate terra_boi:state
12
+ EOF
13
+ .gsub(/\t/, '')
14
+ )
15
+
16
+ def init
17
+ self.application_name = generate_application_name
18
+ self.class_options = options
19
+ end
20
+
21
+ def create_main_terraform_file
22
+ template "state_main.erb", "terraform/state/main.tf"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,39 @@
1
+ FROM ruby:<%= class_options[:ruby_version] %>
2
+
3
+ # replace shell with bash so we can source files
4
+ RUN rm /bin/sh && ln -s /bin/bash /bin/sh
5
+
6
+ RUN apt-get update -qq && apt-get install -y build-essential
7
+
8
+ # # for postgres
9
+ # RUN apt-get install -y libpq-dev
10
+
11
+ # # for nokogiri
12
+ # RUN apt-get install -y libxml2-dev libxslt1-dev
13
+
14
+ # # for capybara-webkit
15
+ # RUN apt-get install -y libqtwebkit4 libqt4-dev xvfb
16
+
17
+ # for a JS runtime
18
+ RUN curl -sL https://deb.nodesource.com/setup_11.x | bash -
19
+ RUN apt-get install -y nodejs
20
+
21
+ RUN node -v
22
+ RUN npm -v
23
+
24
+ RUN npm install yarn -g
25
+
26
+ ENV APP_HOME /<%= application_name %>
27
+ RUN mkdir $APP_HOME
28
+ WORKDIR $APP_HOME
29
+
30
+ ADD Gemfile* $APP_HOME/
31
+ RUN bundle install
32
+
33
+ ADD . $APP_HOME
34
+
35
+ RUN yarn install --check-files
36
+
37
+ EXPOSE 3000
38
+
39
+ ENTRYPOINT bin/rails server --port 3000 -b 0.0.0.0
@@ -0,0 +1,31 @@
1
+ # ---------------------------------------------------------------------------------------------------------------------
2
+ # 1. STATE
3
+ # ---------------------------------------------------------------------------------------------------------------------
4
+
5
+ terraform {
6
+ backend "s3" {
7
+ bucket = "<%= application_name %>-terraform-state-storage"
8
+ key = "terraform/<%= config[:env] %>-state/data"
9
+ region = "us-east-2"
10
+ dynamodb_table = "<%= application_name %>-terraform-state-lock"
11
+ encrypt = true
12
+ }
13
+ }
14
+
15
+ # ---------------------------------------------------------------------------------------------------------------------
16
+ # 2. DB + S3 MODULE
17
+ # ---------------------------------------------------------------------------------------------------------------------
18
+
19
+ variable "db_username" {}
20
+ variable "db_password" {}
21
+
22
+ module "db_and_s3" {
23
+ source = "github.com/charliereese/terraform_modules//data?ref=v0.0.6"
24
+
25
+ env = "<%= config[:env] %>"
26
+ app_name = "<%= application_name %>"
27
+ db_instance_class = "<%= config[:env] == 'prod' ? 'db.t3.micro' : 'db.t2.micro' %>"
28
+ db_encrypted = <%= config[:env] == 'prod' ? true : false %>
29
+ db_username = var.db_username
30
+ db_password = var.db_password
31
+ }
@@ -0,0 +1,19 @@
1
+ output "address" {
2
+ value = module.db_and_s3.address
3
+ description = "Connect to the database at this endpoint"
4
+ }
5
+
6
+ output "port" {
7
+ value = module.db_and_s3.port
8
+ description = "The port the database is listening on"
9
+ }
10
+
11
+ output "endpoint" {
12
+ value = module.db_and_s3.endpoint
13
+ description = "The endpoint of the databse"
14
+ }
15
+
16
+ output "db_name" {
17
+ value = module.db_and_s3.db_name
18
+ description = "The name of the database"
19
+ }
@@ -0,0 +1,4 @@
1
+ Rails.application.configure do
2
+ config.hosts << '.<%= class_options[:domain_name] %>'
3
+ config.hosts << /compute\.amazonaws\.com/
4
+ end
@@ -0,0 +1,22 @@
1
+ #!/bin/bash
2
+
3
+ # Update to the latest current version of packages
4
+ sudo apt-get update
5
+ sudo apt -y install docker.io
6
+ docker --version
7
+
8
+ # # Start the Docker service
9
+ sudo service docker start
10
+ sudo usermod -aG docker ubuntu
11
+
12
+ # # Automatically start Docker service when the system boots, i.e. when the EC2 instance created from this AMI is launched or rebooted
13
+ sudo systemctl enable docker
14
+
15
+ # Log in
16
+ sudo docker login --username $DOCKERHUB_USERNAME -p $DOCKERHUB_ACCESS_TOKEN
17
+
18
+ # Run the container:
19
+ # --restart=always i.e. always start the container when the EC2 instance created from this AMI is launched or rebooted
20
+ # --detach , -d i.e. Run container in background and print container ID
21
+ # sudo docker run --restart=always USERNAME/<%= application_name %>:latest
22
+ sudo docker container run -p 3000:3000 --name <%= application_name %> --restart always -d $DOCKERHUB_USERNAME/<%= application_name %>:latest
@@ -0,0 +1,41 @@
1
+ {
2
+ "variables": {
3
+ "DOCKERHUB_ACCESS_TOKEN": "",
4
+ "DOCKERHUB_USERNAME": ""
5
+ },
6
+
7
+ "builders": [{
8
+ "type": "amazon-ebs",
9
+ "region": "us-east-2",
10
+ "source_ami_filter": {
11
+ "filters": {
12
+ "virtualization-type": "hvm",
13
+ "name": "ubuntu/images/*ubuntu-disco-19.04-amd64-server-*",
14
+ "root-device-type": "ebs"
15
+ },
16
+ "owners": ["099720109477"],
17
+ "most_recent": true
18
+ },
19
+ "instance_type": "t2.micro",
20
+ "ssh_username": "ubuntu",
21
+ "ami_name": "<%= application_name %>-ec2 {{timestamp}}",
22
+ "tags": {
23
+ "application": "<%= application_name %>-web-server"
24
+ }
25
+ }],
26
+
27
+ "provisioners": [{
28
+ "type": "shell",
29
+ "inline": [
30
+ "sleep 30"
31
+ ]
32
+ },
33
+ {
34
+ "type":"shell",
35
+ "environment_vars": [
36
+ "DOCKERHUB_ACCESS_TOKEN={{user `DOCKERHUB_ACCESS_TOKEN`}}",
37
+ "DOCKERHUB_USERNAME={{user `DOCKERHUB_USERNAME`}}"
38
+ ],
39
+ "script": "ami_build.sh"
40
+ }]
41
+ }
@@ -0,0 +1,10 @@
1
+ # ---------------------------------------------------------------------------------------------------------------------
2
+ # 1. STATE MODULE
3
+ # ---------------------------------------------------------------------------------------------------------------------
4
+
5
+ module "remote_state_locking" {
6
+ source = "github.com/charliereese/terraform_modules//state?ref=v0.0.6"
7
+
8
+ app_name = "<%= application_name %>"
9
+ region = "us-east-2"
10
+ }
@@ -0,0 +1,30 @@
1
+ # ---------------------------------------------------------------------------------------------------------------------
2
+ # 1. STATE
3
+ # ---------------------------------------------------------------------------------------------------------------------
4
+
5
+ terraform {
6
+ backend "s3" {
7
+ bucket = "<%= application_name %>-terraform-state-storage"
8
+ key = "terraform/<%= config[:env] %>-state/web-servers"
9
+ region = "us-east-2"
10
+ dynamodb_table = "<%= application_name %>-terraform-state-lock"
11
+ encrypt = true
12
+ }
13
+ }
14
+
15
+ # ---------------------------------------------------------------------------------------------------------------------
16
+ # 2. WEB SERVERS MODULE
17
+ # ---------------------------------------------------------------------------------------------------------------------
18
+
19
+ module "webserver_cluster" {
20
+ source = "github.com/charliereese/terraform_modules//web_servers?ref=v0.0.6"
21
+
22
+ instance_type = "t2.micro"
23
+ env = "<%= config[:env] %>"
24
+ app_name = "<%= application_name %>"
25
+ domain_name = "<%= config[:domain_name] %>"
26
+ min_size = 1
27
+ max_size = 1
28
+ business_hours_size = 1
29
+ night_hours_size = 1
30
+ }
@@ -0,0 +1,14 @@
1
+ output "alb_dns_name" {
2
+ value = module.webserver_cluster.alb_dns_name
3
+ description = "The domain name of the application load balancer"
4
+ }
5
+
6
+ output "asg_name" {
7
+ value = module.webserver_cluster.asg_name
8
+ description = "autoscaling group name"
9
+ }
10
+
11
+ output "alb_security_group_id" {
12
+ value = module.webserver_cluster.alb_security_group_id
13
+ description = "ID of Security Group attached to ALB"
14
+ }
@@ -0,0 +1,39 @@
1
+ require "generators/extensions"
2
+
3
+ module TerraBoi
4
+ class WebServersGenerator < Rails::Generators::Base
5
+ attr_accessor :application_name, :class_options
6
+ class_option :domain_name, type: :string
7
+ source_root File.expand_path('templates', __dir__)
8
+
9
+ desc (<<-EOF
10
+ Generate staging and production terraform web server files
11
+
12
+ To execute, run rails generate terra_boi:web_servers --domain_name example.com
13
+ EOF
14
+ .gsub(/\t/, '')
15
+ )
16
+
17
+ def init
18
+ # defined in lib/generators/extensions
19
+ self.application_name = generate_application_name
20
+ self.class_options = options
21
+ end
22
+
23
+ def create_main_terraform_file
24
+ generate_terraform_files({
25
+ template: 'web_servers_main.erb',
26
+ file_path: 'web_servers/main.tf',
27
+ env: ['staging', 'prod']
28
+ })
29
+ end
30
+
31
+ def create_output_terraform_file
32
+ generate_terraform_files({
33
+ template: 'web_servers_output.erb',
34
+ file_path: 'web_servers/output.tf',
35
+ env: ['staging', 'prod']
36
+ })
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :terra_boi do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,4 @@
1
+ module TerraBoi
2
+ class Railtie < ::Rails::Railtie
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module TerraBoi
2
+ VERSION = '0.0.1'
3
+ end
data/lib/terra_boi.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "terra_boi/railtie"
2
+
3
+ module TerraBoi
4
+ # Your code goes here...
5
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: terra_boi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Charlie Reese
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-09-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 6.0.0
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '6.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 6.0.0
33
+ description: 'This gem was created to get rails applications deployed into production
34
+ as quickly and easily as possible. It contains generators that create infrastructure
35
+ code for load balancing / auto scaling / zero-downtime deployments, (rails) web
36
+ apps (EC2 instances), DBs, and S3 buckets. List of items created by this gem''s
37
+ generators: Dockerfile, Rails initializer file (for setting up config.hosts), Packer
38
+ repository (for creating AWS EC2 AMIs), and Terraform repository (for creating infrastructure
39
+ as code to immediately deploy staging / prod infrastructure).'
40
+ email:
41
+ - j.charles.reese@gmail.com
42
+ executables: []
43
+ extensions: []
44
+ extra_rdoc_files: []
45
+ files:
46
+ - MIT-LICENSE
47
+ - README.md
48
+ - Rakefile
49
+ - lib/generators/extensions.rb
50
+ - lib/generators/terra_boi/boilerplate_generator.rb
51
+ - lib/generators/terra_boi/data_generator.rb
52
+ - lib/generators/terra_boi/dockerfile_generator.rb
53
+ - lib/generators/terra_boi/host_initializer_generator.rb
54
+ - lib/generators/terra_boi/packer_generator.rb
55
+ - lib/generators/terra_boi/state_generator.rb
56
+ - lib/generators/terra_boi/templates/Dockerfile.erb
57
+ - lib/generators/terra_boi/templates/data_main.erb
58
+ - lib/generators/terra_boi/templates/data_output.erb
59
+ - lib/generators/terra_boi/templates/host_initializer.erb
60
+ - lib/generators/terra_boi/templates/packer_ami_build.erb
61
+ - lib/generators/terra_boi/templates/packer_application.erb
62
+ - lib/generators/terra_boi/templates/state_main.erb
63
+ - lib/generators/terra_boi/templates/web_servers_main.erb
64
+ - lib/generators/terra_boi/templates/web_servers_output.erb
65
+ - lib/generators/terra_boi/web_servers_generator.rb
66
+ - lib/tasks/terra_boi_tasks.rake
67
+ - lib/terra_boi.rb
68
+ - lib/terra_boi/railtie.rb
69
+ - lib/terra_boi/version.rb
70
+ homepage: https://github.com/charliereese/terra_boi
71
+ licenses:
72
+ - MIT
73
+ metadata: {}
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 2.7.7
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: Generators to help you get rails applications deployed into production as
94
+ quickly and easily as possible.
95
+ test_files: []