rubycfn 0.4.10 → 0.5.4

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -1
  3. data/Gemfile.lock +48 -46
  4. data/README.md +46 -71
  5. data/bin/rubycfn +17 -73
  6. data/lib/cli_methods.rb +2 -2
  7. data/lib/rubycfn/version.rb +1 -1
  8. data/rubycfn.gemspec +1 -1
  9. data/templates/.env +2 -0
  10. data/templates/.env.acceptance +1 -0
  11. data/templates/.env.dependencies.rspec +6 -0
  12. data/templates/.env.development +1 -0
  13. data/templates/.env.production +1 -0
  14. data/templates/.env.rspec +1 -0
  15. data/templates/.env.test +1 -0
  16. data/templates/{.gitignore.erb → .gitignore} +7 -0
  17. data/templates/{.rubocop.yml.erb → .rubocop.yml} +17 -1
  18. data/templates/{Gemfile.erb → Gemfile} +0 -1
  19. data/templates/README.md +58 -0
  20. data/templates/{Rakefile.erb → Rakefile} +15 -8
  21. data/templates/config.yaml +68 -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/lib/aws_helper/dependencies.rb +35 -0
  25. data/templates/{deploy.rb.erb → lib/aws_helper/deploy.rb} +5 -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} +8 -6
  29. data/templates/lib/core/applications.rb +625 -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 +29 -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 +221 -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} +11 -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 +190 -0
  47. data/templates/lib/stacks/ecs_stack/load_balancer.rb +70 -0
  48. data/templates/{ecs_stack.rb.erb → lib/stacks/ecs_stack/main.rb} +3 -0
  49. data/templates/lib/stacks/ecs_stack/rollback.rb +77 -0
  50. data/templates/{project_stack.rb.erb → lib/stacks/parent_stack/main.rb} +2 -2
  51. data/templates/lib/stacks/parent_stack/parent.rb +18 -0
  52. data/templates/lib/stacks/vpc_stack/infra_vpc.rb +193 -0
  53. data/templates/{vpc_stack.rb.erb → lib/stacks/vpc_stack/main.rb} +1 -2
  54. data/templates/{parent_stack_spec.rb.erb → spec/lib/parent_spec.rb} +2 -5
  55. data/templates/{spec_helper.rb.erb → spec/spec_helper.rb} +2 -2
  56. metadata +61 -51
  57. data/format.vim +0 -3
  58. data/templates/.env.erb +0 -4
  59. data/templates/.env.production.erb +0 -6
  60. data/templates/.env.rspec.erb +0 -6
  61. data/templates/.env.test.erb +0 -6
  62. data/templates/.gitlab-ci.yml.erb +0 -75
  63. data/templates/aws_sdk.rb.erb +0 -18
  64. data/templates/core_diff.rb.erb +0 -59
  65. data/templates/dependencies.rb.erb +0 -23
  66. data/templates/ecs_stack_concern.rb.erb +0 -20
  67. data/templates/global_variables.rb.erb +0 -16
  68. data/templates/helpers.rb.erb +0 -7
  69. data/templates/new_concern.rb.erb +0 -10
  70. data/templates/project_concern.rb.erb +0 -26
  71. data/templates/subnets.rb.erb +0 -18
  72. data/templates/vpc_concerns.rb.erb +0 -87
  73. data/templates/vpc_spec.rb.erb +0 -39
@@ -0,0 +1,40 @@
1
+ require "aws-sdk-core"
2
+ require "aws-sdk-s3"
3
+ require "aws-sdk-iam"
4
+ require "aws-sdk-organizations"
5
+
6
+ def generate_session_name
7
+ "assume_role_" + (0...12).map { ("a".."z").to_a[rand(26)] }.join
8
+ end
9
+
10
+ def assume_role(aws_accounts, to_account, from_account = nil)
11
+ session_name = generate_session_name
12
+ if from_account
13
+ from_credentials = aws_accounts[from_account][:credentials]
14
+ credentials = Aws::AssumeRoleCredentials.new(
15
+ client: Aws::STS::Client.new(
16
+ access_key_id: from_credentials[:access_key_id],
17
+ region: "eu-central-1",
18
+ secret_access_key: from_credentials[:secret_access_key],
19
+ session_token: from_credentials[:session_token]
20
+ ),
21
+ role_arn: "arn:aws:iam::#{aws_accounts[to_account][:account_id]}:role/#{aws_accounts[to_account][:role_name]}",
22
+ role_session_name: session_name
23
+ )
24
+ else
25
+ credentials = Aws::AssumeRoleCredentials.new(
26
+ client: Aws::STS::Client.new(region: aws_accounts[to_account][:region]),
27
+ role_arn: "arn:aws:iam::#{aws_accounts[to_account][:account_id]}:role/#{aws_accounts[to_account][:role_name]}",
28
+ role_session_name: session_name
29
+ )
30
+ end
31
+ aws_accounts[to_account][:credentials] = {
32
+ access_key_id: credentials.credentials.access_key_id,
33
+ credentials: credentials,
34
+ region: aws_accounts[to_account][:region],
35
+ secret_access_key: credentials.credentials.secret_access_key,
36
+ session_name: session_name,
37
+ session_token: credentials.credentials.session_token
38
+ }
39
+ aws_accounts
40
+ end
@@ -0,0 +1,25 @@
1
+ # Add convenient method to reference secrets.
2
+ # Would be nice for parameter store as well!
3
+ class String
4
+ def secret(argument)
5
+ [
6
+ "{{resolve:secretsmanager:",
7
+ self.ref,
8
+ ":SecretString:",
9
+ argument,
10
+ "}}"
11
+ ].fnjoin
12
+ end
13
+ end
14
+
15
+ class Symbol
16
+ def secret(argument)
17
+ [
18
+ "{{resolve:secretsmanager:",
19
+ self.ref,
20
+ ":SecretString:",
21
+ argument,
22
+ "}}"
23
+ ].fnjoin
24
+ end
25
+ end
@@ -2,5 +2,6 @@ require "digest/md5"
2
2
  require "fileutils"
3
3
 
4
4
  require_relative "../aws_helper/main"
5
+ require_relative "../core/git"
5
6
 
6
7
  compile_stacks
@@ -0,0 +1,29 @@
1
+ require "aws-sdk-core"
2
+ require "aws-sdk-cloudformation"
3
+ require "dotenv"
4
+
5
+ Dotenv.load(".env.private")
6
+ Dotenv.load(".env")
7
+ Dotenv.load(".env.#{ENV["ENVIRONMENT"]}")
8
+
9
+ ENV["AWS_DEFAULT_REGION"] ||= "eu-west-1"
10
+ ENV["AWS_REGION"] ||= ENV["AWS_DEFAULT_REGION"]
11
+
12
+ client = Aws::CloudFormation::Client.new(region: ENV["AWS_REGION"])
13
+
14
+ begin
15
+ res = client.describe_stacks(
16
+ stack_name: "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack"
17
+ )
18
+ rescue Aws::CloudFormation::Errors::InvalidClientTokenId, Aws::CloudFormation::Errors::ValidationError => e
19
+ puts "E: #{e.class}"
20
+ raise "ERROR: Your AWS credentials are not set or invalid." if e.class == Aws::CloudFormation::Errors::InvalidClientTokenId
21
+ raise "ERROR: <%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack does not exist. Run `rake init` first!" if e.class == Aws::CloudFormation::Errors::ValidationError
22
+ end
23
+
24
+ dep_file = File.open(".env.dependencies.#{ENV["ENVIRONMENT"]}", "w")
25
+ res[:stacks].each do |stack|
26
+ stack[:outputs].each do |output|
27
+ dep_file.puts "#{output[:output_key].upcase}=#{output[:output_value]}"
28
+ end
29
+ end
@@ -6,6 +6,10 @@ require "aws-sdk"
6
6
 
7
7
  require_relative "../aws_helper/main"
8
8
 
9
+ Dotenv.load(".env.private")
10
+ Dotenv.load(".env.dependencies.#{ENV["ENVIRONMENT"]}")
11
+ raise "CLOUDFORMATIONBUCKET not set. Run `rake init` and `rake update` first!" unless ENV["CLOUDFORMATIONBUCKET"]
12
+
9
13
  env_vars = load_env_vars
10
14
 
11
15
  set_aws_credentials(
@@ -15,12 +19,22 @@ set_aws_credentials(
15
19
  )
16
20
 
17
21
  s3_filename = get_parent_stack_s3_location(
18
- env_vars[:artifact_bucket],
22
+ ENV["CLOUDFORMATIONBUCKET"],
19
23
  env_vars[:environment]
20
24
  )
21
25
 
22
26
  client = Aws::CloudFormation::Client.new
23
27
 
28
+ parent_parameters = []
29
+ File.open(".env.dependencies.#{ENV["ENVIRONMENT"]}").read.each_line do |line|
30
+ line.strip!
31
+ param, value = line.split("=")
32
+ parent_parameters.push(
33
+ parameter_key: param,
34
+ parameter_value: value
35
+ )
36
+ end
37
+
24
38
  # Store previous CloudFormation events in an array, so that we don't output
25
39
  # events from previous deploys.
26
40
 
@@ -47,15 +61,13 @@ if stack_exists
47
61
  stack_name: env_vars[:stack_name],
48
62
  template_url: s3_filename,
49
63
  capabilities: %w(CAPABILITY_IAM CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND),
50
- # stack_policy_body: "StackPolicyBody",
51
- # stack_policy_url: "StackPolicyURL",
64
+ parameters: parent_parameters,
52
65
  tags: [
53
66
  {
54
67
  key: "team",
55
- value: "<%= name.downcase %>"
68
+ value: "infra"
56
69
  }
57
- ],
58
- # client_request_token: "ClientRequestToken",
70
+ ]
59
71
  )
60
72
  else
61
73
  client.create_stack(
@@ -64,15 +76,13 @@ else
64
76
  timeout_in_minutes: 60,
65
77
  capabilities: %w(CAPABILITY_IAM CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND),
66
78
  on_failure: "ROLLBACK",
67
- # stack_policy_body: "StackPolicyBody",
68
- # stack_policy_url: "StackPolicyURL",
79
+ parameters: parent_parameters,
69
80
  tags: [
70
81
  {
71
82
  key: "team",
72
- value: "<%= name.downcase %>"
83
+ value: "infra"
73
84
  }
74
85
  ],
75
- # client_request_token: "ClientRequestToken",
76
86
  enable_termination_protection: false
77
87
  )
78
88
  end
@@ -0,0 +1,15 @@
1
+ require "git-revision"
2
+
3
+ module Git
4
+ class Revision
5
+ class << self
6
+ def dirty?
7
+ !`git diff --numstat | wc -l`.strip.to_i.zero?
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ def git_revision
14
+ "#{Git::Revision.commit}#{Git::Revision.dirty? ? "-dirty" : ""}"
15
+ end
@@ -0,0 +1,221 @@
1
+ require "aws-sdk"
2
+ require "dotenv"
3
+ require "git-revision"
4
+ require "rubycfn"
5
+ require "yaml"
6
+
7
+ require_relative "../aws_helper/main"
8
+
9
+ Dotenv.load(".env.private")
10
+ Dotenv.load(".env")
11
+ Dotenv.load(".env.#{ENV["ENVIRONMENT"]}")
12
+
13
+ set_aws_credentials(
14
+ ENV["AWS_REGION"],
15
+ ENV["AWS_ACCESS_KEY_ID"],
16
+ ENV["AWS_SECRET_ACCESS_KEY"]
17
+ )
18
+
19
+ def inject_dummy_resource(stack)
20
+ hack_stack = JSON.parse(stack)
21
+ hack_stack["Resources"] = {} if hack_stack["Resources"].nil?
22
+ hack_stack["Resources"]["CloudFormationDummyResource"] = {
23
+ "Type": "AWS::CloudFormation::WaitConditionHandle",
24
+ "Metadata": {
25
+ "Comment": "Resource to update stack even if there are no changes",
26
+ "GitCommitHash": Git::Revision.commit
27
+ }
28
+ }
29
+ hack_stack.to_json
30
+ end
31
+
32
+ def read_domain_name
33
+ config = YAML.safe_load(File.read("config.yaml"), [Symbol])
34
+ config["applications"] ||= {}
35
+ config["environments"] ||= {}
36
+ config["subnets"] ||= {}
37
+
38
+ # Allow override by setting ENV var
39
+ domain_name = ENV["DOMAIN_NAME"]
40
+ subdomain = ENV["SUBDOMAIN"] # rubocop:disable Lint/UselessAssignment
41
+
42
+ # First, look at environment specific domain name configuration
43
+ domain_name ||= config["environments"][ENV["ENVIRONMENT"]]["domain_name"].nil? && nil || config["environments"][ENV["ENVIRONMENT"]]["domain_name"]
44
+
45
+ # Assign the global domain name configuration unless domain_name was set to false in environment config.yaml
46
+ domain_name ||= config["domain_name"] unless domain_name.class == FalseClass
47
+
48
+ # Set domain name to an empty string if domain_name was set to false
49
+ domain_name = "" if domain_name.class == FalseClass
50
+
51
+ # If the no_subdomain setting for environments in config.yaml is omitted or set to false, set subdomain to environment, else assign empty string
52
+ subdomain = (config["environments"][ENV["ENVIRONMENT"]]["no_subdomain"].nil? || config["environments"][ENV["ENVIRONMENT"]]["no_subdomain"] == false) && ENV["ENVIRONMENT"] || ""
53
+
54
+ # Return an array with t he subdomain and domain_name
55
+ [subdomain, domain_name]
56
+ end
57
+
58
+ subdomain, domain_name = read_domain_name
59
+
60
+ raise "ENVIRONMENT not set" unless ENV["ENVIRONMENT"]
61
+ warn "WARNING: domain_name not set in config.yaml... Route53 Hosted Zone will not be created" if domain_name.empty?
62
+
63
+ module Project<%= project_name %>DependencyStack
64
+ extend ActiveSupport::Concern
65
+ include Rubycfn
66
+
67
+ included do
68
+ description "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}Dependency Stack"
69
+
70
+ parameter :environment,
71
+ description: "Environment name",
72
+ type: "String"
73
+
74
+ parameter :domain_name,
75
+ description: "Domain name",
76
+ type: "String"
77
+
78
+ condition :has_environment,
79
+ [["", :environment.ref].fnequals].fnnot
80
+
81
+ condition :has_domain_name,
82
+ [["", :domain_name.ref].fnequals].fnnot
83
+
84
+ %i(
85
+ artifact_bucket
86
+ cloudformation_bucket
87
+ lambda_bucket
88
+ logging_bucket
89
+ ).each do |bucket|
90
+ resource bucket,
91
+ deletion_policy: "Retain",
92
+ update_replace_policy: "Retain",
93
+ type: "AWS::S3::Bucket"
94
+
95
+ output bucket,
96
+ value: bucket.ref
97
+ end
98
+
99
+ resource :hosted_zone,
100
+ condition: "HasDomainName",
101
+ type: "AWS::Route53::HostedZone" do |r|
102
+ r.property(:hosted_zone_config) do
103
+ {
104
+ "Comment": ["Hosted zone for ", ["HasEnvironment", [:environment.ref, "."].fnjoin, ""].fnif, :domain_name.ref].fnjoin
105
+ }
106
+ end
107
+ r.property(:name) { [["HasEnvironment", [:environment.ref, "."].fnjoin, ""].fnif, :domain_name.ref].fnjoin }
108
+ end
109
+
110
+ output :hosted_zone_id,
111
+ condition: "HasDomainName",
112
+ value: :hosted_zone.ref
113
+
114
+ output :hosted_zone_name,
115
+ condition: "HasDomainName",
116
+ value: [["HasEnvironment", [:environment.ref, "."].fnjoin, ""].fnif, :domain_name.ref].fnjoin
117
+ end
118
+ end
119
+
120
+ stack = include Project<%= project_name %>DependencyStack # rubocop:disable Style/MixinUsage
121
+ template = stack.render_template
122
+
123
+ client = Aws::CloudFormation::Client.new
124
+
125
+ stack_exists = false
126
+ previous_statuses = []
127
+ 80.times do
128
+ previous_events = get_prior_events(client, "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack")
129
+ previous_statuses = previous_events.map(&:event_id)
130
+ stack_exists = previous_events.size.to_i.positive? ? true : false
131
+ break unless stack_exists
132
+
133
+ events_last_deploy = get_events_last_deploy(previous_events)
134
+ last_event = events_last_deploy.shift
135
+ break if last_event \
136
+ && (last_event.logical_resource_id == "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack") \
137
+ && (last_event.stack_name == "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack") \
138
+ && (DEPLOYABLE_STATES.include? last_event.resource_status)
139
+ puts "Stack is currently in #{last_event.resource_status} mode. Waiting for it to finish..." if last_event
140
+ sleep 15
141
+ end
142
+
143
+ template = inject_dummy_resource(template)
144
+
145
+ parameters = [
146
+ {
147
+ parameter_key: "Environment",
148
+ parameter_value: subdomain
149
+ },
150
+ {
151
+ parameter_key: "DomainName",
152
+ parameter_value: domain_name
153
+ }
154
+ ]
155
+
156
+ if stack_exists
157
+ client.update_stack(
158
+ stack_name: "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack",
159
+ template_body: template,
160
+ capabilities: %w(CAPABILITY_IAM CAPABILITY_NAMED_IAM),
161
+ parameters: parameters,
162
+ tags: [
163
+ {
164
+ key: "team",
165
+ value: "infra"
166
+ }
167
+ ]
168
+ )
169
+ else
170
+ client.create_stack(
171
+ stack_name: "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack",
172
+ template_body: template,
173
+ timeout_in_minutes: 60,
174
+ capabilities: %w(CAPABILITY_IAM CAPABILITY_NAMED_IAM),
175
+ on_failure: "ROLLBACK",
176
+ parameters: parameters,
177
+ tags: [
178
+ {
179
+ key: "team",
180
+ value: "infra"
181
+ }
182
+ ],
183
+ enable_termination_protection: false
184
+ )
185
+ end
186
+
187
+ shown_log_lines = {}
188
+
189
+ 360.times do
190
+ resp = client.describe_stack_events(
191
+ stack_name: "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack"
192
+ )
193
+ resp.stack_events.to_a.reverse.each_with_index do |event, index|
194
+ next if previous_statuses.include? event.event_id
195
+ @completed = false
196
+ @stack_name = event.stack_name
197
+ @logical_resource_id = event.logical_resource_id
198
+ @resource_type = event.resource_type
199
+ @timestamp = event.timestamp
200
+ @resource_status = event.resource_status
201
+ @resource_status_reason = event.resource_status_reason
202
+ log_line = "[#{@logical_resource_id.green}] #{@timestamp.to_s.blue}: " \
203
+ "#{@resource_status.white} #{@resource_status_reason.to_s.red}"
204
+ puts log_line unless shown_log_lines[log_line]
205
+ shown_log_lines[log_line] = true
206
+ if (@stack_name == "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack") \
207
+ && (@logical_resource_id == "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack") \
208
+ && (END_STATES.include? @resource_status) \
209
+ && (index + 1 == resp.stack_events.to_a.size)
210
+ @completed = true
211
+ end
212
+ end
213
+ if @completed
214
+ puts "==================================="
215
+ puts " STATUS: #{@resource_status} #{@resource_status_reason}"
216
+ puts "==================================="
217
+ raise "#{@resource_status} #{@resource_status_reason}" if FAILURE_STATES.include? @resource_status
218
+ break
219
+ end
220
+ sleep(10)
221
+ end
@@ -1,8 +1,10 @@
1
1
  require "rubycfn"
