stalkedbybean 0.1.0
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 +7 -0
- data/.gitignore +13 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +80 -0
- data/LICENSE.txt +30 -0
- data/README.md +116 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/config/.stalkedbybean.yml +1 -0
- data/config/config_test.yml +25 -0
- data/docs/setting_up_config_file.md +55 -0
- data/docs/setting_up_credstash.md +19 -0
- data/exe/stalkedbybean +4 -0
- data/lib/stalkedbybean.rb +15 -0
- data/lib/stalkedbybean/app_info.rb +18 -0
- data/lib/stalkedbybean/cli.rb +169 -0
- data/lib/stalkedbybean/deploy.rb +22 -0
- data/lib/stalkedbybean/env_vars.rb +79 -0
- data/lib/stalkedbybean/generators/init.rb +26 -0
- data/lib/stalkedbybean/generators/init/.stalkedbybean.yml +3 -0
- data/lib/stalkedbybean/generators/init/config.yml +25 -0
- data/lib/stalkedbybean/initialize.rb +16 -0
- data/lib/stalkedbybean/parser.rb +29 -0
- data/lib/stalkedbybean/provision.rb +38 -0
- data/lib/stalkedbybean/role_setup.rb +137 -0
- data/lib/stalkedbybean/secrets_setup.rb +49 -0
- data/lib/stalkedbybean/terminate.rb +17 -0
- data/lib/stalkedbybean/version.rb +3 -0
- data/stalkedbybean.gemspec +33 -0
- metadata +189 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '0497c17d1af5b7b34aaf61dcedda053b378b73624cfcd7a3a94d163138ef28e2'
|
4
|
+
data.tar.gz: 1f114e09cdf4530f21ff8674156aaa04ddbde02ccdd89e75b550aad7189e1072
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 74788823e3be103aa95b114a574a47fe1e2de119ccc6665ccdef46a07c33c6ed9782651fff3675170969c072935b9c6b8fce7190fc13d1bb38769166b2201763
|
7
|
+
data.tar.gz: 940c1476844838d5b62d53f7ea7a0ce22999775109d3989343987553c8f6e344e93edd7eb789c907bf0629362c604e74231106d55588c701630d0d7114f3aa69
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
stalkedbybean (0.1.0)
|
5
|
+
aws-sdk-elasticbeanstalk
|
6
|
+
aws-sdk-iam
|
7
|
+
aws-sdk-kms
|
8
|
+
thor
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
aruba (0.14.5)
|
14
|
+
childprocess (>= 0.6.3, < 0.10.0)
|
15
|
+
contracts (~> 0.9)
|
16
|
+
cucumber (>= 1.3.19)
|
17
|
+
ffi (~> 1.9.10)
|
18
|
+
rspec-expectations (>= 2.99)
|
19
|
+
thor (~> 0.19)
|
20
|
+
aws-partitions (1.70.0)
|
21
|
+
aws-sdk-core (3.17.0)
|
22
|
+
aws-partitions (~> 1.0)
|
23
|
+
aws-sigv4 (~> 1.0)
|
24
|
+
jmespath (~> 1.0)
|
25
|
+
aws-sdk-elasticbeanstalk (1.4.0)
|
26
|
+
aws-sdk-core (~> 3)
|
27
|
+
aws-sigv4 (~> 1.0)
|
28
|
+
aws-sdk-iam (1.3.0)
|
29
|
+
aws-sdk-core (~> 3)
|
30
|
+
aws-sigv4 (~> 1.0)
|
31
|
+
aws-sdk-kms (1.5.0)
|
32
|
+
aws-sdk-core (~> 3)
|
33
|
+
aws-sigv4 (~> 1.0)
|
34
|
+
aws-sigv4 (1.0.2)
|
35
|
+
backports (3.11.1)
|
36
|
+
builder (3.2.3)
|
37
|
+
childprocess (0.9.0)
|
38
|
+
ffi (~> 1.0, >= 1.0.11)
|
39
|
+
contracts (0.16.0)
|
40
|
+
cucumber (3.1.0)
|
41
|
+
builder (>= 2.1.2)
|
42
|
+
cucumber-core (~> 3.1.0)
|
43
|
+
cucumber-expressions (~> 5.0.4)
|
44
|
+
cucumber-wire (~> 0.0.1)
|
45
|
+
diff-lcs (~> 1.3)
|
46
|
+
gherkin (~> 5.0)
|
47
|
+
multi_json (>= 1.7.5, < 2.0)
|
48
|
+
multi_test (>= 0.1.2)
|
49
|
+
cucumber-core (3.1.0)
|
50
|
+
backports (>= 3.8.0)
|
51
|
+
cucumber-tag_expressions (~> 1.1.0)
|
52
|
+
gherkin (>= 5.0.0)
|
53
|
+
cucumber-expressions (5.0.13)
|
54
|
+
cucumber-tag_expressions (1.1.1)
|
55
|
+
cucumber-wire (0.0.1)
|
56
|
+
diff-lcs (1.3)
|
57
|
+
ffi (1.9.23)
|
58
|
+
gherkin (5.0.0)
|
59
|
+
jmespath (1.3.1)
|
60
|
+
multi_json (1.13.1)
|
61
|
+
multi_test (0.1.2)
|
62
|
+
rake (10.5.0)
|
63
|
+
rspec-expectations (3.7.0)
|
64
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
65
|
+
rspec-support (~> 3.7.0)
|
66
|
+
rspec-support (3.7.1)
|
67
|
+
thor (0.20.0)
|
68
|
+
|
69
|
+
PLATFORMS
|
70
|
+
ruby
|
71
|
+
|
72
|
+
DEPENDENCIES
|
73
|
+
aruba
|
74
|
+
bundler (~> 1.16)
|
75
|
+
cucumber
|
76
|
+
rake (~> 10.0)
|
77
|
+
stalkedbybean!
|
78
|
+
|
79
|
+
BUNDLED WITH
|
80
|
+
1.16.0
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
BSD 3-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2018, Ascential plc
|
4
|
+
|
5
|
+
All rights reserved.
|
6
|
+
|
7
|
+
Redistribution and use in source and binary forms, with or without
|
8
|
+
modification, are permitted provided that the following conditions are met:
|
9
|
+
|
10
|
+
* Redistributions of source code must retain the above copyright notice, this
|
11
|
+
list of conditions and the following disclaimer.
|
12
|
+
|
13
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
14
|
+
this list of conditions and the following disclaimer in the documentation
|
15
|
+
and/or other materials provided with the distribution.
|
16
|
+
|
17
|
+
* Neither the name of the copyright holder nor the names of its
|
18
|
+
contributors may be used to endorse or promote products derived from
|
19
|
+
this software without specific prior written permission.
|
20
|
+
|
21
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
22
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
23
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
24
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
25
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
26
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
27
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
28
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
29
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# Stalkedbybean
|
2
|
+
|
3
|
+
Little Ruby command line utility to help Ascential Makers to deploy on AWS beanstalk. Configurable through command line and config file.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'stalkedbybean'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
$ bundle install
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
```
|
22
|
+
$ gem install stalkedbybean
|
23
|
+
```
|
24
|
+
|
25
|
+
## How to use
|
26
|
+
|
27
|
+
You can perform all the steps for deploying your app (initializing it, handling secrets, creating the environment, deploying the version and terminating environment finally) by running a simple Ruby script.
|
28
|
+
|
29
|
+
1. This gem relies on some dependencies ([AWS CLI](https://aws.amazon.com/cli/), [AWS EB CLI](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3.html) and [Credstash](https://github.com/fugue/credstash)) you will have to install.
|
30
|
+
```
|
31
|
+
$ pip3 install awscli --upgrade --user
|
32
|
+
$ pip3 install awsebcli --upgrade --user
|
33
|
+
$ sudo pip3 install boto botocore boto3
|
34
|
+
$ sudo pip3 install credstash
|
35
|
+
```
|
36
|
+
|
37
|
+
2. Make sure you have your AWS credentials set up. If not, you can do so by [following the instructions here.](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html)
|
38
|
+
|
39
|
+
3. Initialise a default config file in your project's root directory. Replace `your-environment-name` which whatever applies to you (eg; test, staging, production etc). This should generate a [config file](./config/config_test.yml) and [config settings file](./config/.stalkedbybean.yml) in the directory you are in.
|
40
|
+
```
|
41
|
+
$ stalkedbybean init your-environment-name
|
42
|
+
```
|
43
|
+
|
44
|
+
4. Update the generated [config file](./config/config_test.yml) with the config options relevant to _your_ app especially the mandatory ones for setting up secrets. You won't be able to get your `kms_arn` until you set up your secrets below so leave that for now.
|
45
|
+
|
46
|
+
Detailed information on how to update your config options [can be found here](./docs/setting_up_config_file.md).
|
47
|
+
|
48
|
+
5. The generated file will automatically be set as your default config file. You can override this by passing it with the flag ```-f FILENAME``` when running the gem commands or changing the default file in `config/.stalkedbybean.yml`.
|
49
|
+
|
50
|
+
## Commands Details
|
51
|
+
|
52
|
+
```bash
|
53
|
+
stalkedbybean init # Generates a config file
|
54
|
+
stalkedbybean create [OPTIONS] # Creates a new AWS application
|
55
|
+
stalkedbybean secrets <command> [OPTIONS] # Sets up and manages secrets using Credstash
|
56
|
+
stalkedbybean setup_roles [OPTIONS] # Sets up roles in AWS IAM
|
57
|
+
stalkedbybean provision -v VERSION [OPTIONS] # Provisions new environment in AWS EB
|
58
|
+
stalkedbybean deploy -v VERSION [OPTIONS] # Deploys new version of environment
|
59
|
+
stalkedbybean terminate [OPTIONS] # Terminates environment, application and all resources
|
60
|
+
stalkedbybean update_config [OPTIONS] # Updates all config options
|
61
|
+
stalkedbybean print_env_vars [OPTIONS] # Prints existing environment variables
|
62
|
+
stalkedbybean update_env_vars [OPTIONS] # Updates environment variables
|
63
|
+
stalkedbybean versions [OPTIONS] # Displays application versions
|
64
|
+
stalkedbybean help [COMMAND] # Describe available commands or one specific command
|
65
|
+
```
|
66
|
+
|
67
|
+
## Handling Secrets
|
68
|
+
|
69
|
+
The Beanstalk platform expects secrets to be put using [CredStash](https://github.com/fugue/credstash), in the same region that you are deploying, using a table called `your_app_name-your_environment_name`, encrypted through a KMS key.
|
70
|
+
|
71
|
+
This can be done using `stalkedbybeans`.
|
72
|
+
|
73
|
+
1. Make sure you have the `config.yml` file with the mandatory options for setting up secrets filled up correctly.
|
74
|
+
|
75
|
+
2. Create a KMS key and setup a table to hold your secrets. This step will also print out your KMS ARN which you should copy and paste into your [config.yml file](./config/config_test.yml) as it will be required for deployment.
|
76
|
+
```bash
|
77
|
+
$ stalkedbybeans secrets setup
|
78
|
+
```
|
79
|
+
|
80
|
+
3. To add a secret in a key/value pair:
|
81
|
+
```bash
|
82
|
+
$ stalkedbybeans secrets add [key] [value]
|
83
|
+
```
|
84
|
+
|
85
|
+
4. To get a secret:
|
86
|
+
```bash
|
87
|
+
$ stalkedbybeans secrets get [key]
|
88
|
+
```
|
89
|
+
|
90
|
+
5. You can also change the value of an existing secret by creating a new version of it. Credstash will automatically use the latest version of the secret.
|
91
|
+
```bash
|
92
|
+
$ stalkedbybeans secrets change [key] [new_value] [version]
|
93
|
+
```
|
94
|
+
|
95
|
+
6. To get all the secrets stored within your application:
|
96
|
+
```bash
|
97
|
+
$ stalkedbybeans secrets getall
|
98
|
+
```
|
99
|
+
|
100
|
+
If you do not want to use the script, you can also use Credstash [manually as described here](./docs/setting_up_credstash.md).
|
101
|
+
|
102
|
+
Keys are versioned. See [CredStash documentation](https://github.com/fugue/credstash) for more details.
|
103
|
+
|
104
|
+
## Development
|
105
|
+
|
106
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
107
|
+
|
108
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
109
|
+
|
110
|
+
## Contributing
|
111
|
+
|
112
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ascential/stalkedbybean.
|
113
|
+
|
114
|
+
## License
|
115
|
+
|
116
|
+
The gem is available as open source under the terms of the [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "stalkedbybean"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
default: "config/config_test.yml"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# MANDATORY OPTIONS TO BE FILLED UP BEFORE SETTING UP SECRETS
|
2
|
+
app_name:
|
3
|
+
aws_profile:
|
4
|
+
aws_region:
|
5
|
+
environment: test
|
6
|
+
|
7
|
+
# MANDATORY OPTIONS TO BE FILLED UP BEFORE SETTING UP ROLES
|
8
|
+
aws_account_id:
|
9
|
+
kms_arn:
|
10
|
+
|
11
|
+
# OPTIONAL (BUT HIGHLY RECOMMENDED) OPTIONS
|
12
|
+
vpc_id:
|
13
|
+
vpc_security_groups:
|
14
|
+
-
|
15
|
+
instance_count:
|
16
|
+
instance_size:
|
17
|
+
platform_arn:
|
18
|
+
env_vars: "KEY=value"
|
19
|
+
vpc_ec2_subnets:
|
20
|
+
-
|
21
|
+
-
|
22
|
+
vpc_elb_subnets:
|
23
|
+
-
|
24
|
+
-
|
25
|
+
key_name:
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# What Goes in Your Config File
|
2
|
+
|
3
|
+
A short guide as to what needs to go in your config file for deployment as well as where you might find them.
|
4
|
+
|
5
|
+
## Mandatory Options
|
6
|
+
* **aws_profile**
|
7
|
+
|
8
|
+
* **aws_region**
|
9
|
+
|
10
|
+
The region where your resource is going to reside in. This is up to you but **please** ensure that it is consistent throughout your app. You can find more details as well the list of possible regions [at this link](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html).
|
11
|
+
|
12
|
+
* **kms_arn**
|
13
|
+
|
14
|
+
You should have created a key [as detailed here](./README.md#handling-secrets) to handle any secrets within Credstash. To get the ARN of your key, go to the IAM service page --> Encryption Keys and find the key that you have created. Copy the entire ARN of your key for this field.
|
15
|
+
|
16
|
+
## Not-so-mandatory Options
|
17
|
+
|
18
|
+
* **vpc_id**
|
19
|
+
|
20
|
+
VPC (Virtual Private Cloud) is an isolated virtual network in the AWS cloud. You can find your **VPC ID** by going to the VPC service page and searching the table in **Your VPCs**.
|
21
|
+
|
22
|
+
* **vpc_security_groups**
|
23
|
+
|
24
|
+
Find your relevant security group by going to the VPC service page and searching the table in **Security Groups** for the groups relevant to your app. You might have more than one security group. You will need to copy their group IDs.
|
25
|
+
|
26
|
+
If your application has a database, you will also need to include your [RDS security group](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.RDSSecurityGroups.html) by looking up your DB instance on AWS RDS.
|
27
|
+
|
28
|
+
* **instance_count**
|
29
|
+
|
30
|
+
* **instance_size**
|
31
|
+
|
32
|
+
You can specify the instance type and instance size which best fits your app. More details on the different types/sizes which exist [can be found here](https://aws.amazon.com/ec2/instance-types/).
|
33
|
+
|
34
|
+
* **platform_arn**
|
35
|
+
|
36
|
+
The ARN of the custom platform you are using. We offer two versions of custom platforms so far for the regions eu-west-1 and eu-west-2.
|
37
|
+
|
38
|
+
eu-west-1: arn:aws:elasticbeanstalk:eu-west-1:160153085320:platform/AscentialPlatform_Ubuntu/1.0.42
|
39
|
+
eu-west-2: arn:aws:elasticbeanstalk:eu-west-2:160153085320:platform/AscentialPlatform_Ubuntu/1.0.2
|
40
|
+
|
41
|
+
If this does not fit your requirements, you can [create your own custom beanstalk platform](./Beanstalk_custom_platform.md).
|
42
|
+
|
43
|
+
* **environment**
|
44
|
+
|
45
|
+
Specify the name of the environment you are deploying (e.g. test, deployment, production etc). You can create and manage separate environments for your application.
|
46
|
+
|
47
|
+
* **vpc_ec2_subnets**
|
48
|
+
|
49
|
+
Your private subnet IDs belong here. Find your relevant private subnet IDs by going to the VPC service page and searching under **Subnets**. You might have more than one security group. An easy way to narrow things down would be to search the subnets by your VPC id.
|
50
|
+
|
51
|
+
* **vpc_elb_subnets**
|
52
|
+
|
53
|
+
Your public subnet IDs belong here. Find your relevant private subnet IDs by going to the VPC service page and searching under **Subnets**. You might have more than one security group. An easy way to narrow things down would be to search the subnets by your VPC id.
|
54
|
+
|
55
|
+
* **key_name**
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Setting up CredStash
|
2
|
+
|
3
|
+
You need to go to [the aws console of IAM, section encryption key](https://console.aws.amazon.com/iam/home#/encryptionKeys/eu-west-1) and create a key here. The alias you use will be used everytime you put a value to your secrets.
|
4
|
+
We advise to use `app_name` as the alias of the key
|
5
|
+
|
6
|
+
You can create the table by using
|
7
|
+
```bash
|
8
|
+
$ credstash -r your_region -p your_profile -t app_name-environment_name setup
|
9
|
+
```
|
10
|
+
|
11
|
+
You can now add secrets under a key by calling
|
12
|
+
```bash
|
13
|
+
$ credstash -r your_region -p your_profile -t app_name-environment_name put -k alias/key_alias key value
|
14
|
+
```
|
15
|
+
|
16
|
+
and consulting a key by doing
|
17
|
+
```bash
|
18
|
+
$ credstash -r your_region -p your_profile -t app_name-environment_name get key
|
19
|
+
```
|
data/exe/stalkedbybean
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "stalkedbybean/version"
|
2
|
+
require "stalkedbybean/initialize"
|
3
|
+
require "stalkedbybean/secrets_setup"
|
4
|
+
require "stalkedbybean/role_setup"
|
5
|
+
require "stalkedbybean/provision"
|
6
|
+
require "stalkedbybean/deploy"
|
7
|
+
require "stalkedbybean/terminate"
|
8
|
+
require "stalkedbybean/env_vars"
|
9
|
+
require "stalkedbybean/app_info"
|
10
|
+
require "stalkedbybean/parser"
|
11
|
+
|
12
|
+
|
13
|
+
module Stalkedbybean
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'Shellwords'
|
2
|
+
|
3
|
+
module Stalkedbybean
|
4
|
+
class AppInfo
|
5
|
+
|
6
|
+
def self.parse_options(file_path, options)
|
7
|
+
@options = Stalkedbybean::Parser.parse_options(file_path, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def self.list_application_versions
|
12
|
+
system(
|
13
|
+
"eb appversion --profile #{@options[:aws_profile]} -r #{@options[:aws_region]}"
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'stalkedbybean'
|
3
|
+
require 'stalkedbybean/generators/init'
|
4
|
+
|
5
|
+
module Stalkedbybean
|
6
|
+
class CLI < Thor
|
7
|
+
|
8
|
+
desc "create [OPTIONS]", "Creates a new AWS application"
|
9
|
+
method_option :file_path, :type => :string, :aliases => "-f"
|
10
|
+
method_option :app_name, :type => :string, :aliases => "-n"
|
11
|
+
method_option :aws_profile, :type => :string, :aliases => "-p"
|
12
|
+
method_option :aws_region, :type => :string, :aliases => "-r"
|
13
|
+
method_option :platform_arn, :type => :string, :aliases => "-a"
|
14
|
+
def create
|
15
|
+
Stalkedbybean::Initialize.parse_options(options[:file_path], options)
|
16
|
+
Stalkedbybean::Initialize.initialize_app
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "secrets <command> [OPTIONS]", "Sets up and manages secrets using Credstash"
|
20
|
+
method_option :file_path, :type => :string, :aliases => "-f"
|
21
|
+
method_option :app_name, :type => :string, :aliases => "-n"
|
22
|
+
method_option :aws_profile, :type => :string, :aliases => "-p"
|
23
|
+
method_option :aws_region, :type => :string, :aliases => "-r"
|
24
|
+
method_option :environment, :type => :string, :aliases => "-e"
|
25
|
+
def secrets(action, *args)
|
26
|
+
if action == "setup"
|
27
|
+
Stalkedbybean::SecretsSetup.parse_options(options[:file_path], options)
|
28
|
+
Stalkedbybean::SecretsSetup.create_key
|
29
|
+
Stalkedbybean::SecretsSetup.create_credstash_table
|
30
|
+
elsif action == "add"
|
31
|
+
Stalkedbybean::SecretsSetup.parse_options(options[:file_path], options)
|
32
|
+
Stalkedbybean::SecretsSetup.add_secret(args[0], args[1])
|
33
|
+
elsif action == "get"
|
34
|
+
Stalkedbybean::SecretsSetup.parse_options(options[:file_path], options)
|
35
|
+
Stalkedbybean::SecretsSetup.get_secret(args[0])
|
36
|
+
elsif action == "change"
|
37
|
+
Stalkedbybean::SecretsSetup.parse_options(options[:file_path], options)
|
38
|
+
Stalkedbybean::SecretsSetup.change_secret(args[0], args[1], args[2])
|
39
|
+
elsif action == "getall"
|
40
|
+
Stalkedbybean::SecretsSetup.parse_options(options[:file_path], options)
|
41
|
+
Stalkedbybean::SecretsSetup.getall_secrets
|
42
|
+
else
|
43
|
+
puts (
|
44
|
+
<<~HEREDOC
|
45
|
+
USAGE: stalkedbybean secrets <command> [OPTIONS]
|
46
|
+
COMMANDS:
|
47
|
+
- setup
|
48
|
+
- add KEY VALUE
|
49
|
+
- get KEY
|
50
|
+
- change KEY NEW_VALUE VERSION
|
51
|
+
- getall
|
52
|
+
HEREDOC
|
53
|
+
)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "setup_roles [OPTIONS]", "Sets up roles in AWS IAM"
|
58
|
+
method_option :file_path, :type => :string, :aliases => "-f"
|
59
|
+
method_option :app_name, :type => :string, :aliases => "-n"
|
60
|
+
method_option :aws_profile, :type => :string, :aliases => "-p"
|
61
|
+
method_option :aws_region, :type => :string, :aliases => "-r"
|
62
|
+
method_option :environment, :type => :string, :aliases => "-e"
|
63
|
+
method_option :aws_account_id, :type => :string
|
64
|
+
method_option :kms_arn, :type => :string
|
65
|
+
def setup_roles
|
66
|
+
Stalkedbybean::RoleSetup.parse_options(options[:file_path], options)
|
67
|
+
Stalkedbybean::RoleSetup.setup_IAM
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "provision -v VERSION [OPTIONS]", "Provisions new environment in AWS EB"
|
71
|
+
method_option :file_path, :type => :string, :aliases => "-f"
|
72
|
+
method_option :app_name, :type => :string, :aliases => "-n"
|
73
|
+
method_option :aws_profile, :type => :string, :aliases => "-p"
|
74
|
+
method_option :aws_region, :type => :string, :aliases => "-r"
|
75
|
+
method_option :environment, :type => :string, :aliases => "-e"
|
76
|
+
method_option :platform_arn, :type => :string, :aliases => "-a"
|
77
|
+
method_option :instance_size, :type => :string, :aliases => "-i"
|
78
|
+
method_option :instance_count, :type => :string, :aliases => "-s"
|
79
|
+
method_option :vpc_id, :type => :string
|
80
|
+
method_option :vpc_ec2_subnets, :type => :array
|
81
|
+
method_option :vpc_elb_subnets, :type => :array
|
82
|
+
method_option :vpc_security_groups, :type => :array
|
83
|
+
method_option :version, :type => :string, :aliases => "-v"
|
84
|
+
method_option :key_name, :type => :string
|
85
|
+
method_option :env_vars, :type => :string
|
86
|
+
def provision
|
87
|
+
Stalkedbybean::Provision.parse_options(options[:file_path], options)
|
88
|
+
Stalkedbybean::Provision.create_environment
|
89
|
+
end
|
90
|
+
|
91
|
+
desc "deploy -v VERSION [OPTIONS]", "Deploys new version of environment"
|
92
|
+
method_option :file_path, :type => :string, :aliases => "-f"
|
93
|
+
method_option :app_name, :type => :string, :aliases => "-n"
|
94
|
+
method_option :aws_profile, :type => :string, :aliases => "-p"
|
95
|
+
method_option :aws_region, :type => :string, :aliases => "-r"
|
96
|
+
method_option :environment, :type => :string, :aliases => "-e"
|
97
|
+
method_option :version, :type => :string, :aliases => "-v"
|
98
|
+
def deploy
|
99
|
+
Stalkedbybean::Deploy.parse_options(options[:file_path], options)
|
100
|
+
Stalkedbybean::Deploy.deploy_version
|
101
|
+
end
|
102
|
+
|
103
|
+
desc "terminate [OPTIONS]", "Terminates environment, application and all resources"
|
104
|
+
method_option :file_path, :type => :string, :aliases => "-f"
|
105
|
+
method_option :aws_profile, :type => :string, :aliases => "-p"
|
106
|
+
method_option :aws_region, :type => :string, :aliases => "-r"
|
107
|
+
method_option :environment, :type => :string, :aliases => "-e"
|
108
|
+
def terminate
|
109
|
+
Stalkedbybean::Terminate.parse_options(options[:file_path], options)
|
110
|
+
Stalkedbybean::Terminate.terminate_environment
|
111
|
+
end
|
112
|
+
|
113
|
+
desc "update_config [OPTIONS]", "Updates all config options"
|
114
|
+
method_option :file_path, :type => :string, :aliases => "-f"
|
115
|
+
method_option :app_name, :type => :string, :aliases => "-n"
|
116
|
+
method_option :aws_profile, :type => :string, :aliases => "-p"
|
117
|
+
method_option :aws_region, :type => :string, :aliases => "-r"
|
118
|
+
method_option :environment, :type => :string, :aliases => "-e"
|
119
|
+
method_option :instance_size, :type => :string, :aliases => "-i"
|
120
|
+
method_option :instance_count, :type => :string, :aliases => "-s"
|
121
|
+
method_option :vpc_id, :type => :string
|
122
|
+
method_option :vpc_ec2_subnets, :type => :array
|
123
|
+
method_option :vpc_elb_subnets, :type => :array
|
124
|
+
method_option :vpc_security_groups, :type => :array
|
125
|
+
method_option :key_name, :type => :string
|
126
|
+
method_option :env_vars, :type => :string
|
127
|
+
def update_config
|
128
|
+
Stalkedbybean::EnvVars.parse_options(options[:file_path], options)
|
129
|
+
Stalkedbybean::EnvVars.update_configuration_options
|
130
|
+
end
|
131
|
+
|
132
|
+
desc "update_env_vars [OPTIONS]", "Updates environment variables"
|
133
|
+
method_option :file_path, :type => :string, :aliases => "-f"
|
134
|
+
method_option :aws_profile, :type => :string, :aliases => "-p"
|
135
|
+
method_option :aws_region, :type => :string, :aliases => "-r"
|
136
|
+
method_option :env_vars, :type => :string
|
137
|
+
def update_env_vars
|
138
|
+
Stalkedbybean::EnvVars.parse_options(options[:file_path], options)
|
139
|
+
Stalkedbybean::EnvVars.update_environment_variables
|
140
|
+
end
|
141
|
+
|
142
|
+
desc "print_env_vars [OPTIONS]", "Prints existing environment variables"
|
143
|
+
method_option :file_path, :type => :string, :aliases => "-f"
|
144
|
+
method_option :app_name, :type => :string, :aliases => "-n"
|
145
|
+
method_option :aws_profile, :type => :string, :aliases => "-p"
|
146
|
+
method_option :aws_region, :type => :string, :aliases => "-r"
|
147
|
+
method_option :environment, :type => :string, :aliases => "-e"
|
148
|
+
def print_env_vars
|
149
|
+
Stalkedbybean::EnvVars.parse_options(options[:file_path], options)
|
150
|
+
Stalkedbybean::EnvVars.print_environment_variables
|
151
|
+
end
|
152
|
+
|
153
|
+
desc "versions [OPTIONS]", "Displays application versions"
|
154
|
+
method_option :file_path, :type => :string, :aliases => "-f"
|
155
|
+
method_option :aws_profile, :type => :string, :aliases => "-p"
|
156
|
+
method_option :aws_region, :type => :string, :aliases => "-r"
|
157
|
+
def versions
|
158
|
+
Stalkedbybean::AppInfo.parse_options(options[:file_path], options)
|
159
|
+
Stalkedbybean::AppInfo.list_application_versions
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
desc "init", "Generates a config file"
|
164
|
+
def init(name)
|
165
|
+
Stalkedbybean::Generators::Init.start([name])
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'Shellwords'
|
2
|
+
|
3
|
+
module Stalkedbybean
|
4
|
+
class Deploy
|
5
|
+
|
6
|
+
def self.parse_options(file_path, options)
|
7
|
+
@options = Stalkedbybean::Parser.parse_options(file_path, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.deploy_version
|
11
|
+
system(
|
12
|
+
<<~HEREDOC
|
13
|
+
eb deploy #{@options[:app_name]}-#{@options[:environment]} \
|
14
|
+
--profile #{@options[:aws_profile]} \
|
15
|
+
-r #{@options[:aws_region]} \
|
16
|
+
--version #{@options[:version]}
|
17
|
+
HEREDOC
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'Shellwords'
|
2
|
+
require 'aws-sdk-elasticbeanstalk'
|
3
|
+
|
4
|
+
module Stalkedbybean
|
5
|
+
class EnvVars
|
6
|
+
|
7
|
+
def self.parse_options(file_path, options)
|
8
|
+
@options = Stalkedbybean::Parser.parse_options(file_path, options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.update_configuration_options
|
12
|
+
|
13
|
+
@client = Aws::ElasticBeanstalk::Client.new(region: "#{@options[:aws_region]}", profile: "#{@options[:aws_profile]}")
|
14
|
+
|
15
|
+
resp = @client.update_environment({
|
16
|
+
application_name: "#{@options[:app_name]}",
|
17
|
+
environment_name: "#{@options[:app_name]}-#{@options[:environment]}",
|
18
|
+
platform_arn: "#{@options[:platform_arn]}",
|
19
|
+
option_settings: [
|
20
|
+
{
|
21
|
+
namespace: "aws:ec2:vpc",
|
22
|
+
option_name: "VPCId",
|
23
|
+
value: "#{@options[:vpc_id]}"
|
24
|
+
},
|
25
|
+
{
|
26
|
+
namespace: "aws:autoscaling:launchconfiguration",
|
27
|
+
option_name: "SecurityGroups",
|
28
|
+
value: "#{@options[:vpc_security_groups]}"
|
29
|
+
},
|
30
|
+
{
|
31
|
+
namespace: "aws:autoscaling:asg",
|
32
|
+
option_name: "MaxSize",
|
33
|
+
value: "1"
|
34
|
+
},
|
35
|
+
{
|
36
|
+
namespace: "aws:autoscaling:asg",
|
37
|
+
option_name: "MinSize",
|
38
|
+
value: "1"
|
39
|
+
},
|
40
|
+
{
|
41
|
+
namespace: "aws:autoscaling:launchconfiguration",
|
42
|
+
option_name: "InstanceType",
|
43
|
+
value: "#{@options[:instance_size]}"
|
44
|
+
},
|
45
|
+
{
|
46
|
+
namespace: "aws:ec2:vpc",
|
47
|
+
option_name: "ELBSubnets",
|
48
|
+
value: "#{@options[:vpc_elb_subnets]}"
|
49
|
+
},
|
50
|
+
{
|
51
|
+
namespace: "aws:ec2:vpc",
|
52
|
+
option_name: "Subnets",
|
53
|
+
value: "#{@options[:vpc_ec2_subnets]}"
|
54
|
+
},
|
55
|
+
{
|
56
|
+
namespace: "aws:autoscaling:launchconfiguration",
|
57
|
+
option_name: "EC2KeyName",
|
58
|
+
value: "#{@options[:key_name]}"
|
59
|
+
},
|
60
|
+
],
|
61
|
+
})
|
62
|
+
|
63
|
+
puts "Environment update has started. This will take some time."
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.update_environment_variables
|
67
|
+
system(
|
68
|
+
"eb setenv #{@options[:env_vars]} --profile #{@options[:aws_profile]} --region #{@options[:aws_region]}"
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.print_environment_variables
|
73
|
+
system(
|
74
|
+
"eb printenv #{@options[:app_name]}-#{@options[:environment]} --profile #{@options[:aws_profile]} -r #{@options[:aws_region]}"
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'thor/group'
|
2
|
+
|
3
|
+
module Stalkedbybean
|
4
|
+
module Generators
|
5
|
+
class Init < Thor::Group
|
6
|
+
argument :name, :type => :string
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
def self.source_root
|
10
|
+
File.dirname(__FILE__) + "/init"
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_group
|
14
|
+
empty_directory('config')
|
15
|
+
end
|
16
|
+
|
17
|
+
def copy_config_file
|
18
|
+
template("config.yml", "config/config_#{name}.yml")
|
19
|
+
end
|
20
|
+
|
21
|
+
def copy_config_settings
|
22
|
+
template(".stalkedbybean.yml", "config/.stalkedbybean.yml")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# MANDATORY OPTIONS TO BE FILLED UP BEFORE SETTING UP SECRETS
|
2
|
+
app_name:
|
3
|
+
aws_profile:
|
4
|
+
aws_region:
|
5
|
+
environment: <%= name %>
|
6
|
+
|
7
|
+
# MANDATORY OPTIONS TO BE FILLED UP BEFORE SETTING UP ROLES
|
8
|
+
aws_account_id:
|
9
|
+
kms_arn:
|
10
|
+
|
11
|
+
# OPTIONAL (BUT HIGHLY RECOMMENDED) OPTIONS
|
12
|
+
vpc_id:
|
13
|
+
vpc_security_groups:
|
14
|
+
-
|
15
|
+
instance_count:
|
16
|
+
instance_size:
|
17
|
+
platform_arn:
|
18
|
+
env_vars: "KEY=value"
|
19
|
+
vpc_ec2_subnets:
|
20
|
+
-
|
21
|
+
-
|
22
|
+
vpc_elb_subnets:
|
23
|
+
-
|
24
|
+
-
|
25
|
+
key_name:
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'Shellwords'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Stalkedbybean
|
5
|
+
class Initialize
|
6
|
+
|
7
|
+
def self.parse_options(file_path, options)
|
8
|
+
@options = Stalkedbybean::Parser.parse_options(file_path, options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.initialize_app
|
12
|
+
system("eb init #{@options[:app_name]} --profile #{@options[:aws_profile]} -r #{@options[:aws_region]} -p #{@options[:platform_arn]}")
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Stalkedbybean
|
2
|
+
module Parser
|
3
|
+
extend self
|
4
|
+
|
5
|
+
CONFIG_SETTINGS_FILE = "config/.stalkedbybean.yml"
|
6
|
+
|
7
|
+
def parse_options(file_path, options)
|
8
|
+
file_path ||= get_default_file_path
|
9
|
+
default_options = load_default_options(file_path)
|
10
|
+
parsed_options = symbolize_option_names(options)
|
11
|
+
default_options.merge!(parsed_options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def load_default_options(file_path)
|
15
|
+
default_options = YAML::load(open(file_path))
|
16
|
+
symbolize_option_names(default_options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def symbolize_option_names(options)
|
20
|
+
options.map { |key, value| [key.to_sym, value] }.to_h
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_default_file_path
|
24
|
+
settings = YAML::load_file(CONFIG_SETTINGS_FILE)
|
25
|
+
settings["default"]
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'Shellwords'
|
2
|
+
|
3
|
+
module Stalkedbybean
|
4
|
+
class Provision
|
5
|
+
|
6
|
+
def self.parse_options(file_path, options)
|
7
|
+
@options = Stalkedbybean::Parser.parse_options(file_path, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.create_environment
|
11
|
+
puts "provisioning app #{@options[:app_name]} in AWS region #{@options[:aws_region]} for environment #{@options[:environment]}"
|
12
|
+
|
13
|
+
system(
|
14
|
+
<<~HEREDOC
|
15
|
+
eb create #{@options[:app_name]}-#{@options[:environment]} \
|
16
|
+
--profile #{@options[:aws_profile]} \
|
17
|
+
--region #{@options[:aws_region]} \
|
18
|
+
-p #{@options[:platform_arn]} \
|
19
|
+
-i #{@options[:instance_size]} \
|
20
|
+
-ip #{@options[:app_name]}-#{@options[:environment]}-beanstalk-EC2 \
|
21
|
+
-sr aws-elasticbeanstalk-service-role \
|
22
|
+
--tags project=#{@options[:app_name]},environment=#{@options[:environment]} \
|
23
|
+
--scale #{@options[:instance_count]} \
|
24
|
+
--elb-type classic \
|
25
|
+
--vpc.id #{@options[:vpc_id]} \
|
26
|
+
--vpc.elbpublic \
|
27
|
+
--vpc.ec2subnets #{@options[:vpc_ec2_subnets].join(',')} \
|
28
|
+
--vpc.elbsubnets #{@options[:vpc_elb_subnets].join(',')} \
|
29
|
+
--vpc.securitygroups #{@options[:vpc_security_groups].join(',')} \
|
30
|
+
--version #{@options[:version]} \
|
31
|
+
--envvars #{@options[:env_vars]} \
|
32
|
+
--keyname #{@options[:key_name]}
|
33
|
+
HEREDOC
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'aws-sdk-iam'
|
2
|
+
|
3
|
+
module Stalkedbybean
|
4
|
+
class RoleSetup
|
5
|
+
|
6
|
+
def self.parse_options(file_path, options)
|
7
|
+
@options = Stalkedbybean::Parser.parse_options(file_path, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.setup_IAM
|
11
|
+
|
12
|
+
@app_tag = "#{@options[:app_name]}-#{@options[:environment]}"
|
13
|
+
@client = Aws::IAM::Client.new(region: "#{@options[:aws_region]}", profile: "#{@options[:aws_profile]}")
|
14
|
+
@iam = Aws::IAM::Resource.new(client: @client)
|
15
|
+
|
16
|
+
role_name = "#{@app_tag}-beanstalk-EC2"
|
17
|
+
|
18
|
+
begin
|
19
|
+
role = self.create_role
|
20
|
+
puts "Role created"
|
21
|
+
rescue Aws::IAM::Errors::EntityAlreadyExists
|
22
|
+
puts "Role already created"
|
23
|
+
role = @client.get_role({
|
24
|
+
role_name: role_name
|
25
|
+
})
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
cred_stash_policy = self.create_cred_stash_policy
|
30
|
+
puts "Credstash policy created"
|
31
|
+
rescue Aws::IAM::Errors::EntityAlreadyExists
|
32
|
+
puts "Credstash policy already created"
|
33
|
+
|
34
|
+
policies = @client.list_policies({})
|
35
|
+
arn = policies.policies.find { |policy| policy.policy_name == "#{@app_tag}-credstash-access" }.arn
|
36
|
+
|
37
|
+
cred_stash_policy = @client.get_policy({
|
38
|
+
policy_arn: arn
|
39
|
+
})
|
40
|
+
end
|
41
|
+
|
42
|
+
begin
|
43
|
+
self.attach_policy_to_role(cred_stash_policy.arn, role)
|
44
|
+
puts "Credstash policy attached"
|
45
|
+
rescue Exception => ex
|
46
|
+
puts "Credstash policy already attached"
|
47
|
+
end
|
48
|
+
|
49
|
+
begin
|
50
|
+
self.attach_policy_to_role("arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier", role)
|
51
|
+
rescue Exception => ex
|
52
|
+
puts "AWSElasticBeanstalkWebTier policy already attached"
|
53
|
+
end
|
54
|
+
|
55
|
+
begin
|
56
|
+
@client.create_instance_profile({
|
57
|
+
instance_profile_name: role_name
|
58
|
+
})
|
59
|
+
puts "Instance profile created"
|
60
|
+
rescue Exception => ex
|
61
|
+
puts "Instance profile already created"
|
62
|
+
end
|
63
|
+
|
64
|
+
begin
|
65
|
+
@client.add_role_to_instance_profile({
|
66
|
+
instance_profile_name: role_name,
|
67
|
+
role_name: role_name
|
68
|
+
})
|
69
|
+
puts "Role added to instance profile"
|
70
|
+
rescue Exception => ex
|
71
|
+
puts "Role has already been added to instance profile"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def self.create_role
|
78
|
+
policy_doc = {
|
79
|
+
Version:"2012-10-17",
|
80
|
+
Statement:[
|
81
|
+
{
|
82
|
+
Effect:"Allow",
|
83
|
+
Principal:{
|
84
|
+
Service:"ec2.amazonaws.com"
|
85
|
+
},
|
86
|
+
Action:"sts:AssumeRole"
|
87
|
+
}
|
88
|
+
]
|
89
|
+
}
|
90
|
+
|
91
|
+
role = @iam.create_role({
|
92
|
+
role_name: "#{@app_tag}-beanstalk-EC2",
|
93
|
+
assume_role_policy_document: policy_doc.to_json
|
94
|
+
})
|
95
|
+
|
96
|
+
return role
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.create_cred_stash_policy
|
100
|
+
role_policy_document = {
|
101
|
+
"Version": "2012-10-17",
|
102
|
+
"Statement": [
|
103
|
+
{
|
104
|
+
"Action": [
|
105
|
+
"kms:Decrypt"
|
106
|
+
],
|
107
|
+
"Effect": "Allow",
|
108
|
+
"Resource": "#{@options[:kms_arn]}"
|
109
|
+
},
|
110
|
+
{
|
111
|
+
"Action": [
|
112
|
+
"dynamodb:GetItem",
|
113
|
+
"dynamodb:Query",
|
114
|
+
"dynamodb:Scan"
|
115
|
+
],
|
116
|
+
"Effect": "Allow",
|
117
|
+
"Resource": "arn:aws:dynamodb:#{@options[:aws_region]}:#{@options[:aws_account_id]}:table/#{@app_tag}"
|
118
|
+
}
|
119
|
+
]
|
120
|
+
}.to_json
|
121
|
+
|
122
|
+
cred_stash_policy = @iam.create_policy({
|
123
|
+
policy_name: "#{@app_tag}-credstash-access",
|
124
|
+
policy_document: role_policy_document
|
125
|
+
})
|
126
|
+
|
127
|
+
cred_stash_policy
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.attach_policy_to_role(policy_arn, role)
|
131
|
+
role.attach_policy({
|
132
|
+
policy_arn: policy_arn
|
133
|
+
})
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'aws-sdk-kms'
|
2
|
+
require 'Shellwords'
|
3
|
+
|
4
|
+
module Stalkedbybean
|
5
|
+
class SecretsSetup
|
6
|
+
|
7
|
+
def self.parse_options(file_path, options)
|
8
|
+
@options = Stalkedbybean::Parser.parse_options(file_path, options)
|
9
|
+
@app_tag = "#{@options[:app_name]}-#{@options[:environment]}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.create_key
|
13
|
+
@client = Aws::KMS::Client.new(region: "#{@options[:aws_region]}", profile: "#{@options[:aws_profile]}")
|
14
|
+
key = @client.create_key({})
|
15
|
+
@client.create_alias({
|
16
|
+
alias_name: "alias/#{@options[:app_name]}",
|
17
|
+
target_key_id: key[:key_metadata][:key_id]
|
18
|
+
})
|
19
|
+
|
20
|
+
puts "Your KMS ARN is: #{key[:key_metadata][:arn]}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.create_credstash_table
|
24
|
+
system("credstash -r #{@options[:aws_region]} -p #{@options[:aws_profile]} -t #{@app_tag} setup")
|
25
|
+
puts "Credstash table #{@app_tag} created."
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.add_secret(key, value)
|
29
|
+
raise(StandardError, "Missing or invalid key/value") if key == nil || value == nil
|
30
|
+
system("credstash -r #{@options[:aws_region]} -p #{@options[:aws_profile]} -t #{@app_tag} put -k alias/#{@options[:app_name]} #{key} #{value}")
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.get_secret(key)
|
34
|
+
raise(StandardError, "Missing or invalid key") if key == nil
|
35
|
+
system("credstash -r #{@options[:aws_region]} -p #{@options[:aws_profile]} -t #{@app_tag} get #{key}")
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.getall_secrets
|
39
|
+
system("credstash -r #{@options[:aws_region]} -p #{@options[:aws_profile]} -t #{@app_tag} getall")
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.change_secret(key, value, version)
|
43
|
+
raise(StandardError, "Missing or invalid key/value") if key == nil || value == nil
|
44
|
+
raise(StandardError, "Missing version number") if version == nil
|
45
|
+
system("credstash -r #{@options[:aws_region]} -p #{@options[:aws_profile]} -t #{@app_tag} put -k alias/#{@options[:app_name]} -v #{version} #{key} #{value}")
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'Shellwords'
|
2
|
+
|
3
|
+
module Stalkedbybean
|
4
|
+
class Terminate
|
5
|
+
|
6
|
+
def self.parse_options(file_path, options)
|
7
|
+
@options = Stalkedbybean::Parser.parse_options(file_path, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.terminate_environment
|
11
|
+
system(
|
12
|
+
"eb terminate #{@options[:environment]} --all --profile #{@options[:aws_profile]} -r #{@options[:aws_region]}",
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "stalkedbybean/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "stalkedbybean"
|
8
|
+
spec.version = Stalkedbybean::VERSION
|
9
|
+
spec.authors = ["Kavita Kalaichelvan", "Thomas Depierre"]
|
10
|
+
spec.email = ["kavita.kalaichelvan@ascential.com", "thomas.depierre@ascential.com"]
|
11
|
+
|
12
|
+
spec.summary = "Command line utility to deploy Elixir apps to AWS using Elastic Beanstalk"
|
13
|
+
spec.description = "You can deploy your Elixir app to AWS by running a few simple commands."
|
14
|
+
spec.homepage = "https://github.com/ascential/am-stalkedbybean"
|
15
|
+
spec.license = "BSD-3-Clause"
|
16
|
+
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
19
|
+
f.match(%r{^(test|spec|features)/})
|
20
|
+
end
|
21
|
+
spec.bindir = "exe"
|
22
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
+
spec.require_paths = ["lib"]
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "cucumber"
|
28
|
+
spec.add_development_dependency "aruba"
|
29
|
+
spec.add_dependency "thor"
|
30
|
+
spec.add_dependency "aws-sdk-kms"
|
31
|
+
spec.add_dependency "aws-sdk-iam"
|
32
|
+
spec.add_dependency "aws-sdk-elasticbeanstalk"
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stalkedbybean
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kavita Kalaichelvan
|
8
|
+
- Thomas Depierre
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2018-03-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.16'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.16'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '10.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '10.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: cucumber
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: aruba
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: thor
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: aws-sdk-kms
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :runtime
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: aws-sdk-iam
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :runtime
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: aws-sdk-elasticbeanstalk
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :runtime
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
description: You can deploy your Elixir app to AWS by running a few simple commands.
|
127
|
+
email:
|
128
|
+
- kavita.kalaichelvan@ascential.com
|
129
|
+
- thomas.depierre@ascential.com
|
130
|
+
executables:
|
131
|
+
- stalkedbybean
|
132
|
+
extensions: []
|
133
|
+
extra_rdoc_files: []
|
134
|
+
files:
|
135
|
+
- ".gitignore"
|
136
|
+
- ".travis.yml"
|
137
|
+
- Gemfile
|
138
|
+
- Gemfile.lock
|
139
|
+
- LICENSE.txt
|
140
|
+
- README.md
|
141
|
+
- Rakefile
|
142
|
+
- bin/console
|
143
|
+
- bin/setup
|
144
|
+
- config/.stalkedbybean.yml
|
145
|
+
- config/config_test.yml
|
146
|
+
- docs/setting_up_config_file.md
|
147
|
+
- docs/setting_up_credstash.md
|
148
|
+
- exe/stalkedbybean
|
149
|
+
- lib/stalkedbybean.rb
|
150
|
+
- lib/stalkedbybean/app_info.rb
|
151
|
+
- lib/stalkedbybean/cli.rb
|
152
|
+
- lib/stalkedbybean/deploy.rb
|
153
|
+
- lib/stalkedbybean/env_vars.rb
|
154
|
+
- lib/stalkedbybean/generators/init.rb
|
155
|
+
- lib/stalkedbybean/generators/init/.stalkedbybean.yml
|
156
|
+
- lib/stalkedbybean/generators/init/config.yml
|
157
|
+
- lib/stalkedbybean/initialize.rb
|
158
|
+
- lib/stalkedbybean/parser.rb
|
159
|
+
- lib/stalkedbybean/provision.rb
|
160
|
+
- lib/stalkedbybean/role_setup.rb
|
161
|
+
- lib/stalkedbybean/secrets_setup.rb
|
162
|
+
- lib/stalkedbybean/terminate.rb
|
163
|
+
- lib/stalkedbybean/version.rb
|
164
|
+
- stalkedbybean.gemspec
|
165
|
+
homepage: https://github.com/ascential/am-stalkedbybean
|
166
|
+
licenses:
|
167
|
+
- BSD-3-Clause
|
168
|
+
metadata: {}
|
169
|
+
post_install_message:
|
170
|
+
rdoc_options: []
|
171
|
+
require_paths:
|
172
|
+
- lib
|
173
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
requirements: []
|
184
|
+
rubyforge_project:
|
185
|
+
rubygems_version: 2.7.3
|
186
|
+
signing_key:
|
187
|
+
specification_version: 4
|
188
|
+
summary: Command line utility to deploy Elixir apps to AWS using Elastic Beanstalk
|
189
|
+
test_files: []
|