terracop 0.1.1 → 0.2.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/.rubocop.yml +8 -0
- data/CHANGELOG.md +20 -1
- data/README.md +6 -5
- data/lib/terracop.rb +6 -1
- data/lib/terracop/cop/aws/bad_password_policy.rb +73 -0
- data/lib/terracop/cop/aws/ensure_propagated_tags.rb +60 -0
- data/lib/terracop/cop/aws/ensure_tags.rb +23 -5
- data/lib/terracop/cop/aws/fault_intolerant.rb +40 -0
- data/lib/terracop/cop/aws/{iam_role_policy.rb → iam_inline_policy.rb} +7 -5
- data/lib/terracop/cop/aws/iam_policy_attachment.rb +48 -0
- data/lib/terracop/cop/aws/prefer_launch_templates.rb +41 -0
- data/lib/terracop/plan_loader.rb +4 -1
- data/lib/terracop/runner.rb +25 -16
- data/lib/terracop/version.rb +1 -1
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fb344f85daa3aa3f6d3c3c4f0d436c0b4c0d4211e4fbc6ff3b19f44e1ea1148
|
4
|
+
data.tar.gz: 2bbff8adc3eeeedf696296e9ce90c4cbebe2ced06c781fe703f14477f8a58f93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b695431e3b74dd944dc60f5df9fb70ac88c9884c2a51397ef1ad59539359efabdfdd767302faf2be925d31e61cc2540558deea6e5870029287a424fc7607ac7
|
7
|
+
data.tar.gz: a5b1ef53d62e241551a38aaab925df92c3811355fd42a66075e56247d78c43f3162b356a06125b8d03a176538d1ba270cc652a4c3715f9837e0cb56b645b1e3f
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,7 +4,26 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
|
5
5
|
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
-
## 0.
|
7
|
+
## 0.2.0 (2019-12-28)
|
8
|
+
|
9
|
+
- New cops:
|
10
|
+
- Aws/BadPasswordPolicy
|
11
|
+
- Aws/EnsurePropagatedTags
|
12
|
+
- Aws/FaultIntolerant
|
13
|
+
- Aws/IamInlinePolicy
|
14
|
+
- Aws/IamPolicyAttachment
|
15
|
+
- Aws/PreferLaunchTemplates
|
16
|
+
- Deprecated cop: IamRolePolicy.
|
17
|
+
- Improve test coverage.
|
18
|
+
- Improve Aws/EnsureTags to handle weird resources.
|
19
|
+
- Ignore deletions when analyzing plans.
|
20
|
+
|
21
|
+
## 0.1.1 (2019-12-22)
|
22
|
+
|
23
|
+
- Exit with failure when offenses are found.
|
24
|
+
- Add `terracop` executable.
|
25
|
+
|
26
|
+
## 0.1.0 (2019-12-22)
|
8
27
|
|
9
28
|
- Initial release.
|
10
29
|
- Can load Terraform 0.12 state and plan files.
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# Terracop
|
2
2
|
|
3
|
-
Terracop is
|
4
|
-
parser and analyzer. Put it in a CI pipeline to analyze your
|
5
|
-
or run it on already applied states and see what could be
|
3
|
+
Terracop is an opinionated HashiCorp [Terraform](https://www.terraform.io/)
|
4
|
+
state / plan parser and analyzer. Put it in a CI pipeline to analyze your
|
5
|
+
Terraform plans or run it on already applied states and see what could be
|
6
|
+
improved.
|
6
7
|
|
7
8
|
The checks run by Terracop go anywhere from resource names guidelines to
|
8
9
|
identifying security holes in your configuration.
|
@@ -33,8 +34,8 @@ like this:
|
|
33
34
|
|
34
35
|
$ terracop --state path/to/state/file
|
35
36
|
|
36
|
-
Terracop can
|
37
|
-
|
37
|
+
Terracop can also parse terraform plan files, in order to report potential
|
38
|
+
issues before you apply the plan and persist the problem. Eg:
|
38
39
|
|
39
40
|
$ terraform plan -out tfplan
|
40
41
|
$ terracop --plan tfplan
|
data/lib/terracop.rb
CHANGED
@@ -3,12 +3,17 @@
|
|
3
3
|
require 'json'
|
4
4
|
require 'yaml'
|
5
5
|
|
6
|
+
require 'terracop/cop/aws/bad_password_policy'
|
6
7
|
require 'terracop/cop/aws/describe_security_group_rules'
|
8
|
+
require 'terracop/cop/aws/ensure_propagated_tags'
|
7
9
|
require 'terracop/cop/aws/ensure_tags'
|
8
|
-
require 'terracop/cop/aws/
|
10
|
+
require 'terracop/cop/aws/fault_intolerant'
|
11
|
+
require 'terracop/cop/aws/iam_inline_policy'
|
12
|
+
require 'terracop/cop/aws/iam_policy_attachment'
|
9
13
|
require 'terracop/cop/aws/open_egress'
|
10
14
|
require 'terracop/cop/aws/open_ingress'
|
11
15
|
require 'terracop/cop/aws/open_ssh'
|
16
|
+
require 'terracop/cop/aws/prefer_launch_templates'
|
12
17
|
require 'terracop/cop/aws/unrestricted_egress_ports'
|
13
18
|
require 'terracop/cop/aws/unrestricted_ingress_ports'
|
14
19
|
require 'terracop/cop/aws/wide_egress'
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'terracop/cop/base'
|
4
|
+
|
5
|
+
module Terracop
|
6
|
+
module Cop
|
7
|
+
module Aws
|
8
|
+
# This cop warns against a password policy that goes against industry
|
9
|
+
# best practices. Ideally the password policy should be strict enough
|
10
|
+
# to require the use of a password manager, and never expire passwords.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# # bad
|
14
|
+
# resource "aws_iam_account_password_policy" "policy" {
|
15
|
+
# minimum_password_length = 4
|
16
|
+
# require_lowercase_characters = true
|
17
|
+
# require_numbers = true
|
18
|
+
# allow_users_to_change_password = false
|
19
|
+
# max_password_age = 7
|
20
|
+
# }
|
21
|
+
#
|
22
|
+
# # good
|
23
|
+
# resource "aws_iam_account_password_policy" "policy" {
|
24
|
+
# minimum_password_length = 20
|
25
|
+
# require_lowercase_characters = true
|
26
|
+
# require_uppercase_characters = true
|
27
|
+
# require_numbers = true
|
28
|
+
# require_symbols = true
|
29
|
+
# allow_users_to_change_password = true
|
30
|
+
# }
|
31
|
+
class BadPasswordPolicy < Base
|
32
|
+
register
|
33
|
+
applies_to :aws_iam_account_password_policy
|
34
|
+
|
35
|
+
def check
|
36
|
+
check_length
|
37
|
+
check_characters
|
38
|
+
check_age
|
39
|
+
end
|
40
|
+
|
41
|
+
def check_length
|
42
|
+
length = attributes['minimum_password_length']
|
43
|
+
if length && length < 14
|
44
|
+
offense('Set the minimum password length policy to at least 14.')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def check_characters
|
49
|
+
if !attributes['require_uppercase_characters'] ||
|
50
|
+
!attributes['require_lowercase_characters']
|
51
|
+
offense('Require both lowercase and uppercase characters.')
|
52
|
+
end
|
53
|
+
|
54
|
+
unless attributes['require_numbers']
|
55
|
+
offense('Require numbers in passwords.')
|
56
|
+
end
|
57
|
+
|
58
|
+
unless attributes['require_symbols']
|
59
|
+
offense('Require symbols in passwords.')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def check_age
|
64
|
+
age = attributes['max_password_age']
|
65
|
+
if age && age < 90
|
66
|
+
offense('Expiring passwords is discouraged. If you really have ' \
|
67
|
+
'to, do not do it more than once every 3 months.')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'terracop/cop/base'
|
4
|
+
|
5
|
+
module Terracop
|
6
|
+
module Cop
|
7
|
+
module Aws
|
8
|
+
# This cop makes sure that EC2 instances launched by Autoscaling Groups
|
9
|
+
# also have tags. It is configured like the Aws/EnsureTags cop.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# resource "aws_asg" "asg" {
|
14
|
+
# tag {
|
15
|
+
# key = "Name"
|
16
|
+
# value = "asg"
|
17
|
+
# propagate_at_launch = false
|
18
|
+
# }
|
19
|
+
# }
|
20
|
+
#
|
21
|
+
# # good
|
22
|
+
# resource "aws_asg" "asg" {
|
23
|
+
# tag {
|
24
|
+
# key = "Name"
|
25
|
+
# value = "asg"
|
26
|
+
# propagate_at_launch = true
|
27
|
+
# }
|
28
|
+
# }
|
29
|
+
class EnsurePropagatedTags < Base
|
30
|
+
register
|
31
|
+
applies_to :aws_autoscaling_group
|
32
|
+
|
33
|
+
def check
|
34
|
+
if self.class.config['Required']
|
35
|
+
check_required(propagated_tags, self.class.config['Required'])
|
36
|
+
elsif propagated_tags.empty?
|
37
|
+
offense 'The EC2 instances launched by this Autoscaling group ' \
|
38
|
+
'will not have any tags.'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def propagated_tags
|
45
|
+
tags = attributes['tags'] || attributes['tag']
|
46
|
+
tags.select { |t| t['propagate_at_launch'] }
|
47
|
+
end
|
48
|
+
|
49
|
+
def check_required(tags, required_tags)
|
50
|
+
required_tags.each do |key|
|
51
|
+
unless tags.find { |t| t['key'] == key }
|
52
|
+
offense "Required tag \"#{key}\" is not propagated to EC2 " \
|
53
|
+
'instances launched by this Autoscaling Group.'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -27,24 +27,42 @@ module Terracop
|
|
27
27
|
register
|
28
28
|
|
29
29
|
def check
|
30
|
-
|
30
|
+
tags = tags_for(attributes)
|
31
|
+
return unless tags
|
31
32
|
|
32
33
|
if self.class.config['Required']
|
33
|
-
check_required(self.class.config['Required'])
|
34
|
-
elsif
|
34
|
+
check_required(tags, self.class.config['Required'])
|
35
|
+
elsif tags.empty?
|
35
36
|
offense 'Tag resources properly.'
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
39
40
|
private
|
40
41
|
|
41
|
-
def check_required(required_tags)
|
42
|
+
def check_required(tags, required_tags)
|
42
43
|
required_tags.each do |key|
|
43
|
-
unless
|
44
|
+
unless tag(tags, key)
|
44
45
|
offense "Required tag \"#{key}\" is missing on this resource."
|
45
46
|
end
|
46
47
|
end
|
47
48
|
end
|
49
|
+
|
50
|
+
def tags_for(attributes)
|
51
|
+
case type
|
52
|
+
when 'aws_autoscaling_group'
|
53
|
+
attributes['tags'] || attributes['tag']
|
54
|
+
else
|
55
|
+
attributes['tags']
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def tag(list, name)
|
60
|
+
if list.is_a?(Hash)
|
61
|
+
list[name]
|
62
|
+
else
|
63
|
+
list.find { |tag| tag['key'] == name }
|
64
|
+
end
|
65
|
+
end
|
48
66
|
end
|
49
67
|
end
|
50
68
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'terracop/cop/base'
|
4
|
+
|
5
|
+
module Terracop
|
6
|
+
module Cop
|
7
|
+
module Aws
|
8
|
+
# This cop checks for Autoscaling Groups that can only launch instances
|
9
|
+
# in a specific Availability Zone. This creates an availability risk,
|
10
|
+
# as if that AZ is lost, the ASG will not be able to launch instances
|
11
|
+
# anywhere else.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# # bad
|
15
|
+
# resource "aws_autoscaling_group" "asg" {
|
16
|
+
# vpc_zone_identifier = ["subnet-123"]
|
17
|
+
# }
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# resource "aws_autoscaling_group" "asg" {
|
21
|
+
# # Note that to pass this cop, the two subnets must live in
|
22
|
+
# # different AZs.
|
23
|
+
# vpc_zone_identifier = ["subnet-123", "subnet-456"]
|
24
|
+
# }
|
25
|
+
class FaultIntolerant < Base
|
26
|
+
register
|
27
|
+
applies_to :aws_autoscaling_group
|
28
|
+
|
29
|
+
MSG = 'This Autoscaling Group can launch instances in only one AZ ' \
|
30
|
+
'(%<az>s). This setup would not tolerate the loss of that AZ.'
|
31
|
+
|
32
|
+
def check
|
33
|
+
return unless attributes['availability_zones'].count < 2
|
34
|
+
|
35
|
+
offense(format(MSG, az: attributes['availability_zones'][0]))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -5,7 +5,7 @@ require 'terracop/cop/base'
|
|
5
5
|
module Terracop
|
6
6
|
module Cop
|
7
7
|
module Aws
|
8
|
-
# This cop warns against the use of inline role policies.
|
8
|
+
# This cop warns against the use of inline group/role/user policies.
|
9
9
|
# Inline policies tend to be copy/pasted, sometimes with minor changes
|
10
10
|
# and are not shown in the "Policies" tab of AWS IAM.
|
11
11
|
#
|
@@ -33,13 +33,15 @@ module Terracop
|
|
33
33
|
# role = aws_iam_role.role.name
|
34
34
|
# policy_arn = aws_iam_policy.policy.arn
|
35
35
|
# }
|
36
|
-
class
|
36
|
+
class IamInlinePolicy < Base
|
37
37
|
register
|
38
|
-
applies_to :aws_iam_role_policy
|
38
|
+
applies_to :aws_iam_group_policy, :aws_iam_role_policy,
|
39
|
+
:aws_iam_user_policy
|
39
40
|
|
40
41
|
def check
|
41
|
-
|
42
|
-
|
42
|
+
entity = type.scan(/aws_iam_(.+)_policy/).first.first
|
43
|
+
offense("Use aws_iam_#{entity}_policy_attachment instead of " \
|
44
|
+
"attaching inline policies with aws_iam_#{entity}_policy.")
|
43
45
|
end
|
44
46
|
end
|
45
47
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'terracop/cop/base'
|
4
|
+
|
5
|
+
module Terracop
|
6
|
+
module Cop
|
7
|
+
module Aws
|
8
|
+
# This cop warns against the use of an evil all encompassing
|
9
|
+
# aws_iam_policy_attachment.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# resource "aws_iam_policy_attachment" "attach" {
|
14
|
+
# name = "test-attachment"
|
15
|
+
# policy_arn = aws_iam_policy.policy.arn
|
16
|
+
# users = [aws_iam_user.user.name]
|
17
|
+
# roles = [aws_iam_role.role.name]
|
18
|
+
# groups = [aws_iam_group.group.name]
|
19
|
+
# }
|
20
|
+
#
|
21
|
+
# # good
|
22
|
+
# resource "aws_iam_role_policy_attachment" "attach" {
|
23
|
+
# role = aws_iam_role.role.name
|
24
|
+
# policy_arn = aws_iam_policy.policy.arn
|
25
|
+
# }
|
26
|
+
#
|
27
|
+
# resource "aws_iam_user_policy_attachment" "attach" {
|
28
|
+
# user = aws_iam_user.user.name
|
29
|
+
# policy_arn = aws_iam_policy.policy.arn
|
30
|
+
# }
|
31
|
+
#
|
32
|
+
# resource "aws_iam_group_policy_attachment" "attach" {
|
33
|
+
# group = aws_iam_group.user.name
|
34
|
+
# policy_arn = aws_iam_policy.policy.arn
|
35
|
+
# }
|
36
|
+
class IamPolicyAttachment < Base
|
37
|
+
register
|
38
|
+
applies_to :iam_policy_attachment
|
39
|
+
|
40
|
+
def check
|
41
|
+
offense('Use aws_iam_role_policy_attachment, ' \
|
42
|
+
'aws_iam_user_policy_attachment, or ' \
|
43
|
+
'aws_iam_group_policy_attachment instead.')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'terracop/cop/aws/security_group_rule_cop'
|
4
|
+
|
5
|
+
module Terracop
|
6
|
+
module Cop
|
7
|
+
module Aws
|
8
|
+
# This cop warns against an ingress rule from 0.0.0.0/0 on port 22 (SSH).
|
9
|
+
# That is a Very Bad Idea™.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# resource "aws_launch_configuration" "lc" {}
|
14
|
+
#
|
15
|
+
# resource "aws_autoscaling_group" "asg" {
|
16
|
+
# launch_configuration = aws_launch_configuration.lc.name
|
17
|
+
# }
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# resource "aws_launch_template" "tpl" {}
|
21
|
+
#
|
22
|
+
# resource "aws_autoscaling_group" "asg" {
|
23
|
+
# launch_template {
|
24
|
+
# id = aws_launch_template.tpl.id
|
25
|
+
# version = "$Latest"
|
26
|
+
# }
|
27
|
+
# }
|
28
|
+
class PreferLaunchTemplates < SecurityGroupRuleCop
|
29
|
+
register
|
30
|
+
applies_to :aws_launch_configuration, :aws_autoscaling_group
|
31
|
+
|
32
|
+
def check
|
33
|
+
if type == 'aws_launch_configuration' ||
|
34
|
+
attributes['launch_configuration']
|
35
|
+
offense('Prefer Launch Templates to Launch Configurations.')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/terracop/plan_loader.rb
CHANGED
@@ -9,7 +9,8 @@ module Terracop
|
|
9
9
|
plan = decode(file)
|
10
10
|
|
11
11
|
changed_resources = plan['resource_changes'].reject! do |resource|
|
12
|
-
resource['change']['actions'] == ['no-op']
|
12
|
+
resource['change']['actions'] == ['no-op'] ||
|
13
|
+
resource['change']['actions'] == ['delete']
|
13
14
|
end
|
14
15
|
|
15
16
|
restruct_resources(changed_resources)
|
@@ -17,12 +18,14 @@ module Terracop
|
|
17
18
|
|
18
19
|
private
|
19
20
|
|
21
|
+
# :nocov:
|
20
22
|
def decode(file)
|
21
23
|
JSON.parse(`terraform show -json #{file}`)
|
22
24
|
rescue JSON::ParserError
|
23
25
|
puts 'Terraform failed to decode the plan file.'
|
24
26
|
exit
|
25
27
|
end
|
28
|
+
# :nocov:
|
26
29
|
|
27
30
|
def restruct_resources(resources)
|
28
31
|
resources.map do |resource|
|
data/lib/terracop/runner.rb
CHANGED
@@ -3,50 +3,59 @@
|
|
3
3
|
module Terracop
|
4
4
|
# Executes Terracop on a given state file.
|
5
5
|
class Runner
|
6
|
-
attr_accessor :state
|
7
|
-
|
8
6
|
def initialize(type, file, formatter)
|
9
7
|
@formatter = Formatters.const_get(formatter.to_s.capitalize).new
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
else
|
14
|
-
load_state_from_terraform
|
15
|
-
end
|
9
|
+
@type = type
|
10
|
+
@file = file
|
16
11
|
end
|
17
12
|
|
18
13
|
def run
|
19
|
-
offenses =
|
14
|
+
offenses = state.map do |instance|
|
20
15
|
Terracop::Cop.run_for(
|
21
16
|
instance[:type], instance[:name],
|
22
17
|
instance[:index], instance[:attributes]
|
23
18
|
)
|
24
19
|
end
|
25
20
|
|
26
|
-
|
27
|
-
print @formatter.generate(by_res)
|
21
|
+
print formatted(offenses)
|
28
22
|
|
29
23
|
offenses.flatten.count
|
30
24
|
end
|
31
25
|
|
26
|
+
def state
|
27
|
+
@state ||= begin
|
28
|
+
if @file
|
29
|
+
load_state_from_file(@type, @file)
|
30
|
+
else
|
31
|
+
load_state_from_terraform
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
32
36
|
private
|
33
37
|
|
34
38
|
def load_state_from_file(type, file)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
39
|
+
if type == :plan
|
40
|
+
PlanLoader.load(file)
|
41
|
+
else
|
42
|
+
StateLoader.load(file)
|
43
|
+
end
|
40
44
|
end
|
41
45
|
|
42
46
|
# :nocov:
|
43
47
|
def load_state_from_terraform
|
44
|
-
|
48
|
+
StateLoader.load_from_text(`terraform state pull`)
|
45
49
|
rescue JSON::ParserError
|
46
50
|
puts 'Run terracop somewhere with a state file or pass it directly ' \
|
47
51
|
'with --state FILE'
|
48
52
|
exit
|
49
53
|
end
|
50
54
|
# :nocov:
|
55
|
+
|
56
|
+
def formatted(offenses)
|
57
|
+
by_res = offenses.flatten.group_by { |o| "#{o[:type]}.#{o[:name]}" }
|
58
|
+
@formatter.generate(by_res)
|
59
|
+
end
|
51
60
|
end
|
52
61
|
end
|
data/lib/terracop/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: terracop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Francesco Boffa
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-12-
|
11
|
+
date: 2019-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -148,12 +148,17 @@ files:
|
|
148
148
|
- default_config.yml
|
149
149
|
- exe/terracop
|
150
150
|
- lib/terracop.rb
|
151
|
+
- lib/terracop/cop/aws/bad_password_policy.rb
|
151
152
|
- lib/terracop/cop/aws/describe_security_group_rules.rb
|
153
|
+
- lib/terracop/cop/aws/ensure_propagated_tags.rb
|
152
154
|
- lib/terracop/cop/aws/ensure_tags.rb
|
153
|
-
- lib/terracop/cop/aws/
|
155
|
+
- lib/terracop/cop/aws/fault_intolerant.rb
|
156
|
+
- lib/terracop/cop/aws/iam_inline_policy.rb
|
157
|
+
- lib/terracop/cop/aws/iam_policy_attachment.rb
|
154
158
|
- lib/terracop/cop/aws/open_egress.rb
|
155
159
|
- lib/terracop/cop/aws/open_ingress.rb
|
156
160
|
- lib/terracop/cop/aws/open_ssh.rb
|
161
|
+
- lib/terracop/cop/aws/prefer_launch_templates.rb
|
157
162
|
- lib/terracop/cop/aws/security_group_rule_cop.rb
|
158
163
|
- lib/terracop/cop/aws/unrestricted_egress_ports.rb
|
159
164
|
- lib/terracop/cop/aws/unrestricted_ingress_ports.rb
|
@@ -194,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
199
|
- !ruby/object:Gem::Version
|
195
200
|
version: '0'
|
196
201
|
requirements: []
|
197
|
-
rubygems_version: 3.
|
202
|
+
rubygems_version: 3.1.2
|
198
203
|
signing_key:
|
199
204
|
specification_version: 4
|
200
205
|
summary: Automatic Terraform state/plan checking tool
|