rubycfn 0.4.10 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/Gemfile.lock +1 -1
- data/README.md +43 -67
- data/bin/rubycfn +17 -73
- data/lib/cli_methods.rb +2 -2
- data/lib/rubycfn/version.rb +1 -1
- data/templates/.env +2 -0
- data/templates/.env.acceptance +1 -0
- data/templates/.env.dependencies.rspec +6 -0
- data/templates/.env.development +1 -0
- data/templates/.env.production +1 -0
- data/templates/.env.rspec +1 -0
- data/templates/.env.test +1 -0
- data/templates/{.gitignore.erb → .gitignore} +3 -0
- data/templates/{.rubocop.yml.erb → .rubocop.yml} +14 -1
- data/templates/{Gemfile.erb → Gemfile} +0 -1
- data/templates/README.md +57 -0
- data/templates/{Rakefile.erb → Rakefile} +15 -8
- data/templates/bootstrap/dependency_stack.rb +49 -0
- data/templates/config.yaml +65 -0
- data/templates/lib/aws_helper/aws_sdk.rb +30 -0
- data/templates/{compiler.rb.erb → lib/aws_helper/compiler.rb} +15 -9
- data/templates/{dependencies.rb.erb → lib/aws_helper/dependencies.rb} +5 -3
- data/templates/{deploy.rb.erb → lib/aws_helper/deploy.rb} +6 -4
- data/templates/lib/aws_helper/helpers.rb +3 -0
- data/templates/{main_aws_helper.rb.erb → lib/aws_helper/main.rb} +0 -0
- data/templates/{upload_stack.rb.erb → lib/aws_helper/upload_stack.rb} +15 -6
- data/templates/lib/core/applications.rb +479 -0
- data/templates/lib/core/assume_role.rb +40 -0
- data/templates/lib/core/classes.rb +25 -0
- data/templates/{core_compile.rb.erb → lib/core/compile.rb} +1 -0
- data/templates/lib/core/dependencies.rb +22 -0
- data/templates/{core_deploy.rb.erb → lib/core/deploy.rb} +20 -10
- data/templates/lib/core/git.rb +15 -0
- data/templates/lib/core/init.rb +173 -0
- data/templates/{core_upload.rb.erb → lib/core/upload.rb} +0 -0
- data/templates/{main.rb.erb → lib/main.rb} +8 -6
- data/templates/lib/shared_concerns/global_variables.rb +56 -0
- data/templates/{helper_methods.rb.erb → lib/shared_concerns/helper_functions.rb} +0 -0
- data/templates/lib/shared_concerns/helper_methods.rb +3 -0
- data/templates/{shared_methods.rb.erb → lib/shared_concerns/shared_methods.rb} +9 -0
- data/templates/lib/stacks/acm_stack/certificate_manager.rb +79 -0
- data/templates/{new_stack.rb.erb → lib/stacks/acm_stack/main.rb} +3 -4
- data/templates/lib/stacks/ecs_stack/ecs_cluster.rb +344 -0
- data/templates/lib/stacks/ecs_stack/lifecycle_hook.rb +188 -0
- data/templates/lib/stacks/ecs_stack/load_balancer.rb +68 -0
- data/templates/{ecs_stack.rb.erb → lib/stacks/ecs_stack/main.rb} +2 -1
- data/templates/{project_stack.rb.erb → lib/stacks/parent_stack/main.rb} +2 -2
- data/templates/lib/stacks/parent_stack/parent.rb +18 -0
- data/templates/lib/stacks/vpc_stack/infra_vpc.rb +193 -0
- data/templates/{vpc_stack.rb.erb → lib/stacks/vpc_stack/main.rb} +1 -2
- data/templates/{parent_stack_spec.rb.erb → spec/lib/parent_spec.rb} +2 -5
- data/templates/{spec_helper.rb.erb → spec/spec_helper.rb} +2 -2
- metadata +54 -44
- data/format.vim +0 -3
- data/templates/.env.erb +0 -4
- data/templates/.env.production.erb +0 -6
- data/templates/.env.rspec.erb +0 -6
- data/templates/.env.test.erb +0 -6
- data/templates/.gitlab-ci.yml.erb +0 -75
- data/templates/aws_sdk.rb.erb +0 -18
- data/templates/core_diff.rb.erb +0 -59
- data/templates/ecs_stack_concern.rb.erb +0 -20
- data/templates/global_variables.rb.erb +0 -16
- data/templates/helpers.rb.erb +0 -7
- data/templates/new_concern.rb.erb +0 -10
- data/templates/project_concern.rb.erb +0 -26
- data/templates/subnets.rb.erb +0 -18
- data/templates/vpc_concerns.rb.erb +0 -87
- data/templates/vpc_spec.rb.erb +0 -39
@@ -0,0 +1,65 @@
|
|
1
|
+
environments:
|
2
|
+
rspec:
|
3
|
+
vpc_cidr: 192.168.0.0/16
|
4
|
+
stack_name: rspec-devops
|
5
|
+
domain_name: "rspec.io"
|
6
|
+
no_subdomain: true
|
7
|
+
development:
|
8
|
+
vpc_cidr: 10.10.0.0/16
|
9
|
+
stack_name: development-devops
|
10
|
+
test:
|
11
|
+
vpc_cidr: 10.20.0.0/16
|
12
|
+
stack_name: test-devops
|
13
|
+
acceptance:
|
14
|
+
vpc_cidr: 10.30.0.0/16
|
15
|
+
stack_name: acceptance-devops
|
16
|
+
production:
|
17
|
+
vpc_cidr: 10.40.0.0/16
|
18
|
+
stack_name: production-devops
|
19
|
+
subnets:
|
20
|
+
- ec2_public:
|
21
|
+
owner: infra
|
22
|
+
public: true
|
23
|
+
offset: 1
|
24
|
+
deploy_nat: true
|
25
|
+
output_cidr: false
|
26
|
+
- ec2_private:
|
27
|
+
owner: infra
|
28
|
+
public: false
|
29
|
+
offset: 2
|
30
|
+
deploy_nat: false
|
31
|
+
output_cidr: false
|
32
|
+
- backend_rds_public:
|
33
|
+
owner: infra
|
34
|
+
public: true
|
35
|
+
offset: 3
|
36
|
+
deploy_nat: false
|
37
|
+
output_cidr: false
|
38
|
+
- backend_rds_private:
|
39
|
+
owner: infra
|
40
|
+
public: false
|
41
|
+
offset: 4
|
42
|
+
deploy_nat: false
|
43
|
+
output_cidr: false
|
44
|
+
applications:
|
45
|
+
hello-world:
|
46
|
+
image: nginxdemos/hello
|
47
|
+
container_port: 80
|
48
|
+
priority: 2
|
49
|
+
min: 2
|
50
|
+
max: 8
|
51
|
+
mem: 128
|
52
|
+
env:
|
53
|
+
SOME_ENV_VAR: Exposed
|
54
|
+
SOME_OTHER_VAR: desopxE
|
55
|
+
hello-world2:
|
56
|
+
image: tutum/hello-world
|
57
|
+
container_port: 80
|
58
|
+
priority: 3
|
59
|
+
min: 2
|
60
|
+
max: 8
|
61
|
+
mem: 128
|
62
|
+
env:
|
63
|
+
SOME_ENV_VAR: Exposed
|
64
|
+
SOME_OTHER_VAR: desopxE
|
65
|
+
domain_name: "example.com"
|
@@ -0,0 +1,30 @@
|
|
1
|
+
def create_bucket_if_not_exists(aws_region, artifact_bucket)
|
2
|
+
s3 = Aws::S3::Resource.new(region: aws_region)
|
3
|
+
begin
|
4
|
+
s3.create_bucket(bucket: artifact_bucket)
|
5
|
+
rescue => exception
|
6
|
+
raise exception unless exception.class == Aws::S3::Errors::BucketAlreadyOwnedByYou
|
7
|
+
end
|
8
|
+
s3
|
9
|
+
end
|
10
|
+
|
11
|
+
def set_aws_credentials(region, access_key_id, secret_access_key)
|
12
|
+
if access_key_id.nil? == false && secret_access_key.nil? == false
|
13
|
+
aws_session_token = ENV["AWS_SESSION_TOKEN"]
|
14
|
+
if aws_session_token.nil?
|
15
|
+
Aws.config.update(
|
16
|
+
region: region,
|
17
|
+
credentials: Aws::Credentials.new(access_key_id, secret_access_key)
|
18
|
+
)
|
19
|
+
else
|
20
|
+
Aws.config.update(
|
21
|
+
region: region,
|
22
|
+
credentials: Aws::Credentials.new(access_key_id, secret_access_key, aws_session_token)
|
23
|
+
)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
Aws.config.update(
|
27
|
+
region: region
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
@@ -1,12 +1,14 @@
|
|
1
1
|
require "git-revision"
|
2
2
|
|
3
|
-
def update_references(contents, environment,
|
3
|
+
def update_references(contents, environment, _artifact_bucket)
|
4
|
+
Dotenv.load(".env.private")
|
5
|
+
Dotenv.load(".env.dependencies")
|
4
6
|
contents["Resources"].map do |resource|
|
5
7
|
resource_name = resource.shift
|
6
8
|
resource_values = resource.shift
|
7
9
|
if resource_values["Type"] == "AWS::CloudFormation::Stack"
|
8
10
|
template_hash = @stack_hashes[resource_name.to_sym]
|
9
|
-
s3_url = "https://s3.amazonaws.com/#{
|
11
|
+
s3_url = "https://s3.amazonaws.com/#{ENV["CLOUDFORMATIONBUCKET"]}/#{environment}-" \
|
10
12
|
"#{resource_name.downcase}-#{template_hash}.json"
|
11
13
|
resource_values["Properties"]["TemplateURL"] = s3_url
|
12
14
|
end
|
@@ -30,17 +32,21 @@ end
|
|
30
32
|
def compile_stacks(skip_creation = false)
|
31
33
|
stacks = {}
|
32
34
|
FileUtils.mkdir_p "build" unless skip_creation
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
# Iterate twice to support dynamically generated modules
|
36
|
+
2.times do
|
37
|
+
Module.constants.select do |mod|
|
38
|
+
if mod =~ /Stack$/
|
39
|
+
next unless stacks[mod.to_sym].nil?
|
40
|
+
send("include", Object.const_get("SharedConcerns"))
|
41
|
+
stacks[mod.to_sym] = send("include", Object.const_get(mod)).render_template("AWS")
|
42
|
+
end
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
40
46
|
stacks.each do |stack_name, stack|
|
41
47
|
stack = inject_dummy_resource(stack)
|
42
48
|
next if JSON.parse(stack)["Resources"].nil?
|
43
|
-
|
49
|
+
stack_to_hash(stack_name)
|
44
50
|
unless skip_creation
|
45
51
|
puts "- Saved #{stack_name} to build/#{ENV["ENVIRONMENT"]}-#{stack_name.downcase}.json"
|
46
52
|
File.open("build/#{ENV["ENVIRONMENT"]}-#{stack_name.downcase}.json", "w") { |f| f.write(JSON.pretty_generate(JSON.parse(stack))) }
|
@@ -50,9 +56,9 @@ def compile_stacks(skip_creation = false)
|
|
50
56
|
stacks.each do |stack_name, stack|
|
51
57
|
stack = inject_dummy_resource(stack)
|
52
58
|
next if JSON.parse(stack)["Resources"].nil?
|
53
|
-
stack = update_references(JSON.parse(stack), ENV["ENVIRONMENT"], ENV["
|
59
|
+
stack = update_references(JSON.parse(stack), ENV["ENVIRONMENT"], ENV["CLOUDFORMATIONBUCKET"])
|
54
60
|
stacks[stack_name] = stack
|
55
|
-
|
61
|
+
stack_to_hash(stack_name)
|
56
62
|
unless skip_creation
|
57
63
|
File.open("build/#{ENV["ENVIRONMENT"]}-#{stack_name.downcase}.json", "w") { |f| f.write(JSON.pretty_generate(JSON.parse(stack))) }
|
58
64
|
end
|
@@ -1,13 +1,15 @@
|
|
1
1
|
def load_env_vars
|
2
|
+
Dotenv.load(".env.private")
|
3
|
+
Dotenv.load(".env.dependencies")
|
2
4
|
Dotenv.load(".env")
|
3
5
|
Dotenv.load(".env.#{ENV["ENVIRONMENT"]}")
|
4
|
-
|
6
|
+
|
5
7
|
check_dependencies
|
6
8
|
{
|
7
9
|
aws_region: ENV["AWS_REGION"],
|
8
10
|
aws_access_key_id: ENV["AWS_ACCESS_KEY_ID"],
|
9
11
|
aws_secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"],
|
10
|
-
artifact_bucket: ENV["
|
12
|
+
artifact_bucket: ENV["ARTIFACTBUCKET"],
|
11
13
|
environment: ENV["ENVIRONMENT"],
|
12
14
|
stack_name: ENV["STACK_NAME"]
|
13
15
|
}
|
@@ -16,7 +18,7 @@ end
|
|
16
18
|
def check_dependencies
|
17
19
|
ENV["AWS_REGION"] ||= ENV["AWS_DEFAULT_REGION"]
|
18
20
|
raise "AWS_REGION not set" unless ENV["AWS_REGION"]
|
19
|
-
raise "
|
21
|
+
raise "ARTIFACTBUCKET not set" unless ENV["ARTIFACTBUCKET"]
|
20
22
|
raise "ENVIRONMENT not set" unless ENV["ENVIRONMENT"]
|
21
23
|
raise "STACK_NAME not set" unless ENV["STACK_NAME"]
|
22
24
|
raise "AWS CREDENTIALS NOT SET" unless ENV["AWS_ACCESS_KEY_ID"] && ENV["AWS_SECRET_ACCESS_KEY"]
|
@@ -3,7 +3,7 @@ WAITING_STATES = %w(
|
|
3
3
|
UPDATE_COMPLETE_CLEANUP_IN_PROGRESS UPDATE_IN_PROGRESS
|
4
4
|
UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS UPDATE_ROLLBACK_IN_PROGRESS
|
5
5
|
).freeze
|
6
|
-
SUCCESS_STATES = %w(CREATE_COMPLETE UPDATE_COMPLETE).freeze
|
6
|
+
SUCCESS_STATES = %w(IMPORT_COMPLETE CREATE_COMPLETE UPDATE_COMPLETE).freeze
|
7
7
|
FAILURE_STATES = %w(
|
8
8
|
CREATE_FAILED DELETE_FAILED UPDATE_ROLLBACK_FAILED
|
9
9
|
ROLLBACK_FAILED ROLLBACK_COMPLETE ROLLBACK_FAILED
|
@@ -11,7 +11,7 @@ FAILURE_STATES = %w(
|
|
11
11
|
).freeze
|
12
12
|
END_STATES = SUCCESS_STATES + FAILURE_STATES
|
13
13
|
DEPLOYABLE_STATES = %w(
|
14
|
-
CREATE_COMPLETE UPDATE_COMPLETE ROLLBACK_COMPLETE
|
14
|
+
IMPORT_COMPLETE CREATE_COMPLETE UPDATE_COMPLETE ROLLBACK_COMPLETE
|
15
15
|
UPDATE_ROLLBACK_COMPLETE
|
16
16
|
).freeze
|
17
17
|
|
@@ -38,16 +38,18 @@ end
|
|
38
38
|
def get_parent_stack_s3_location(bucket, environment)
|
39
39
|
stacks = compile_stacks(true)
|
40
40
|
parent_stack = nil
|
41
|
+
file_hash = nil
|
41
42
|
|
42
43
|
stacks.each do |stack_name, stack|
|
43
44
|
next if JSON.parse(stack)["Resources"].nil?
|
44
45
|
JSON.parse(stack)["Resources"].each do |_resource, payload|
|
45
46
|
if payload["Type"] == "AWS::CloudFormation::Stack"
|
46
47
|
parent_stack = stack_name
|
48
|
+
json_file = "build/#{environment}-#{stack_name.downcase}.json"
|
49
|
+
file_hash = git_revision
|
47
50
|
break
|
48
51
|
end
|
49
52
|
end
|
50
53
|
end
|
51
|
-
|
52
|
-
"https://s3.amazonaws.com/#{bucket}/#{environment}-#{parent_stack.downcase}-#{@stack_hashes[parent_stack.to_sym]}.json"
|
54
|
+
"https://s3.amazonaws.com/#{bucket}/#{environment}-#{parent_stack.downcase}-#{file_hash}.json"
|
53
55
|
end
|
File without changes
|
@@ -1,4 +1,8 @@
|
|
1
|
+
require_relative "../core/git"
|
2
|
+
|
1
3
|
def upload_stacks
|
4
|
+
Dotenv.load(".env.private")
|
5
|
+
Dotenv.load(".env.dependencies")
|
2
6
|
env_vars = load_env_vars
|
3
7
|
|
4
8
|
set_aws_credentials(
|
@@ -7,21 +11,26 @@ def upload_stacks
|
|
7
11
|
env_vars[:aws_secret_access_key]
|
8
12
|
)
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
+
begin
|
15
|
+
s3 = create_bucket_if_not_exists(
|
16
|
+
env_vars[:aws_region],
|
17
|
+
env_vars[:artifact_bucket]
|
18
|
+
)
|
19
|
+
rescue => e
|
20
|
+
puts "Exception create_bucket_if_not_exists #{e}"
|
21
|
+
end
|
14
22
|
|
15
23
|
stacks = compile_stacks(true)
|
24
|
+
raise "CLOUDFORMATIONBUCKET not found in DependencyStack outputs" unless ENV["CLOUDFORMATIONBUCKET"]
|
16
25
|
stacks.each do |stack_name, stack|
|
17
26
|
next if JSON.parse(stack)["Resources"].nil?
|
18
27
|
hash = @stack_hashes[stack_name.to_sym]
|
19
28
|
local_file = "#{env_vars[:environment]}-#{stack_name.downcase}.json"
|
20
29
|
s3_filename = "#{env_vars[:environment]}-#{stack_name.downcase}-#{hash}.json"
|
21
30
|
# content = JSON.parse(stack).to_json
|
22
|
-
obj = s3.bucket(
|
31
|
+
obj = s3.bucket(ENV["CLOUDFORMATIONBUCKET"]).object(s3_filename)
|
23
32
|
content = File.open("build/#{local_file}").read
|
24
33
|
obj.put(body: content)
|
25
|
-
puts "Uploaded #{stack_name} to s3://#{
|
34
|
+
puts "Uploaded #{stack_name} to s3://#{ENV["CLOUDFORMATIONBUCKET"]}/#{s3_filename}"
|
26
35
|
end
|
27
36
|
end
|