2
2
  require "dotenv"
3
+ require_relative "core/classes"
3
4
 
4
- Dotenv.load(".env")
5
5
  Dotenv.load(".env.private")
6
+ Dotenv.load(".env.dependencies.#{ENV["ENVIRONMENT"]}")
7
+ Dotenv.load(".env")
6
8
  Dotenv.load(".env.#{ENV["ENVIRONMENT"]}")
7
9
 
8
10
  # Include all group concerns
@@ -21,10 +23,10 @@ module SharedConcerns
21
23
  end
22
24
 
23
25
  # Include all stack concerns
24
- Dir[File.expand_path("../stacks/", __FILE__) + "/**/*.rb"].sort.each do |file|
25
- subdir = File.basename(file, ".rb")
26
- Dir[File.expand_path("../stacks/", __dir__) + "/#{subdir}/**/*.rb"].sort.each do |subfile|
27
- require subfile
26
+ # Load module code first, and last include main.rb's.
27
+ 2.times do |i|
28
+ Dir[File.expand_path("../stacks/", __FILE__) + "/**/*.rb"].sort.each do |file|
29
+ require file unless File.basename(file) == "main.rb" || i.positive?
30
+ require file if File.basename(file) == "main.rb" && i.positive?
28
31
  end
29
- require file
30
32
  end
