terra_boi 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []