rubycfn 0.4.10 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -1
  3. data/Gemfile.lock +1 -1
  4. data/README.md +43 -67
  5. data/bin/rubycfn +17 -73
  6. data/lib/cli_methods.rb +2 -2
  7. data/lib/rubycfn/version.rb +1 -1
  8. data/templates/.env +2 -0
  9. data/templates/.env.acceptance +1 -0
  10. data/templates/.env.dependencies.rspec +6 -0
  11. data/templates/.env.development +1 -0
  12. data/templates/.env.production +1 -0
  13. data/templates/.env.rspec +1 -0
  14. data/templates/.env.test +1 -0
  15. data/templates/{.gitignore.erb → .gitignore} +3 -0
  16. data/templates/{.rubocop.yml.erb → .rubocop.yml} +14 -1
  17. data/templates/{Gemfile.erb → Gemfile} +0 -1
  18. data/templates/README.md +57 -0
  19. data/templates/{Rakefile.erb → Rakefile} +15 -8
  20. data/templates/bootstrap/dependency_stack.rb +49 -0
  21. data/templates/config.yaml +65 -0
  22. data/templates/lib/aws_helper/aws_sdk.rb +30 -0
  23. data/templates/{compiler.rb.erb → lib/aws_helper/compiler.rb} +15 -9
  24. data/templates/{dependencies.rb.erb → lib/aws_helper/dependencies.rb} +5 -3
  25. data/templates/{deploy.rb.erb → lib/aws_helper/deploy.rb} +6 -4
  26. data/templates/lib/aws_helper/helpers.rb +3 -0
  27. data/templates/{main_aws_helper.rb.erb → lib/aws_helper/main.rb} +0 -0
  28. data/templates/{upload_stack.rb.erb → lib/aws_helper/upload_stack.rb} +15 -6
  29. data/templates/lib/core/applications.rb +479 -0
  30. data/templates/lib/core/assume_role.rb +40 -0
  31. data/templates/lib/core/classes.rb +25 -0
  32. data/templates/{core_compile.rb.erb → lib/core/compile.rb} +1 -0
  33. data/templates/lib/core/dependencies.rb +22 -0
  34. data/templates/{core_deploy.rb.erb → lib/core/deploy.rb} +20 -10
  35. data/templates/lib/core/git.rb +15 -0
  36. data/templates/lib/core/init.rb +173 -0
  37. data/templates/{core_upload.rb.erb → lib/core/upload.rb} +0 -0
  38. data/templates/{main.rb.erb → lib/main.rb} +8 -6
  39. data/templates/lib/shared_concerns/global_variables.rb +56 -0
  40. data/templates/{helper_methods.rb.erb → lib/shared_concerns/helper_functions.rb} +0 -0
  41. data/templates/lib/shared_concerns/helper_methods.rb +3 -0
  42. data/templates/{shared_methods.rb.erb → lib/shared_concerns/shared_methods.rb} +9 -0
  43. data/templates/lib/stacks/acm_stack/certificate_manager.rb +79 -0
  44. data/templates/{new_stack.rb.erb → lib/stacks/acm_stack/main.rb} +3 -4
  45. data/templates/lib/stacks/ecs_stack/ecs_cluster.rb +344 -0
  46. data/templates/lib/stacks/ecs_stack/lifecycle_hook.rb +188 -0
  47. data/templates/lib/stacks/ecs_stack/load_balancer.rb +68 -0
  48. data/templates/{ecs_stack.rb.erb → lib/stacks/ecs_stack/main.rb} +2 -1
  49. data/templates/{project_stack.rb.erb → lib/stacks/parent_stack/main.rb} +2 -2
  50. data/templates/lib/stacks/parent_stack/parent.rb +18 -0
  51. data/templates/lib/stacks/vpc_stack/infra_vpc.rb +193 -0
  52. data/templates/{vpc_stack.rb.erb → lib/stacks/vpc_stack/main.rb} +1 -2
  53. data/templates/{parent_stack_spec.rb.erb → spec/lib/parent_spec.rb} +2 -5
  54. data/templates/{spec_helper.rb.erb → spec/spec_helper.rb} +2 -2
  55. metadata +54 -44
  56. data/format.vim +0 -3
  57. data/templates/.env.erb +0 -4
  58. data/templates/.env.production.erb +0 -6
  59. data/templates/.env.rspec.erb +0 -6
  60. data/templates/.env.test.erb +0 -6
  61. data/templates/.gitlab-ci.yml.erb +0 -75
  62. data/templates/aws_sdk.rb.erb +0 -18
  63. data/templates/core_diff.rb.erb +0 -59
  64. data/templates/ecs_stack_concern.rb.erb +0 -20
  65. data/templates/global_variables.rb.erb +0 -16
  66. data/templates/helpers.rb.erb +0 -7
  67. data/templates/new_concern.rb.erb +0 -10
  68. data/templates/project_concern.rb.erb +0 -26
  69. data/templates/subnets.rb.erb +0 -18
  70. data/templates/vpc_concerns.rb.erb +0 -87
  71. 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, artifact_bucket)
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/#{artifact_bucket}/#{environment}-" \
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
- Module.constants.select do |mod|
34
- if mod =~ /Stack$/
35
- send("include", Object.const_get("SharedConcerns"))
36
- stacks[mod.to_sym] = send("include", Object.const_get(mod)).render_template("AWS")
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
- stack_to_md5(stack_name, stack)
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["ARTIFACT_BUCKET"])
59
+ stack = update_references(JSON.parse(stack), ENV["ENVIRONMENT"], ENV["CLOUDFORMATIONBUCKET"])
54
60
  stacks[stack_name] = stack
55
- stack_to_md5(stack_name, stack)
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
- Dotenv.load(".env.private")
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["ARTIFACT_BUCKET"],
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 "ARTIFACT_BUCKET not set" unless ENV["ARTIFACT_BUCKET"]
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
@@ -0,0 +1,3 @@
1
+ def stack_to_hash(stack_name)
2
+ @stack_hashes[stack_name] = git_revision
3
+ end
@@ -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
- s3 = create_bucket_if_not_exists(
11
- env_vars[:aws_region],
12
- env_vars[:artifact_bucket]
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(env_vars[:artifact_bucket]).object(s3_filename)
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://#{env_vars[:artifact_bucket]}/#{s3_filename}"
34
+ puts "Uploaded #{stack_name} to s3://#{ENV["CLOUDFORMATIONBUCKET"]}/#{s3_filename}"
26
35
  end
27
36
  end