@@ -0,0 +1,56 @@
1
+ require "yaml"
2
+
3
+ module Concerns
4
+ module GlobalVariables
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ def load_config(_val)
9
+ config = YAML.safe_load(File.read("config.yaml"), [Symbol])
10
+ config["applications"] ||= {}
11
+ config["environments"] ||= {}
12
+ config["subnets"] ||= {}
13
+ config
14
+ end
15
+
16
+ def global_tags(_val)
17
+ [
18
+ {
19
+ "Key": "Team",
20
+ "Value": "infra"
21
+ },
22
+ {
23
+ "Key": "Environment",
24
+ "Value": environment.to_s
25
+ },
26
+ {
27
+ "Key": "StackName",
28
+ "Value": stack_name.to_s
29
+ }
30
+ ]
31
+ end
32
+
33
+ variable :environment,
34
+ default: "development",
35
+ global: true,
36
+ value: ENV["ENVIRONMENT"]
37
+
38
+ variable :region,
39
+ global: true,
40
+ default: ENV["DEFAULT_AWS_REGION"],
41
+ value: ENV["AWS_REGION"]
42
+
43
+ variable :infra_config,
44
+ global: true,
45
+ filter: :load_config
46
+
47
+ variable :stack_name,
48
+ global: true,
49
+ default: infra_config["environments"][environment]["stack_name"]
50
+
51
+ variable :default_tags,
52
+ global: true,
53
+ filter: :global_tags
54
+ end
55
+ end
56
+ end