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.
@@ -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?("com.amazonaws")
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 { |arn|
46
+ target_groups = endpoint_service.network_load_balancer_arns.map do |arn|
49
47
  aws.target_groups_by_lb(arn)
50
- }.flatten
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
- source = { vpc: options[:source], name: name }
57
- else
58
- source = options[:source]
59
- end
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 "You need to pass either a service_name or source option to create an endpoint"
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
- name: "endpoint-#{ident}",
71
- description: "Describe the ingress and egress of the endpoint #{ident}",
72
- tags: options[:tags],
73
- vpc_id: vpc.id,
74
- }
75
-
76
- resource :aws_vpc_endpoint, ident, {
77
- vpc_id: vpc.id,
78
- service_name: service_name,
79
- vpc_endpoint_type: "Interface",
80
- security_group_ids: [ @security_group ],
81
- auto_accept: options[:auto_accept],
82
- subnet_ids: options[:subnets].map(&:id),
83
- private_dns_enabled: options[:private_dns],
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: "CNAME",
96
- resource_name: tf_safe("#{@name}-#{endpoint_service.fqdn}"),
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(service_name)
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 ! load_balancer or load_balancer.type != "network"
37
- raise "The load balancer needs to be a network load balancer"
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
- acceptance_required: options[:acceptance_required],
48
- allowed_principals: options[:allowed_principals],
49
- network_load_balancer_arns: [load_balancer.id],
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, "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({ service: self }))
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
- UNIT_REQUIRED_KEYS = [:name]
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 = <<EOF
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 { |var|
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 { |volume|
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: <<EOF
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
- ssh_group: "cloud",
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
- if ! options[:units].all? { |u| UNIT_REQUIRED_KEYS.all? { |key| u.has_key?(key) } }
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
- if ! options[:units].all? { |u| u.has_key?(:contents) || u.has_key?(:dropins) }
96
- raise "All units have to have contents and/or dropins"
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
- if ! options[:files].all? { |f| FILE_REQUIRED_KEYS.all? { |key| f.has_key?(key) } }
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__), "templates/ignition.yaml")
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(vpc, name)
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: "t2.micro",
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
- name: "instance-#{ident}",
50
- description: "Describe the ingress and egress of the instance #{ident}",
51
- tags: options[:tags],
52
- vpc_id: vpc.id,
53
- egress: [
54
- {
55
- from_port: 0,
56
- to_port: 0,
57
- protocol: -1,
58
- cidr_blocks: ["0.0.0.0/0"],
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.has_key? :ip_address
66
- lifecycle = {
67
- lifecycle: { create_before_destroy: false },
68
- }
69
- else
70
- lifecycle = {
71
- lifecycle: { create_before_destroy: true },
72
- }
73
- end
74
-
75
- if options.has_key? :subnet
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
- ami: options[:ami],
86
- instance_type: options[:instance_type],
87
- iam_instance_profile: profile_from(options[:instance_profile]),
88
- subnet_id: @subnet.id,
89
- associate_public_ip_address: options[:public],
90
- root_block_device: {
91
- volume_type: 'gp2',
92
- volume_size: 32,
93
- },
94
- tags: {
95
- 'Name' => ident,
96
- }.merge(options[:tags]),
97
- vpc_security_group_ids: [
98
- vpc.internal_ssh_security_group,
99
- ].push(*options[:security_groups]),
100
- user_data: options[:user_data],
101
- lifecycle: {
102
- create_before_destroy: true,
103
- },
104
- depends_on: options[:depends_on],
105
- }.merge(options[:ip_address] ? { private_ip: options[:ip_address] } : {}).merge(lifecycle)
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