inspec-iggy 0.2.0 → 0.4.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 +4 -4
- data/Gemfile +8 -6
- data/README.md +91 -40
- data/inspec-iggy.gemspec +13 -13
- data/lib/inspec-iggy.rb +11 -2
- data/lib/inspec-iggy/cloudformation/cli_command.rb +92 -0
- data/lib/inspec-iggy/cloudformation/parser.rb +106 -0
- data/lib/inspec-iggy/inspec_helper.rb +62 -40
- data/lib/inspec-iggy/plugin.rb +43 -0
- data/lib/inspec-iggy/profile.rb +74 -0
- data/lib/inspec-iggy/terraform/cli_command.rb +94 -0
- data/lib/inspec-iggy/terraform/parser.rb +147 -0
- data/lib/inspec-iggy/version.rb +4 -4
- metadata +13 -16
- data/lib/inspec-iggy/cli.rb +0 -53
- data/lib/inspec-iggy/cloudformation.rb +0 -104
- data/lib/inspec-iggy/terraform.rb +0 -146
- data/test/bad.json +0 -6
- data/test/bjc-demo-aws-4.5.4.json +0 -851
- data/test/main.tf +0 -156
- data/test/outputs.tf +0 -11
- data/test/terraform.tfstate +0 -383
- data/test/variables.tf +0 -35
data/lib/inspec-iggy/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inspec-iggy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Ray
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: inspec
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '2.
|
19
|
+
version: '2.3'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 4.0.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '2.
|
29
|
+
version: '2.3'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 4.0.0
|
33
33
|
description: Generate InSpec compliance profiles from Terraform by tagging instances
|
34
34
|
and mapping Terraform to InSpec.
|
35
35
|
email:
|
@@ -42,17 +42,14 @@ files:
|
|
42
42
|
- README.md
|
43
43
|
- inspec-iggy.gemspec
|
44
44
|
- lib/inspec-iggy.rb
|
45
|
-
- lib/inspec-iggy/
|
46
|
-
- lib/inspec-iggy/cloudformation.rb
|
45
|
+
- lib/inspec-iggy/cloudformation/cli_command.rb
|
46
|
+
- lib/inspec-iggy/cloudformation/parser.rb
|
47
47
|
- lib/inspec-iggy/inspec_helper.rb
|
48
|
-
- lib/inspec-iggy/
|
48
|
+
- lib/inspec-iggy/plugin.rb
|
49
|
+
- lib/inspec-iggy/profile.rb
|
50
|
+
- lib/inspec-iggy/terraform/cli_command.rb
|
51
|
+
- lib/inspec-iggy/terraform/parser.rb
|
49
52
|
- lib/inspec-iggy/version.rb
|
50
|
-
- test/bad.json
|
51
|
-
- test/bjc-demo-aws-4.5.4.json
|
52
|
-
- test/main.tf
|
53
|
-
- test/outputs.tf
|
54
|
-
- test/terraform.tfstate
|
55
|
-
- test/variables.tf
|
56
53
|
homepage: https://github.com/inspec/inspec-iggy
|
57
54
|
licenses:
|
58
55
|
- Apache-2.0
|
@@ -73,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
70
|
version: '0'
|
74
71
|
requirements: []
|
75
72
|
rubyforge_project:
|
76
|
-
rubygems_version: 2.6.
|
73
|
+
rubygems_version: 2.6.13
|
77
74
|
signing_key:
|
78
75
|
specification_version: 4
|
79
76
|
summary: InSpec plugin to generate InSpec compliance profiles from Terraform.
|
data/lib/inspec-iggy/cli.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
#
|
3
|
-
# Author:: Matt Ray (<matt@chef.io>)
|
4
|
-
#
|
5
|
-
# Copyright:: 2018, Chef Software, Inc <legal@chef.io>
|
6
|
-
#
|
7
|
-
|
8
|
-
require "inspec/plugins"
|
9
|
-
require "thor"
|
10
|
-
|
11
|
-
require "inspec-iggy/terraform"
|
12
|
-
|
13
|
-
module Iggy
|
14
|
-
class CLI < Thor
|
15
|
-
namespace "terraform"
|
16
|
-
|
17
|
-
map %w{-v --version} => "version"
|
18
|
-
|
19
|
-
desc "version", "Display version information", hide: true
|
20
|
-
def version
|
21
|
-
say("Iggy v#{Iggy::VERSION}")
|
22
|
-
end
|
23
|
-
|
24
|
-
class_option :tfstate,
|
25
|
-
:aliases => "-t",
|
26
|
-
:desc => "Specify path to the input terraform.tfstate",
|
27
|
-
:default => "terraform.tfstate"
|
28
|
-
|
29
|
-
class_option :debug,
|
30
|
-
:desc => "Verbose debugging messages",
|
31
|
-
:type => :boolean,
|
32
|
-
:default => false
|
33
|
-
|
34
|
-
desc "generate [options]", "Generate InSpec compliance controls from terraform.tfstate"
|
35
|
-
def generate
|
36
|
-
Inspec::Log.level = :debug if options[:debug]
|
37
|
-
generated_controls = Iggy::Terraform.parse_generate(options[:tfstate])
|
38
|
-
# let's just generate a control file with a set of controls for now
|
39
|
-
Iggy::InspecHelper.print_controls(options[:tfstate], generated_controls)
|
40
|
-
exit 0
|
41
|
-
end
|
42
|
-
|
43
|
-
desc "extract [options]", "Extract tagged InSpec profiles from terraform.tfstate"
|
44
|
-
def extract
|
45
|
-
Inspec::Log.level = :debug if options[:debug]
|
46
|
-
extracted_profiles = Iggy::Terraform.parse_extract(options[:tfstate])
|
47
|
-
Iggy::InspecHelper.print_commands(extracted_profiles)
|
48
|
-
exit 0
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
Inspec::Plugins::CLI.add_subcommand(CLI, "terraform", "terraform SUBCOMMAND ...", "Extract or generate InSpec from Terraform", {})
|
53
|
-
end
|
@@ -1,104 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Matt Ray (<matt@chef.io>)
|
3
|
-
#
|
4
|
-
# Copyright:: 2018, Chef Software, Inc <legal@chef.io>
|
5
|
-
#
|
6
|
-
|
7
|
-
require "iggy"
|
8
|
-
|
9
|
-
require "json"
|
10
|
-
require "thor"
|
11
|
-
|
12
|
-
module Iggy
|
13
|
-
class CloudFormation < Thor
|
14
|
-
option :template,
|
15
|
-
:aliases => "-t",
|
16
|
-
:desc => "Specify path to the input CloudFormation template"
|
17
|
-
|
18
|
-
option :debug,
|
19
|
-
:desc => "Verbose debugging messages",
|
20
|
-
:type => :boolean,
|
21
|
-
:default => false
|
22
|
-
|
23
|
-
desc "generate [options]", "Generate InSpec compliance controls from CloudFormation template"
|
24
|
-
long_desc <<-LONGDESC
|
25
|
-
Reads in a CloudFormation JSON file and generates matching InSpec compliance controls.
|
26
|
-
LONGDESC
|
27
|
-
def generate
|
28
|
-
Iggy::Log.level = :debug if options[:debug]
|
29
|
-
Iggy::Log.debug "CloudFormation.generate file = #{options[:template]}"
|
30
|
-
# hash of generated controls
|
31
|
-
generated_controls = parse_generate(options[:template])
|
32
|
-
Iggy::Log.debug "CloudFormation.generate generated_controls = #{generated_controls}"
|
33
|
-
# let's just generate a control file with a set of controls for now
|
34
|
-
Iggy::Inspec.print_controls(options[:template], generated_controls)
|
35
|
-
exit 0
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def parse_generate(file)
|
41
|
-
Iggy::Log.debug "CloudFormation.parse_generate file = #{file}"
|
42
|
-
begin
|
43
|
-
unless File.file?(file)
|
44
|
-
STDERR.puts "ERROR: #{file} is an invalid file, please check your path."
|
45
|
-
exit(-1)
|
46
|
-
end
|
47
|
-
template = JSON.parse(File.read(file))
|
48
|
-
rescue JSON::ParserError => e
|
49
|
-
STDERR.puts e.message
|
50
|
-
STDERR.puts "ERROR: Parsing error in #{file}."
|
51
|
-
exit(-1)
|
52
|
-
end
|
53
|
-
basename = File.basename(file)
|
54
|
-
absolutename = File.absolute_path(file)
|
55
|
-
|
56
|
-
# InSpec controls generated
|
57
|
-
generated_controls = {}
|
58
|
-
|
59
|
-
# iterate over the resources
|
60
|
-
cfn_resources = template["Resources"]
|
61
|
-
# iterate over the Resources, use these as IDs?
|
62
|
-
cfn_resources.keys.each do |cfn_res|
|
63
|
-
# split out the last ::, these are all AWS
|
64
|
-
cfn_res_type = "aws_" + cfn_resources[cfn_res]["Type"].split("::").last.downcase
|
65
|
-
|
66
|
-
# does this match an InSpec resource?
|
67
|
-
if Inspec::RESOURCES.include?(cfn_res_type)
|
68
|
-
Iggy::Log.debug "CloudFormation.parse_generate cfn_res_type = #{cfn_res_type} MATCH"
|
69
|
-
# insert new control based off the resource's ID
|
70
|
-
generated_controls[cfn_res] = {}
|
71
|
-
generated_controls[cfn_res]["name"] = "#{cfn_res_type}::#{cfn_res}"
|
72
|
-
generated_controls[cfn_res]["title"] = "Iggy #{basename} #{cfn_res_type}::#{cfn_res}"
|
73
|
-
generated_controls[cfn_res]["desc"] = "#{cfn_res_type}::#{cfn_res} from the source file #{absolutename}\nGenerated by Iggy v#{Iggy::VERSION}"
|
74
|
-
generated_controls[cfn_res]["impact"] = "1.0"
|
75
|
-
generated_controls[cfn_res]["resource"] = cfn_res_type
|
76
|
-
generated_controls[cfn_res]["parameter"] = cfn_res
|
77
|
-
generated_controls[cfn_res]["tests"] = []
|
78
|
-
generated_controls[cfn_res]["tests"][0] = "it { should exist }"
|
79
|
-
|
80
|
-
# if there's a match, see if there are matching InSpec properties
|
81
|
-
inspec_properties = Iggy::Inspec.resource_properties(cfn_res_type)
|
82
|
-
|
83
|
-
cfn_resources[cfn_res]["Properties"].keys.each do |attr|
|
84
|
-
# insert '_' on the CamelCase to get camel_case
|
85
|
-
attr_split = attr.split /(?=[A-Z])/
|
86
|
-
property = attr_split.join("_").downcase
|
87
|
-
if inspec_properties.member?(property)
|
88
|
-
Iggy::Log.debug "CloudFormation.parse_generate #{cfn_res_type} inspec_property = #{property} MATCH"
|
89
|
-
value = cfn_resources[cfn_res]["Properties"][attr]
|
90
|
-
# skip the {"Ref"=>"VPC"} for now
|
91
|
-
generated_controls[cfn_res]["tests"].push("its('#{property}') { should cmp '#{value}' }") unless value.is_a? Hash
|
92
|
-
else
|
93
|
-
Iggy::Log.debug "CloudFormation.parse_generate #{cfn_res_type} inspec_property = #{property} SKIP"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
else
|
97
|
-
Iggy::Log.debug "CloudFormation.parse_generate cfn_res_type = #{cfn_res_type} SKIP"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
generated_controls
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
104
|
-
end
|
@@ -1,146 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Matt Ray (<matt@chef.io>)
|
3
|
-
#
|
4
|
-
# Copyright:: 2018, Chef Software, Inc <legal@chef.io>
|
5
|
-
#
|
6
|
-
|
7
|
-
require "inspec/objects/control"
|
8
|
-
require "inspec/objects/ruby_helper"
|
9
|
-
require "inspec/objects/describe"
|
10
|
-
|
11
|
-
require "inspec-iggy/inspec_helper"
|
12
|
-
|
13
|
-
module Iggy
|
14
|
-
class Terraform
|
15
|
-
|
16
|
-
# makes it easier to change out later
|
17
|
-
TAG_NAME = "iggy_name_"
|
18
|
-
TAG_URL = "iggy_url_"
|
19
|
-
|
20
|
-
# boilerplate tfstate parsing
|
21
|
-
def self.parse_tfstate(file)
|
22
|
-
Inspec::Log.debug "Iggy::Terraform.parse_tfstate file = #{file}"
|
23
|
-
begin
|
24
|
-
unless File.file?(file)
|
25
|
-
STDERR.puts "ERROR: #{file} is an invalid file, please check your path."
|
26
|
-
exit(-1)
|
27
|
-
end
|
28
|
-
tfstate = JSON.parse(File.read(file))
|
29
|
-
rescue JSON::ParserError => e
|
30
|
-
STDERR.puts e.message
|
31
|
-
STDERR.puts "ERROR: Parsing error in #{file}."
|
32
|
-
exit(-1)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# parse through the JSON for the tagged Resources
|
37
|
-
def self.parse_extract(file)
|
38
|
-
tfstate = parse_tfstate(file)
|
39
|
-
# InSpec profiles extracted
|
40
|
-
extracted_profiles = {}
|
41
|
-
|
42
|
-
# iterate over the resources
|
43
|
-
tf_resources = tfstate["modules"][0]["resources"]
|
44
|
-
tf_resources.keys.each do |tf_res|
|
45
|
-
tf_res_id = tf_resources[tf_res]["primary"]["id"]
|
46
|
-
|
47
|
-
# get the attributes, see if any of them have a tagged profile attached
|
48
|
-
tf_resources[tf_res]["primary"]["attributes"].keys.each do |attr|
|
49
|
-
next unless attr.start_with?("tags." + TAG_NAME)
|
50
|
-
Inspec::Log.debug "Iggy::Terraform.parse_extract tf_res = #{tf_res} attr = #{attr} MATCHED TAG"
|
51
|
-
# get the URL and the name of the profiles
|
52
|
-
name = attr.split(TAG_NAME)[1]
|
53
|
-
url = tf_resources[tf_res]["primary"]["attributes"]["tags.#{TAG_URL}#{name}"]
|
54
|
-
if tf_res.start_with?("aws_vpc") # should this be VPC or subnet?
|
55
|
-
# if it's a VPC, store it as the VPC id + name
|
56
|
-
key = tf_res_id + ":" + name
|
57
|
-
Inspec::Log.debug "Iggy::Terraform.parse_extract aws_vpc tagged with InSpec #{key}"
|
58
|
-
extracted_profiles[key] = {
|
59
|
-
"type" => "aws_vpc",
|
60
|
-
"az" => "us-west-2",
|
61
|
-
"url" => url,
|
62
|
-
}
|
63
|
-
elsif tf_res.start_with?("aws_instance")
|
64
|
-
# if it's a node, get information about the IP and SSH/WinRM
|
65
|
-
key = tf_res_id + ":" + name
|
66
|
-
Inspec::Log.debug "Iggy::Terraform.parse_extract aws_instance tagged with InSpec #{key}"
|
67
|
-
extracted_profiles[key] = {
|
68
|
-
"type" => "aws_instance",
|
69
|
-
"public_ip" => tf_resources[tf_res]["primary"]["attributes"]["public_ip"],
|
70
|
-
"key_name" => tf_resources[tf_res]["primary"]["attributes"]["key_name"],
|
71
|
-
"url" => url,
|
72
|
-
}
|
73
|
-
else
|
74
|
-
# should generic AWS just be the default except for instances?
|
75
|
-
STDERR.puts "ERROR: #{file} #{tf_res_id} has an InSpec-tagged resource but #{tf_res} is currently unsupported."
|
76
|
-
exit(-1)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
Inspec::Log.debug "Iggy::Terraform.parse_extract extracted_profiles = #{extracted_profiles}"
|
81
|
-
extracted_profiles
|
82
|
-
end
|
83
|
-
|
84
|
-
# parse through the JSON and generate InSpec controls
|
85
|
-
def self.parse_generate(file)
|
86
|
-
tfstate = parse_tfstate(file)
|
87
|
-
basename = File.basename(file)
|
88
|
-
absolutename = File.absolute_path(file)
|
89
|
-
|
90
|
-
# InSpec controls generated
|
91
|
-
generated_controls = []
|
92
|
-
|
93
|
-
# iterate over the resources
|
94
|
-
tf_resources = tfstate["modules"][0]["resources"]
|
95
|
-
tf_resources.keys.each do |tf_res|
|
96
|
-
tf_res_type = tf_resources[tf_res]["type"]
|
97
|
-
|
98
|
-
# add translation layer
|
99
|
-
if InspecHelper::TERRAFORM_RESOURCES.keys.include?(tf_res_type)
|
100
|
-
Inspec::Log.debug "Iggy::Terraform.parse_generate tf_res_type = #{tf_res_type} #{InspecHelper::TERRAFORM_RESOURCES[tf_res_type]} TRANSLATED"
|
101
|
-
tf_res_type = InspecHelper::TERRAFORM_RESOURCES[tf_res_type]
|
102
|
-
end
|
103
|
-
|
104
|
-
# does this match an InSpec resource?
|
105
|
-
if InspecHelper::RESOURCES.include?(tf_res_type)
|
106
|
-
Inspec::Log.debug "Iggy::Terraform.parse_generate tf_res_type = #{tf_res_type} MATCH"
|
107
|
-
tf_res_id = tf_resources[tf_res]["primary"]["id"]
|
108
|
-
|
109
|
-
# insert new control based off the resource's ID
|
110
|
-
ctrl = Inspec::Control.new
|
111
|
-
ctrl.id = "#{tf_res_type}::#{tf_res_id}"
|
112
|
-
ctrl.title = "Iggy #{basename} #{tf_res_type}::#{tf_res_id}"
|
113
|
-
ctrl.desc = "#{tf_res_type}::#{tf_res_id} from the source file #{absolutename}\nGenerated by Iggy v#{Iggy::VERSION}"
|
114
|
-
ctrl.impact = "1.0"
|
115
|
-
|
116
|
-
describe = Inspec::Describe.new
|
117
|
-
# describes the resourde with the id as argument
|
118
|
-
describe.qualifier.push([tf_res_type, tf_res_id])
|
119
|
-
|
120
|
-
# ensure the resource exists
|
121
|
-
describe.add_test(nil, "exist", nil)
|
122
|
-
|
123
|
-
# if there's a match, see if there are matching InSpec properties
|
124
|
-
inspec_properties = Iggy::InspecHelper.resource_properties(tf_res_type)
|
125
|
-
tf_resources[tf_res]["primary"]["attributes"].keys.each do |attr|
|
126
|
-
if inspec_properties.member?(attr)
|
127
|
-
Inspec::Log.debug "Iggy::Terraform.parse_generate #{tf_res_type} inspec_property = #{attr} MATCH"
|
128
|
-
value = tf_resources[tf_res]["primary"]["attributes"][attr]
|
129
|
-
describe.add_test(attr, "cmp", value)
|
130
|
-
else
|
131
|
-
Inspec::Log.debug "Iggy::Terraform.parse_generate #{tf_res_type} inspec_property = #{attr} SKIP"
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
ctrl.add_test(describe)
|
136
|
-
generated_controls.push(ctrl)
|
137
|
-
else
|
138
|
-
Inspec::Log.debug "Iggy::Terraform.parse_generate tf_res_type = #{tf_res_type} SKIP"
|
139
|
-
end
|
140
|
-
end
|
141
|
-
Inspec::Log.debug "Iggy::Terraform.parse_generate generated_controls = #{generated_controls}"
|
142
|
-
generated_controls
|
143
|
-
end
|
144
|
-
|
145
|
-
end
|
146
|
-
end
|
@@ -1,851 +0,0 @@
|
|
1
|
-
|
2
|
-
{
|
3
|
-
"AWSTemplateFormatVersion": "2010-09-09",
|
4
|
-
"Description": "BJC Chef Demo (4.5.4)",
|
5
|
-
"Parameters": {
|
6
|
-
"AvailabilityZone": {
|
7
|
-
"Description": "Availability Zone",
|
8
|
-
"Type": "String",
|
9
|
-
"Default": "us-west-2c"
|
10
|
-
},
|
11
|
-
"DemoName": {
|
12
|
-
"Description": "Name of the customer or organization",
|
13
|
-
"Type": "String",
|
14
|
-
"Default": "bjc-demo"
|
15
|
-
},
|
16
|
-
"Version": {
|
17
|
-
"Description": "Version",
|
18
|
-
"Type": "String",
|
19
|
-
"Default": "4.5.4"
|
20
|
-
},
|
21
|
-
"KeyName": {
|
22
|
-
"Description": "Name of an existing ec2 KeyPair to enable SSH access",
|
23
|
-
"Type": "AWS::EC2::KeyPair::KeyName",
|
24
|
-
"ConstraintDescription": "must be the name of an existing EC2 KeyPair."
|
25
|
-
},
|
26
|
-
"SSHLocation": {
|
27
|
-
"Description": "The IP address range that can be used to SSH to the EC2 instances",
|
28
|
-
"Type": "String",
|
29
|
-
"MinLength": "9",
|
30
|
-
"MaxLength": "18",
|
31
|
-
"Default": "0.0.0.0/0",
|
32
|
-
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
|
33
|
-
"ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
|
34
|
-
},
|
35
|
-
"TTL": {
|
36
|
-
"Description": "Time in hours for the demo to stay active. Default is 4, maximum is 720 hours (30 days).",
|
37
|
-
"Type": "Number",
|
38
|
-
"Default": 8,
|
39
|
-
"MinValue": 0,
|
40
|
-
"MaxValue": 720
|
41
|
-
},
|
42
|
-
"ChefServerAMI": {
|
43
|
-
"Type": "String",
|
44
|
-
"Default": "ami-3e6f1a46",
|
45
|
-
"Description": "AMI ID for the Chef Server"
|
46
|
-
},
|
47
|
-
"BuildNode1AMI": {
|
48
|
-
"Type": "String",
|
49
|
-
"Default": "ami-cb6f1ab3",
|
50
|
-
"Description": "AMI ID for Build Node 1"
|
51
|
-
},
|
52
|
-
"BuildNode2AMI": {
|
53
|
-
"Type": "String",
|
54
|
-
"Default": "ami-3c6d1844",
|
55
|
-
"Description": "AMI ID for Build Node 2"
|
56
|
-
},
|
57
|
-
"BuildNode3AMI": {
|
58
|
-
"Type": "String",
|
59
|
-
"Default": "ami-4b6f1a33",
|
60
|
-
"Description": "AMI ID for Build Node 3"
|
61
|
-
},
|
62
|
-
"deliveredAMI": {
|
63
|
-
"Type": "String",
|
64
|
-
"Default": "ami-676f1a1f",
|
65
|
-
"Description": "AMI ID for delivered"
|
66
|
-
},
|
67
|
-
"ecomacceptanceAMI": {
|
68
|
-
"Type": "String",
|
69
|
-
"Default": "ami-de6c19a6",
|
70
|
-
"Description": "AMI ID for ecomacceptance"
|
71
|
-
},
|
72
|
-
"rehearsalAMI": {
|
73
|
-
"Type": "String",
|
74
|
-
"Default": "ami-846c19fc",
|
75
|
-
"Description": "AMI ID for rehearsal"
|
76
|
-
},
|
77
|
-
"unionAMI": {
|
78
|
-
"Type": "String",
|
79
|
-
"Default": "ami-1f621767",
|
80
|
-
"Description": "AMI ID for union"
|
81
|
-
},
|
82
|
-
"WindowsWorkstation1AMI": {
|
83
|
-
"Type": "String",
|
84
|
-
"Default": "ami-ba6e1bc2",
|
85
|
-
"Description": "AMI ID for the Windows Workstation"
|
86
|
-
},
|
87
|
-
"AutomateAMI": {
|
88
|
-
"Type": "String",
|
89
|
-
"Default": "ami-7d6c1905",
|
90
|
-
"Description": "AMI ID for the Automate Server"
|
91
|
-
}
|
92
|
-
},
|
93
|
-
"Resources": {
|
94
|
-
"InstanceProfile" : {
|
95
|
-
"Type" : "AWS::IAM::InstanceProfile",
|
96
|
-
"Properties" : {
|
97
|
-
"Path" : "/",
|
98
|
-
"Roles" : ["chefDemo"]
|
99
|
-
}
|
100
|
-
},
|
101
|
-
"VPC": {
|
102
|
-
"Type": "AWS::EC2::VPC",
|
103
|
-
"Properties": {
|
104
|
-
"CidrBlock": "172.31.0.0/16",
|
105
|
-
"EnableDnsSupport": "true",
|
106
|
-
"EnableDnsHostnames": "true",
|
107
|
-
"Tags": [
|
108
|
-
{
|
109
|
-
"Key": "Application",
|
110
|
-
"Value": {
|
111
|
-
"Ref": "AWS::StackId"
|
112
|
-
},
|
113
|
-
"Key": "Name",
|
114
|
-
"Value": {
|
115
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "VPC" ] ]
|
116
|
-
}
|
117
|
-
}
|
118
|
-
]
|
119
|
-
}
|
120
|
-
},
|
121
|
-
"SubnetAutomate": {
|
122
|
-
"Type": "AWS::EC2::Subnet",
|
123
|
-
"Properties": {
|
124
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
125
|
-
"VpcId": {
|
126
|
-
"Ref": "VPC"
|
127
|
-
},
|
128
|
-
"CidrBlock": "172.31.54.0/24",
|
129
|
-
"Tags": [
|
130
|
-
{
|
131
|
-
"Key": "Application",
|
132
|
-
"Value": {
|
133
|
-
"Ref": "AWS::StackId"
|
134
|
-
},
|
135
|
-
"Key": "Name",
|
136
|
-
"Value": {
|
137
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "Automate Subnet" ] ]
|
138
|
-
}
|
139
|
-
}
|
140
|
-
]
|
141
|
-
}
|
142
|
-
},
|
143
|
-
"SubnetProd": {
|
144
|
-
"Type": "AWS::EC2::Subnet",
|
145
|
-
"Properties": {
|
146
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
147
|
-
"VpcId": {
|
148
|
-
"Ref": "VPC"
|
149
|
-
},
|
150
|
-
"CidrBlock": "172.31.62.0/24",
|
151
|
-
"Tags": [
|
152
|
-
{
|
153
|
-
"Key": "Application",
|
154
|
-
"Value": {
|
155
|
-
"Ref": "AWS::StackId"
|
156
|
-
},
|
157
|
-
"Key": "Name",
|
158
|
-
"Value": {
|
159
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "Prod Subnet" ] ]
|
160
|
-
}
|
161
|
-
}
|
162
|
-
]
|
163
|
-
}
|
164
|
-
},
|
165
|
-
"SubnetWorkstations": {
|
166
|
-
"Type": "AWS::EC2::Subnet",
|
167
|
-
"Properties": {
|
168
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
169
|
-
"VpcId": {
|
170
|
-
"Ref": "VPC"
|
171
|
-
},
|
172
|
-
"CidrBlock": "172.31.10.0/24",
|
173
|
-
"Tags": [
|
174
|
-
{
|
175
|
-
"Key": "Application",
|
176
|
-
"Value": {
|
177
|
-
"Ref": "AWS::StackId"
|
178
|
-
},
|
179
|
-
"Key": "Name",
|
180
|
-
"Value": {
|
181
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "Workstations Subnet" ] ]
|
182
|
-
}
|
183
|
-
}
|
184
|
-
]
|
185
|
-
}
|
186
|
-
},
|
187
|
-
"InternetGateway": {
|
188
|
-
"Type": "AWS::EC2::InternetGateway",
|
189
|
-
"Properties": {
|
190
|
-
"Tags": [
|
191
|
-
{
|
192
|
-
"Key": "Application",
|
193
|
-
"Value": {
|
194
|
-
"Ref": "AWS::StackId"
|
195
|
-
},
|
196
|
-
"Key": "Name",
|
197
|
-
"Value": {
|
198
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, " IG" ] ]
|
199
|
-
}
|
200
|
-
}
|
201
|
-
]
|
202
|
-
}
|
203
|
-
},
|
204
|
-
"AttachGateway": {
|
205
|
-
"Type": "AWS::EC2::VPCGatewayAttachment",
|
206
|
-
"Properties": {
|
207
|
-
"VpcId": {
|
208
|
-
"Ref": "VPC"
|
209
|
-
},
|
210
|
-
"InternetGatewayId": {
|
211
|
-
"Ref": "InternetGateway"
|
212
|
-
}
|
213
|
-
}
|
214
|
-
},
|
215
|
-
"RouteTable": {
|
216
|
-
"Type": "AWS::EC2::RouteTable",
|
217
|
-
"Properties": {
|
218
|
-
"VpcId": {
|
219
|
-
"Ref": "VPC"
|
220
|
-
},
|
221
|
-
"Tags": [
|
222
|
-
{
|
223
|
-
"Key": "Application",
|
224
|
-
"Value": {
|
225
|
-
"Ref": "AWS::StackId"
|
226
|
-
},
|
227
|
-
"Key": "Name",
|
228
|
-
"Value": {
|
229
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "Demo RouteTable" ] ]
|
230
|
-
}
|
231
|
-
}
|
232
|
-
]
|
233
|
-
}
|
234
|
-
},
|
235
|
-
"Route": {
|
236
|
-
"Type": "AWS::EC2::Route",
|
237
|
-
"DependsOn": "AttachGateway",
|
238
|
-
"Properties": {
|
239
|
-
"RouteTableId": {
|
240
|
-
"Ref": "RouteTable"
|
241
|
-
},
|
242
|
-
"DestinationCidrBlock": "0.0.0.0/0",
|
243
|
-
"GatewayId": {
|
244
|
-
"Ref": "InternetGateway"
|
245
|
-
}
|
246
|
-
}
|
247
|
-
},
|
248
|
-
"SubnetRouteTableAssociationAutomate": {
|
249
|
-
"Type": "AWS::EC2::SubnetRouteTableAssociation",
|
250
|
-
"Properties": {
|
251
|
-
"SubnetId": {
|
252
|
-
"Ref": "SubnetAutomate"
|
253
|
-
},
|
254
|
-
"RouteTableId": {
|
255
|
-
"Ref": "RouteTable"
|
256
|
-
}
|
257
|
-
}
|
258
|
-
},
|
259
|
-
"SubnetRouteTableAssociationProd": {
|
260
|
-
"Type": "AWS::EC2::SubnetRouteTableAssociation",
|
261
|
-
"Properties": {
|
262
|
-
"SubnetId": {
|
263
|
-
"Ref": "SubnetProd"
|
264
|
-
},
|
265
|
-
"RouteTableId": {
|
266
|
-
"Ref": "RouteTable"
|
267
|
-
}
|
268
|
-
}
|
269
|
-
},
|
270
|
-
"SubnetRouteTableAssociationWorkstations": {
|
271
|
-
"Type": "AWS::EC2::SubnetRouteTableAssociation",
|
272
|
-
"Properties": {
|
273
|
-
"SubnetId": {
|
274
|
-
"Ref": "SubnetWorkstations"
|
275
|
-
},
|
276
|
-
"RouteTableId": {
|
277
|
-
"Ref": "RouteTable"
|
278
|
-
}
|
279
|
-
}
|
280
|
-
},
|
281
|
-
"NetworkAcl": {
|
282
|
-
"Type": "AWS::EC2::NetworkAcl",
|
283
|
-
"Properties": {
|
284
|
-
"VpcId": {
|
285
|
-
"Ref": "VPC"
|
286
|
-
},
|
287
|
-
"Tags": [
|
288
|
-
{
|
289
|
-
"Key": "Application",
|
290
|
-
"Value": {
|
291
|
-
"Ref": "AWS::StackId"
|
292
|
-
},
|
293
|
-
"Key": "Name",
|
294
|
-
"Value": {
|
295
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "NetworkAcl" ] ]
|
296
|
-
}
|
297
|
-
}
|
298
|
-
]
|
299
|
-
}
|
300
|
-
},
|
301
|
-
"InboundNetworkAclEntry": {
|
302
|
-
"Type": "AWS::EC2::NetworkAclEntry",
|
303
|
-
"Properties": {
|
304
|
-
"NetworkAclId": {
|
305
|
-
"Ref": "NetworkAcl"
|
306
|
-
},
|
307
|
-
"RuleNumber": "100",
|
308
|
-
"Protocol": "-1",
|
309
|
-
"RuleAction": "allow",
|
310
|
-
"Egress": "false",
|
311
|
-
"CidrBlock": "0.0.0.0/0"
|
312
|
-
}
|
313
|
-
},
|
314
|
-
"OutBoundNetworkAclEntry": {
|
315
|
-
"Type": "AWS::EC2::NetworkAclEntry",
|
316
|
-
"Properties": {
|
317
|
-
"NetworkAclId": {
|
318
|
-
"Ref": "NetworkAcl"
|
319
|
-
},
|
320
|
-
"RuleNumber": "100",
|
321
|
-
"Protocol": "-1",
|
322
|
-
"RuleAction": "allow",
|
323
|
-
"Egress": "true",
|
324
|
-
"CidrBlock": "0.0.0.0/0"
|
325
|
-
}
|
326
|
-
},
|
327
|
-
"SubnetNetworkAclAssociationAutomate": {
|
328
|
-
"Type": "AWS::EC2::SubnetNetworkAclAssociation",
|
329
|
-
"Properties": {
|
330
|
-
"SubnetId": {
|
331
|
-
"Ref": "SubnetAutomate"
|
332
|
-
},
|
333
|
-
"NetworkAclId": {
|
334
|
-
"Ref": "NetworkAcl"
|
335
|
-
}
|
336
|
-
}
|
337
|
-
},
|
338
|
-
"SubnetNetworkAclAssociationProd": {
|
339
|
-
"Type": "AWS::EC2::SubnetNetworkAclAssociation",
|
340
|
-
"Properties": {
|
341
|
-
"SubnetId": {
|
342
|
-
"Ref": "SubnetProd"
|
343
|
-
},
|
344
|
-
"NetworkAclId": {
|
345
|
-
"Ref": "NetworkAcl"
|
346
|
-
}
|
347
|
-
}
|
348
|
-
},
|
349
|
-
"SubnetNetworkAclAssociationPOCWorkstations": {
|
350
|
-
"Type": "AWS::EC2::SubnetNetworkAclAssociation",
|
351
|
-
"Properties": {
|
352
|
-
"SubnetId": {
|
353
|
-
"Ref": "SubnetWorkstations"
|
354
|
-
},
|
355
|
-
"NetworkAclId": {
|
356
|
-
"Ref": "NetworkAcl"
|
357
|
-
}
|
358
|
-
}
|
359
|
-
},
|
360
|
-
"WindowsWorkstation1": {
|
361
|
-
"Type": "AWS::EC2::Instance",
|
362
|
-
"Properties": {
|
363
|
-
"InstanceType": "c4.large",
|
364
|
-
"EbsOptimized" : "true",
|
365
|
-
"IamInstanceProfile" : {"Ref" : "InstanceProfile"},
|
366
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
367
|
-
"NetworkInterfaces": [
|
368
|
-
{
|
369
|
-
"GroupSet": [
|
370
|
-
{
|
371
|
-
"Ref": "DemoSecurityGroup"
|
372
|
-
}
|
373
|
-
],
|
374
|
-
"AssociatePublicIpAddress": "true",
|
375
|
-
"PrivateIpAddress": "172.31.54.201",
|
376
|
-
"DeviceIndex": "0",
|
377
|
-
"DeleteOnTermination": "true",
|
378
|
-
"SubnetId": {
|
379
|
-
"Ref": "SubnetAutomate"
|
380
|
-
}
|
381
|
-
}
|
382
|
-
],
|
383
|
-
"KeyName": {
|
384
|
-
"Ref": "KeyName"
|
385
|
-
},
|
386
|
-
"UserData" : {
|
387
|
-
"Fn::Base64" : {
|
388
|
-
"Fn::Join" : [
|
389
|
-
"",
|
390
|
-
["<powershell>\n",
|
391
|
-
"set-executionpolicy -executionpolicy unrestricted -force -scope LocalMachine",
|
392
|
-
"</powershell>"
|
393
|
-
]
|
394
|
-
]
|
395
|
-
}
|
396
|
-
},
|
397
|
-
"ImageId": {
|
398
|
-
"Ref": "WindowsWorkstation1AMI"
|
399
|
-
},
|
400
|
-
"Tags": [
|
401
|
-
{
|
402
|
-
"Key": "Name",
|
403
|
-
"Value": {
|
404
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "Workstation" ] ]
|
405
|
-
}
|
406
|
-
}
|
407
|
-
]
|
408
|
-
}
|
409
|
-
},
|
410
|
-
"BuildNode1": {
|
411
|
-
"Type": "AWS::EC2::Instance",
|
412
|
-
"Properties": {
|
413
|
-
"InstanceType": "m4.large",
|
414
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
415
|
-
"NetworkInterfaces": [
|
416
|
-
{
|
417
|
-
"GroupSet": [
|
418
|
-
{
|
419
|
-
"Ref": "DemoSecurityGroup"
|
420
|
-
}
|
421
|
-
],
|
422
|
-
"AssociatePublicIpAddress": "true",
|
423
|
-
"PrivateIpAddress": "172.31.54.51",
|
424
|
-
"DeviceIndex": "0",
|
425
|
-
"DeleteOnTermination": "true",
|
426
|
-
"SubnetId": {
|
427
|
-
"Ref": "SubnetAutomate"
|
428
|
-
}
|
429
|
-
}
|
430
|
-
],
|
431
|
-
"KeyName": { "Ref": "KeyName" },
|
432
|
-
"UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
|
433
|
-
"#!/bin/bash -xe\n",
|
434
|
-
"hostnamectl set-hostname build-node-1\n",
|
435
|
-
"sleep 90\n",
|
436
|
-
"sudo chef-client\n"]]}
|
437
|
-
},
|
438
|
-
"ImageId": {
|
439
|
-
"Ref": "BuildNode1AMI"
|
440
|
-
},
|
441
|
-
"Tags": [
|
442
|
-
{
|
443
|
-
"Key": "Name",
|
444
|
-
"Value": {
|
445
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "Build Node 1" ] ]
|
446
|
-
}
|
447
|
-
}
|
448
|
-
]
|
449
|
-
}
|
450
|
-
},
|
451
|
-
"BuildNode2": {
|
452
|
-
"Type": "AWS::EC2::Instance",
|
453
|
-
"Properties": {
|
454
|
-
"InstanceType": "m4.large",
|
455
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
456
|
-
"NetworkInterfaces": [
|
457
|
-
{
|
458
|
-
"GroupSet": [
|
459
|
-
{
|
460
|
-
"Ref": "DemoSecurityGroup"
|
461
|
-
}
|
462
|
-
],
|
463
|
-
"AssociatePublicIpAddress": "true",
|
464
|
-
"PrivateIpAddress": "172.31.54.52",
|
465
|
-
"DeviceIndex": "0",
|
466
|
-
"DeleteOnTermination": "true",
|
467
|
-
"SubnetId": {
|
468
|
-
"Ref": "SubnetAutomate"
|
469
|
-
}
|
470
|
-
}
|
471
|
-
],
|
472
|
-
"KeyName": { "Ref": "KeyName" },
|
473
|
-
"UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
|
474
|
-
"#!/bin/bash -xe\n",
|
475
|
-
"hostnamectl set-hostname build-node-2\n",
|
476
|
-
"sleep 90\n",
|
477
|
-
"sudo chef-client\n"]]}
|
478
|
-
},
|
479
|
-
"ImageId": {
|
480
|
-
"Ref": "BuildNode2AMI"
|
481
|
-
},
|
482
|
-
"Tags": [
|
483
|
-
{
|
484
|
-
"Key": "Name",
|
485
|
-
"Value": {
|
486
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "Build Node 2" ] ]
|
487
|
-
}
|
488
|
-
}
|
489
|
-
]
|
490
|
-
}
|
491
|
-
},
|
492
|
-
"BuildNode3": {
|
493
|
-
"Type": "AWS::EC2::Instance",
|
494
|
-
"Properties": {
|
495
|
-
"InstanceType": "m4.large",
|
496
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
497
|
-
"NetworkInterfaces": [
|
498
|
-
{
|
499
|
-
"GroupSet": [
|
500
|
-
{
|
501
|
-
"Ref": "DemoSecurityGroup"
|
502
|
-
}
|
503
|
-
],
|
504
|
-
"AssociatePublicIpAddress": "true",
|
505
|
-
"PrivateIpAddress": "172.31.54.53",
|
506
|
-
"DeviceIndex": "0",
|
507
|
-
"DeleteOnTermination": "true",
|
508
|
-
"SubnetId": {
|
509
|
-
"Ref": "SubnetAutomate"
|
510
|
-
}
|
511
|
-
}
|
512
|
-
],
|
513
|
-
"KeyName": { "Ref": "KeyName" },
|
514
|
-
"UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
|
515
|
-
"#!/bin/bash -xe\n",
|
516
|
-
"hostnamectl set-hostname build-node-3\n",
|
517
|
-
"sleep 90\n",
|
518
|
-
"sudo chef-client\n"]]}
|
519
|
-
},
|
520
|
-
"ImageId": {
|
521
|
-
"Ref": "BuildNode3AMI"
|
522
|
-
},
|
523
|
-
"Tags": [
|
524
|
-
{
|
525
|
-
"Key": "Name",
|
526
|
-
"Value": {
|
527
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "Build Node 3" ] ]
|
528
|
-
}
|
529
|
-
}
|
530
|
-
]
|
531
|
-
}
|
532
|
-
},
|
533
|
-
"delivered": {
|
534
|
-
"Type": "AWS::EC2::Instance",
|
535
|
-
"Properties": {
|
536
|
-
"InstanceType": "m4.large",
|
537
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
538
|
-
"NetworkInterfaces": [
|
539
|
-
{
|
540
|
-
"GroupSet": [
|
541
|
-
{
|
542
|
-
"Ref": "DemoSecurityGroup"
|
543
|
-
}
|
544
|
-
],
|
545
|
-
"AssociatePublicIpAddress": "true",
|
546
|
-
"PrivateIpAddress": "172.31.54.101",
|
547
|
-
"DeviceIndex": "0",
|
548
|
-
"DeleteOnTermination": "true",
|
549
|
-
"SubnetId": {
|
550
|
-
"Ref": "SubnetAutomate"
|
551
|
-
}
|
552
|
-
}
|
553
|
-
],
|
554
|
-
"KeyName": { "Ref": "KeyName" },
|
555
|
-
"UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
|
556
|
-
"#!/bin/bash -xe\n",
|
557
|
-
"hostnamectl set-hostname delivered\n",
|
558
|
-
"sleep 90\n",
|
559
|
-
"sudo chef-client\n"
|
560
|
-
]]}
|
561
|
-
},
|
562
|
-
"ImageId": {
|
563
|
-
"Ref": "deliveredAMI"
|
564
|
-
},
|
565
|
-
"Tags": [
|
566
|
-
{
|
567
|
-
"Key": "Name",
|
568
|
-
"Value": {
|
569
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "delivered" ] ]
|
570
|
-
}
|
571
|
-
}
|
572
|
-
]
|
573
|
-
}
|
574
|
-
},
|
575
|
-
"ecomacceptance": {
|
576
|
-
"Type": "AWS::EC2::Instance",
|
577
|
-
"Properties": {
|
578
|
-
"InstanceType": "m4.large",
|
579
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
580
|
-
"NetworkInterfaces": [
|
581
|
-
{
|
582
|
-
"GroupSet": [
|
583
|
-
{
|
584
|
-
"Ref": "DemoSecurityGroup"
|
585
|
-
}
|
586
|
-
],
|
587
|
-
"AssociatePublicIpAddress": "true",
|
588
|
-
"PrivateIpAddress": "172.31.54.102",
|
589
|
-
"DeviceIndex": "0",
|
590
|
-
"DeleteOnTermination": "true",
|
591
|
-
"SubnetId": {
|
592
|
-
"Ref": "SubnetAutomate"
|
593
|
-
}
|
594
|
-
}
|
595
|
-
],
|
596
|
-
"KeyName": { "Ref": "KeyName" },
|
597
|
-
"UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
|
598
|
-
"#!/bin/bash -xe\n",
|
599
|
-
"hostnamectl set-hostname ecomacceptance\n",
|
600
|
-
"sleep 90\n",
|
601
|
-
"sudo chef-client\n"
|
602
|
-
]]}
|
603
|
-
},
|
604
|
-
"ImageId": {
|
605
|
-
"Ref": "ecomacceptanceAMI"
|
606
|
-
},
|
607
|
-
"Tags": [
|
608
|
-
{
|
609
|
-
"Key": "Name",
|
610
|
-
"Value": {
|
611
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "ecomacceptance" ] ]
|
612
|
-
}
|
613
|
-
}
|
614
|
-
]
|
615
|
-
}
|
616
|
-
},
|
617
|
-
"rehearsal": {
|
618
|
-
"Type": "AWS::EC2::Instance",
|
619
|
-
"Properties": {
|
620
|
-
"InstanceType": "m4.large",
|
621
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
622
|
-
"NetworkInterfaces": [
|
623
|
-
{
|
624
|
-
"GroupSet": [
|
625
|
-
{
|
626
|
-
"Ref": "DemoSecurityGroup"
|
627
|
-
}
|
628
|
-
],
|
629
|
-
"AssociatePublicIpAddress": "true",
|
630
|
-
"PrivateIpAddress": "172.31.54.103",
|
631
|
-
"DeviceIndex": "0",
|
632
|
-
"DeleteOnTermination": "true",
|
633
|
-
"SubnetId": {
|
634
|
-
"Ref": "SubnetAutomate"
|
635
|
-
}
|
636
|
-
}
|
637
|
-
],
|
638
|
-
"KeyName": { "Ref": "KeyName" },
|
639
|
-
"UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
|
640
|
-
"#!/bin/bash -xe\n",
|
641
|
-
"hostnamectl set-hostname rehearsal\n",
|
642
|
-
"sleep 90\n",
|
643
|
-
"sudo chef-client\n"
|
644
|
-
]]}
|
645
|
-
},
|
646
|
-
"ImageId": {
|
647
|
-
"Ref": "rehearsalAMI"
|
648
|
-
},
|
649
|
-
"Tags": [
|
650
|
-
{
|
651
|
-
"Key": "Name",
|
652
|
-
"Value": {
|
653
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "rehearsal" ] ]
|
654
|
-
}
|
655
|
-
}
|
656
|
-
]
|
657
|
-
}
|
658
|
-
},
|
659
|
-
"union": {
|
660
|
-
"Type": "AWS::EC2::Instance",
|
661
|
-
"Properties": {
|
662
|
-
"InstanceType": "m4.large",
|
663
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
664
|
-
"NetworkInterfaces": [
|
665
|
-
{
|
666
|
-
"GroupSet": [
|
667
|
-
{
|
668
|
-
"Ref": "DemoSecurityGroup"
|
669
|
-
}
|
670
|
-
],
|
671
|
-
"AssociatePublicIpAddress": "true",
|
672
|
-
"PrivateIpAddress": "172.31.54.104",
|
673
|
-
"DeviceIndex": "0",
|
674
|
-
"DeleteOnTermination": "true",
|
675
|
-
"SubnetId": {
|
676
|
-
"Ref": "SubnetAutomate"
|
677
|
-
}
|
678
|
-
}
|
679
|
-
],
|
680
|
-
"KeyName": { "Ref": "KeyName" },
|
681
|
-
"UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
|
682
|
-
"#!/bin/bash -xe\n",
|
683
|
-
"hostnamectl set-hostname union\n",
|
684
|
-
"sleep 90\n",
|
685
|
-
"sudo chef-client\n"
|
686
|
-
]]}
|
687
|
-
},
|
688
|
-
"ImageId": {
|
689
|
-
"Ref": "unionAMI"
|
690
|
-
},
|
691
|
-
"Tags": [
|
692
|
-
{
|
693
|
-
"Key": "Name",
|
694
|
-
"Value": {
|
695
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "union" ] ]
|
696
|
-
}
|
697
|
-
}
|
698
|
-
]
|
699
|
-
}
|
700
|
-
},
|
701
|
-
"Chef": {
|
702
|
-
"Type": "AWS::EC2::Instance",
|
703
|
-
"Properties": {
|
704
|
-
"InstanceType": "c4.xlarge",
|
705
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
706
|
-
"BlockDeviceMappings" : [
|
707
|
-
{
|
708
|
-
"DeviceName" : "/dev/sda1",
|
709
|
-
"Ebs" : { "VolumeSize" : "50" }
|
710
|
-
}
|
711
|
-
],
|
712
|
-
"NetworkInterfaces": [
|
713
|
-
{
|
714
|
-
"GroupSet": [
|
715
|
-
{
|
716
|
-
"Ref": "DemoSecurityGroup"
|
717
|
-
}
|
718
|
-
],
|
719
|
-
"AssociatePublicIpAddress": "true",
|
720
|
-
"PrivateIpAddress": "172.31.54.10",
|
721
|
-
"DeviceIndex": "0",
|
722
|
-
"DeleteOnTermination": "true",
|
723
|
-
"SubnetId": {
|
724
|
-
"Ref": "SubnetAutomate"
|
725
|
-
}
|
726
|
-
}
|
727
|
-
],
|
728
|
-
"KeyName": { "Ref": "KeyName" },
|
729
|
-
"UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
|
730
|
-
"#!/bin/bash -xe\n",
|
731
|
-
"hostnamectl set-hostname chef\n",
|
732
|
-
"chef-server-ctl reconfigure\n"]]}
|
733
|
-
},
|
734
|
-
"ImageId": {
|
735
|
-
"Ref": "ChefServerAMI"
|
736
|
-
},
|
737
|
-
"Tags": [
|
738
|
-
{
|
739
|
-
"Key": "Name",
|
740
|
-
"Value": {
|
741
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "Chef Server" ] ]
|
742
|
-
}
|
743
|
-
}
|
744
|
-
]
|
745
|
-
}
|
746
|
-
},
|
747
|
-
"Automate": {
|
748
|
-
"Type": "AWS::EC2::Instance",
|
749
|
-
"Properties": {
|
750
|
-
"InstanceType": "c4.xlarge",
|
751
|
-
"AvailabilityZone": { "Ref": "AvailabilityZone" },
|
752
|
-
"BlockDeviceMappings" : [
|
753
|
-
{
|
754
|
-
"DeviceName" : "/dev/sda1",
|
755
|
-
"Ebs" : { "VolumeSize" : "50" }
|
756
|
-
}
|
757
|
-
] ,
|
758
|
-
"NetworkInterfaces": [
|
759
|
-
{
|
760
|
-
"GroupSet": [
|
761
|
-
{
|
762
|
-
"Ref": "DemoSecurityGroup"
|
763
|
-
}
|
764
|
-
],
|
765
|
-
"AssociatePublicIpAddress": "true",
|
766
|
-
"PrivateIpAddress": "172.31.54.11",
|
767
|
-
"DeviceIndex": "0",
|
768
|
-
"DeleteOnTermination": "true",
|
769
|
-
"SubnetId": {
|
770
|
-
"Ref": "SubnetAutomate"
|
771
|
-
}
|
772
|
-
}
|
773
|
-
],
|
774
|
-
"KeyName": { "Ref": "KeyName" },
|
775
|
-
"UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
|
776
|
-
"#!/bin/bash -xe\n",
|
777
|
-
"hostnamectl set-hostname automate\n",
|
778
|
-
"delivery-ctl reconfigure\n"]]}
|
779
|
-
},
|
780
|
-
"ImageId": {
|
781
|
-
"Ref": "AutomateAMI"
|
782
|
-
},
|
783
|
-
"Tags": [
|
784
|
-
{
|
785
|
-
"Key": "Name",
|
786
|
-
"Value": {
|
787
|
-
"Fn::Join" : [ " ", [ { "Ref": "DemoName" }, "Automate Server" ] ]
|
788
|
-
}
|
789
|
-
}
|
790
|
-
]
|
791
|
-
}
|
792
|
-
},
|
793
|
-
"DemoSecurityGroup": {
|
794
|
-
"Type": "AWS::EC2::SecurityGroup",
|
795
|
-
"Properties": {
|
796
|
-
"VpcId": {
|
797
|
-
"Ref": "VPC"
|
798
|
-
},
|
799
|
-
"GroupDescription": "Enable required ports for Chef Server",
|
800
|
-
"SecurityGroupIngress": [
|
801
|
-
{
|
802
|
-
"IpProtocol": "tcp",
|
803
|
-
"FromPort": "22",
|
804
|
-
"ToPort": "22",
|
805
|
-
"CidrIp": {
|
806
|
-
"Ref": "SSHLocation"
|
807
|
-
}
|
808
|
-
},
|
809
|
-
{
|
810
|
-
"IpProtocol": "tcp",
|
811
|
-
"FromPort": "0",
|
812
|
-
"ToPort": "65535",
|
813
|
-
"CidrIp": "172.31.0.0/16"
|
814
|
-
},
|
815
|
-
{
|
816
|
-
"IpProtocol": "tcp",
|
817
|
-
"FromPort": "3389",
|
818
|
-
"ToPort": "3389",
|
819
|
-
"CidrIp": "0.0.0.0/0"
|
820
|
-
},
|
821
|
-
{
|
822
|
-
"IpProtocol": "tcp",
|
823
|
-
"FromPort": "443",
|
824
|
-
"ToPort": "443",
|
825
|
-
"CidrIp": "0.0.0.0/0"
|
826
|
-
},
|
827
|
-
{
|
828
|
-
"IpProtocol": "icmp",
|
829
|
-
"FromPort": "8",
|
830
|
-
"ToPort": "-1",
|
831
|
-
"CidrIp": "0.0.0.0/0"
|
832
|
-
},
|
833
|
-
{
|
834
|
-
"IpProtocol": "udp",
|
835
|
-
"FromPort": "3389",
|
836
|
-
"ToPort": "3389",
|
837
|
-
"CidrIp": "0.0.0.0/0"
|
838
|
-
},
|
839
|
-
{
|
840
|
-
"IpProtocol": "tcp",
|
841
|
-
"FromPort": "5985",
|
842
|
-
"ToPort": "5985",
|
843
|
-
"CidrIp": "0.0.0.0/0"
|
844
|
-
}
|
845
|
-
]
|
846
|
-
}
|
847
|
-
}
|
848
|
-
},
|
849
|
-
"Outputs":
|
850
|
-
{"WindowsWorkstation1PubDNS":{"Description":"Public IP address of the Windows Workstation","Value":{"Fn::GetAtt":["WindowsWorkstation1","PublicIp"]}}}
|
851
|
-
}
|