rubycfn 0.4.10 → 0.5.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.
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