terrafying-components 1.11.15 → 1.11.16
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/lib/hash/merge_with_arrays.rb +2 -0
- data/lib/terrafying/components.rb +1 -0
- data/lib/terrafying/components/auditd.rb +7 -7
- data/lib/terrafying/components/ca.rb +17 -21
- data/lib/terrafying/components/dynamicset.rb +103 -116
- data/lib/terrafying/components/endpoint.rb +32 -41
- data/lib/terrafying/components/endpointservice.rb +15 -21
- data/lib/terrafying/components/ignition.rb +42 -49
- data/lib/terrafying/components/instance.rb +56 -55
- data/lib/terrafying/components/instanceprofile.rb +35 -44
- data/lib/terrafying/components/letsencrypt.rb +60 -71
- data/lib/terrafying/components/loadbalancer.rb +43 -43
- data/lib/terrafying/components/ports.rb +12 -11
- data/lib/terrafying/components/prometheus.rb +124 -95
- data/lib/terrafying/components/selfsignedca.rb +90 -104
- data/lib/terrafying/components/service.rb +41 -51
- data/lib/terrafying/components/staticset.rb +58 -68
- data/lib/terrafying/components/subnet.rb +21 -31
- data/lib/terrafying/components/templates/ignition.yaml +26 -5
- data/lib/terrafying/components/usable.rb +78 -92
- data/lib/terrafying/components/version.rb +3 -1
- data/lib/terrafying/components/vpc.rb +181 -209
- data/lib/terrafying/components/vpn.rb +136 -156
- data/lib/terrafying/components/zone.rb +38 -48
- metadata +6 -6
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
require 'terrafying/components/loadbalancer'
|
3
4
|
require 'terrafying/components/usable'
|
@@ -5,16 +6,13 @@ require 'terrafying/components/vpc'
|
|
5
6
|
require 'terrafying/generator'
|
6
7
|
|
7
8
|
module Terrafying
|
8
|
-
|
9
9
|
module Components
|
10
|
-
|
11
10
|
class Endpoint < Terrafying::Context
|
12
|
-
|
13
11
|
attr_reader :fqdn, :security_group
|
14
12
|
|
15
13
|
include Usable
|
16
14
|
|
17
|
-
def self.create_in(vpc, name, options={})
|
15
|
+
def self.create_in(vpc, name, options = {})
|
18
16
|
Endpoint.new.create_in(vpc, name, options)
|
19
17
|
end
|
20
18
|
|
@@ -22,12 +20,12 @@ module Terrafying
|
|
22
20
|
super
|
23
21
|
end
|
24
22
|
|
25
|
-
def create_in(vpc, name, options={})
|
23
|
+
def create_in(vpc, name, options = {})
|
26
24
|
options = {
|
27
25
|
auto_accept: true,
|
28
26
|
subnets: vpc.subnets.fetch(:private, []),
|
29
27
|
private_dns: false,
|
30
|
-
tags: {}
|
28
|
+
tags: {}
|
31
29
|
}.merge(options)
|
32
30
|
|
33
31
|
ident = "#{tf_safe(vpc.name)}-#{name}"
|
@@ -40,70 +38,63 @@ module Terrafying
|
|
40
38
|
elsif options[:service_name]
|
41
39
|
service_name = options[:service_name]
|
42
40
|
|
43
|
-
if options[:service_name].start_with?(
|
41
|
+
if options[:service_name].start_with?('com.amazonaws')
|
44
42
|
@ports = enrich_ports([443])
|
45
43
|
else
|
46
44
|
endpoint_service = aws.endpoint_service_by_name(options[:service_name])
|
47
45
|
|
48
|
-
target_groups = endpoint_service.network_load_balancer_arns.map
|
46
|
+
target_groups = endpoint_service.network_load_balancer_arns.map do |arn|
|
49
47
|
aws.target_groups_by_lb(arn)
|
50
|
-
|
48
|
+
end.flatten
|
51
49
|
|
52
50
|
@ports = enrich_ports(target_groups.map(&:port))
|
53
51
|
end
|
54
52
|
elsif options[:source]
|
55
|
-
if options[:source].is_a?(VPC)
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
source = if options[:source].is_a?(VPC)
|
54
|
+
{ vpc: options[:source], name: name }
|
55
|
+
else
|
56
|
+
options[:source]
|
57
|
+
end
|
60
58
|
|
61
59
|
lb = LoadBalancer.find_in(source[:vpc], source[:name])
|
62
60
|
|
63
61
|
@ports = lb.ports
|
64
62
|
service_name = aws.endpoint_service_by_lb_arn(lb.id).service_name
|
65
63
|
else
|
66
|
-
raise
|
64
|
+
raise 'You need to pass either a service_name or source option to create an endpoint'
|
67
65
|
end
|
68
66
|
|
69
|
-
@security_group = resource :aws_security_group, ident,
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
@fqdn = output_of(:aws_vpc_endpoint, ident, "dns_entry.0.dns_name")
|
67
|
+
@security_group = resource :aws_security_group, ident,
|
68
|
+
name: "endpoint-#{ident}",
|
69
|
+
description: "Describe the ingress and egress of the endpoint #{ident}",
|
70
|
+
tags: options[:tags],
|
71
|
+
vpc_id: vpc.id
|
72
|
+
|
73
|
+
resource :aws_vpc_endpoint, ident,
|
74
|
+
vpc_id: vpc.id,
|
75
|
+
service_name: service_name,
|
76
|
+
vpc_endpoint_type: 'Interface',
|
77
|
+
security_group_ids: [@security_group],
|
78
|
+
auto_accept: options[:auto_accept],
|
79
|
+
subnet_ids: options[:subnets].map(&:id),
|
80
|
+
private_dns_enabled: options[:private_dns]
|
81
|
+
|
82
|
+
@fqdn = output_of(:aws_vpc_endpoint, ident, 'dns_entry.0.dns_name')
|
87
83
|
|
88
84
|
if options[:service]
|
89
85
|
endpoint_service = options[:service]
|
90
86
|
|
91
|
-
record_name = endpoint_service.fqdn.gsub(/.#{endpoint_service.zone.fqdn}$/,
|
87
|
+
record_name = endpoint_service.fqdn.gsub(/.#{endpoint_service.zone.fqdn}$/, '')
|
92
88
|
|
93
89
|
private_zone = add! Zone.create(endpoint_service.zone.fqdn, vpc: vpc)
|
94
90
|
private_zone.add_record(
|
95
|
-
record_name, [@fqdn], type:
|
96
|
-
|
91
|
+
record_name, [@fqdn], type: 'CNAME',
|
92
|
+
resource_name: tf_safe("#{@name}-#{endpoint_service.fqdn}")
|
97
93
|
)
|
98
|
-
else
|
99
|
-
|
100
94
|
end
|
101
95
|
|
102
96
|
self
|
103
97
|
end
|
104
|
-
|
105
98
|
end
|
106
|
-
|
107
99
|
end
|
108
|
-
|
109
100
|
end
|
@@ -1,15 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
require 'terrafying/generator'
|
3
4
|
|
4
5
|
module Terrafying
|
5
|
-
|
6
6
|
module Components
|
7
|
-
|
8
7
|
class EndpointService < Terrafying::Context
|
9
|
-
|
10
8
|
attr_reader :name, :load_balancer, :service_name, :fqdn, :zone
|
11
9
|
|
12
|
-
def self.create_for(load_balancer, name, options={})
|
10
|
+
def self.create_for(load_balancer, name, options = {})
|
13
11
|
EndpointService.new.create_for(load_balancer, name, options)
|
14
12
|
end
|
15
13
|
|
@@ -21,20 +19,20 @@ module Terrafying
|
|
21
19
|
super
|
22
20
|
end
|
23
21
|
|
24
|
-
def find(
|
22
|
+
def find(_service_name)
|
25
23
|
raise 'unimplemented'
|
26
24
|
end
|
27
25
|
|
28
|
-
def create_for(load_balancer, name, options={})
|
26
|
+
def create_for(load_balancer, name, options = {})
|
29
27
|
options = {
|
30
28
|
acceptance_required: true,
|
31
29
|
allowed_principals: [
|
32
|
-
"arn:aws:iam::#{aws.account_id}:root"
|
33
|
-
]
|
30
|
+
"arn:aws:iam::#{aws.account_id}:root"
|
31
|
+
]
|
34
32
|
}.merge(options)
|
35
33
|
|
36
|
-
if !
|
37
|
-
raise
|
34
|
+
if !load_balancer || (load_balancer.type != 'network')
|
35
|
+
raise 'The load balancer needs to be a network load balancer'
|
38
36
|
end
|
39
37
|
|
40
38
|
@name = name
|
@@ -43,24 +41,20 @@ module Terrafying
|
|
43
41
|
@fqdn = options[:fqdn]
|
44
42
|
@zone = options[:zone]
|
45
43
|
|
46
|
-
resource :aws_vpc_endpoint_service, name,
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
}
|
44
|
+
resource :aws_vpc_endpoint_service, name,
|
45
|
+
acceptance_required: options[:acceptance_required],
|
46
|
+
allowed_principals: options[:allowed_principals],
|
47
|
+
network_load_balancer_arns: [load_balancer.id]
|
51
48
|
|
52
|
-
@service_name = output_of(:aws_vpc_endpoint_service, name,
|
49
|
+
@service_name = output_of(:aws_vpc_endpoint_service, name, 'service_name')
|
53
50
|
|
54
51
|
self
|
55
52
|
end
|
56
53
|
|
57
|
-
def expose_in(vpc, options={})
|
54
|
+
def expose_in(vpc, options = {})
|
58
55
|
name = options.fetch(:name, @name)
|
59
|
-
add! Endpoint.create_in(vpc, name, options.merge(
|
56
|
+
add! Endpoint.create_in(vpc, name, options.merge(service: self))
|
60
57
|
end
|
61
|
-
|
62
58
|
end
|
63
|
-
|
64
59
|
end
|
65
|
-
|
66
60
|
end
|
@@ -1,54 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'erb'
|
2
4
|
require 'ostruct'
|
3
5
|
|
4
6
|
module Terrafying
|
5
|
-
|
6
7
|
module Components
|
7
|
-
|
8
8
|
class Ignition
|
9
|
+
UNIT_REQUIRED_KEYS = [:name].freeze
|
10
|
+
FILE_REQUIRED_KEYS = %i[path mode contents].freeze
|
9
11
|
|
10
|
-
|
11
|
-
FILE_REQUIRED_KEYS = [:path, :mode, :contents]
|
12
|
-
|
13
|
-
def self.container_unit(name, image, options={})
|
12
|
+
def self.container_unit(name, image, options = {})
|
14
13
|
options = {
|
15
14
|
volumes: [],
|
16
15
|
environment_variables: [],
|
17
16
|
arguments: [],
|
18
17
|
require_units: [],
|
19
18
|
host_networking: false,
|
20
|
-
privileged: false
|
19
|
+
privileged: false
|
21
20
|
}.merge(options)
|
22
21
|
|
23
22
|
if options[:require_units].count > 0
|
24
|
-
require_units = options[:require_units].join(
|
25
|
-
require =
|
26
|
-
After=#{require_units}
|
27
|
-
Requires=#{require_units}
|
28
|
-
EOF
|
23
|
+
require_units = options[:require_units].join(' ')
|
24
|
+
require = <<~EOF
|
25
|
+
After=#{require_units}
|
26
|
+
Requires=#{require_units}
|
27
|
+
EOF
|
29
28
|
end
|
30
29
|
|
31
30
|
docker_options = []
|
32
31
|
|
33
32
|
if options[:environment_variables].count > 0
|
34
|
-
docker_options += options[:environment_variables].map
|
33
|
+
docker_options += options[:environment_variables].map do |var|
|
35
34
|
"-e #{var}"
|
36
|
-
|
35
|
+
end
|
37
36
|
end
|
38
37
|
|
39
38
|
if options[:volumes].count > 0
|
40
|
-
docker_options += options[:volumes].map
|
39
|
+
docker_options += options[:volumes].map do |volume|
|
41
40
|
"-v #{volume}"
|
42
|
-
|
41
|
+
end
|
43
42
|
end
|
44
43
|
|
45
|
-
if options[:host_networking]
|
46
|
-
docker_options << "--net=host"
|
47
|
-
end
|
44
|
+
docker_options << '--net=host' if options[:host_networking]
|
48
45
|
|
49
|
-
if options[:privileged]
|
50
|
-
docker_options << "--privileged"
|
51
|
-
end
|
46
|
+
docker_options << '--privileged' if options[:privileged]
|
52
47
|
|
53
48
|
docker_options_str = " \\\n" + docker_options.join(" \\\n")
|
54
49
|
|
@@ -58,60 +53,58 @@ EOF
|
|
58
53
|
|
59
54
|
{
|
60
55
|
name: "#{name}.service",
|
61
|
-
contents:
|
62
|
-
[Install]
|
63
|
-
WantedBy=multi-user.target
|
64
|
-
|
65
|
-
[Unit]
|
66
|
-
Description=#{name}
|
67
|
-
#{require}
|
68
|
-
|
69
|
-
[Service]
|
70
|
-
ExecStartPre=-/usr/bin/docker rm -f #{name}
|
71
|
-
ExecStart=/usr/bin/docker run --name #{name} #{docker_options_str} \
|
72
|
-
#{image} #{arguments}
|
73
|
-
Restart=always
|
74
|
-
RestartSec=30
|
75
|
-
|
76
|
-
EOF
|
56
|
+
contents: <<~EOF
|
57
|
+
[Install]
|
58
|
+
WantedBy=multi-user.target
|
59
|
+
|
60
|
+
[Unit]
|
61
|
+
Description=#{name}
|
62
|
+
#{require}
|
63
|
+
|
64
|
+
[Service]
|
65
|
+
ExecStartPre=-/usr/bin/docker rm -f #{name}
|
66
|
+
ExecStart=/usr/bin/docker run --name #{name} #{docker_options_str} \
|
67
|
+
#{image} #{arguments}
|
68
|
+
Restart=always
|
69
|
+
RestartSec=30
|
70
|
+
|
71
|
+
EOF
|
77
72
|
}
|
78
73
|
end
|
79
74
|
|
80
|
-
def self.generate(options={})
|
75
|
+
def self.generate(options = {})
|
81
76
|
options = {
|
82
77
|
keypairs: [],
|
83
78
|
volumes: [],
|
84
79
|
files: [],
|
85
80
|
units: [],
|
86
|
-
|
81
|
+
networkd_units: [],
|
82
|
+
ssh_group: 'cloud',
|
87
83
|
disable_update_engine: false,
|
88
|
-
region: Terrafying::Generator.aws.region
|
84
|
+
region: Terrafying::Generator.aws.region
|
89
85
|
}.merge(options)
|
90
86
|
|
91
|
-
|
87
|
+
unless options[:units].all? { |u| UNIT_REQUIRED_KEYS.all? { |key| u.key?(key) } }
|
92
88
|
raise "All units require the following keys: #{UNIT_REQUIRED_KEYS}"
|
93
89
|
end
|
94
90
|
|
95
|
-
|
96
|
-
raise
|
91
|
+
unless options[:units].all? { |u| u.key?(:contents) || u.key?(:dropins) || u.fetch(:enabled, true) == false || u.fetch(:mask, false) == true }
|
92
|
+
raise 'All enabled unmasked units have to have contents and/or dropins'
|
97
93
|
end
|
98
94
|
|
99
|
-
|
95
|
+
unless options[:files].all? { |f| FILE_REQUIRED_KEYS.all? { |key| f.key?(key) } }
|
100
96
|
raise "All files require the following keys: #{FILE_REQUIRED_KEYS}"
|
101
97
|
end
|
102
98
|
|
103
99
|
options[:cas] = options[:keypairs].map { |kp| kp[:ca] }.compact.sort.uniq
|
104
100
|
|
105
|
-
erb_path = File.join(File.dirname(__FILE__),
|
101
|
+
erb_path = File.join(File.dirname(__FILE__), 'templates/ignition.yaml')
|
106
102
|
erb = ERB.new(IO.read(erb_path))
|
107
103
|
|
108
104
|
yaml = erb.result(OpenStruct.new(options).instance_eval { binding })
|
109
105
|
|
110
106
|
Terrafying::Util.to_ignition(yaml)
|
111
107
|
end
|
112
|
-
|
113
108
|
end
|
114
|
-
|
115
109
|
end
|
116
|
-
|
117
110
|
end
|
@@ -1,19 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
require 'xxhash'
|
3
4
|
|
4
5
|
require 'terrafying/components/usable'
|
5
6
|
|
6
7
|
module Terrafying
|
7
|
-
|
8
8
|
module Components
|
9
|
-
|
10
9
|
class Instance < Terrafying::Context
|
11
|
-
|
12
10
|
attr_reader :id, :name, :ip_address, :subnet
|
13
11
|
|
14
12
|
include Usable
|
15
13
|
|
16
|
-
def self.create_in(vpc, name, options={})
|
14
|
+
def self.create_in(vpc, name, options = {})
|
17
15
|
Instance.new.create_in vpc, name, options
|
18
16
|
end
|
19
17
|
|
@@ -21,23 +19,24 @@ module Terrafying
|
|
21
19
|
Instance.new.find_in vpc, name
|
22
20
|
end
|
23
21
|
|
24
|
-
def initialize
|
22
|
+
def initialize
|
25
23
|
super
|
26
24
|
end
|
27
25
|
|
28
|
-
def find_in(
|
26
|
+
def find_in(_vpc, _name)
|
29
27
|
raise 'unimplemented'
|
30
28
|
end
|
31
29
|
|
32
|
-
def create_in(vpc, name, options={})
|
30
|
+
def create_in(vpc, name, options = {})
|
33
31
|
options = {
|
34
32
|
public: false,
|
35
|
-
instance_type:
|
33
|
+
instance_type: 't2.micro',
|
34
|
+
cpu_credits: 'unlimited',
|
36
35
|
instance_profile: nil,
|
37
36
|
ports: [],
|
38
37
|
tags: {},
|
39
38
|
security_groups: [],
|
40
|
-
depends_on: []
|
39
|
+
depends_on: []
|
41
40
|
}.merge(options)
|
42
41
|
|
43
42
|
ident = "#{tf_safe(vpc.name)}-#{name}"
|
@@ -45,34 +44,33 @@ module Terrafying
|
|
45
44
|
@name = name
|
46
45
|
@ports = enrich_ports(options[:ports])
|
47
46
|
|
48
|
-
@security_group = resource :aws_security_group, ident,
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
}
|
47
|
+
@security_group = resource :aws_security_group, ident,
|
48
|
+
name: "instance-#{ident}",
|
49
|
+
description: "Describe the ingress and egress of the instance #{ident}",
|
50
|
+
tags: options[:tags],
|
51
|
+
vpc_id: vpc.id,
|
52
|
+
egress: [
|
53
|
+
{
|
54
|
+
from_port: 0,
|
55
|
+
to_port: 0,
|
56
|
+
protocol: -1,
|
57
|
+
cidr_blocks: ['0.0.0.0/0']
|
58
|
+
}
|
59
|
+
]
|
62
60
|
|
63
61
|
path_mtu_setup!
|
64
62
|
|
65
|
-
if options.
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
if options.
|
63
|
+
lifecycle = if options.key? :ip_address
|
64
|
+
{
|
65
|
+
lifecycle: { create_before_destroy: false }
|
66
|
+
}
|
67
|
+
else
|
68
|
+
{
|
69
|
+
lifecycle: { create_before_destroy: true }
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
if options.key? :subnet
|
76
74
|
@subnet = options[:subnet]
|
77
75
|
else
|
78
76
|
subnets = options.fetch(:subnets, vpc.subnets[:private])
|
@@ -82,27 +80,30 @@ module Terrafying
|
|
82
80
|
end
|
83
81
|
|
84
82
|
@id = resource :aws_instance, ident, {
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
83
|
+
ami: options[:ami],
|
84
|
+
instance_type: options[:instance_type],
|
85
|
+
credit_specification: {
|
86
|
+
cpu_credits: options[:cpu_credits]
|
87
|
+
},
|
88
|
+
iam_instance_profile: profile_from(options[:instance_profile]),
|
89
|
+
subnet_id: @subnet.id,
|
90
|
+
associate_public_ip_address: options[:public],
|
91
|
+
root_block_device: {
|
92
|
+
volume_type: 'gp2',
|
93
|
+
volume_size: 32
|
94
|
+
},
|
95
|
+
tags: {
|
96
|
+
'Name' => ident
|
97
|
+
}.merge(options[:tags]),
|
98
|
+
vpc_security_group_ids: [
|
99
|
+
vpc.internal_ssh_security_group
|
100
|
+
].push(*options[:security_groups]),
|
101
|
+
user_data: options[:user_data],
|
102
|
+
lifecycle: {
|
103
|
+
create_before_destroy: true
|
104
|
+
},
|
105
|
+
depends_on: options[:depends_on]
|
106
|
+
}.merge(options[:ip_address] ? { private_ip: options[:ip_address] } : {}).merge(lifecycle)
|
106
107
|
|
107
108
|
@ip_address = output_of(:aws_instance, ident, options[:public] ? :public_ip : :private_ip)
|
108
109
|
|