Add has_roles to aws_ec2_instance (#90)

* Rename EC2-instance resources

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Add interim updates

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* testing for issue 82

Signed-off-by: Simon Varlow <simon.varlow@d2l.com>

* completed integration for EC2 roles

Signed-off-by: Simon Varlow <simon.varlow@d2l.com>

* adding in the beginning of the unit test for issue 82

Signed-off-by: Simon Varlow <simon.varlow@d2l.com>

* Fix unit tests

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Add has_roles? examples

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Remove redundant gsub

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* corrected OpenStruct format

Signed-off-by: Simon Varlow <simon.varlow@d2l.com>

* setting up variable for InstanceProfile

Signed-off-by: Simon Varlow <simon.varlow@d2l.com>

* Updated the unit test so all variables are at the top

Signed-off-by: Simon Varlow <simon.varlow@d2l.com>

* Fixed Rubocop issues that were detected

Signed-off-by: Simon Varlow <simon.varlow@d2l.com>

* Updating README.md to include changes to aws_ec2

Signed-off-by: Simon Varlow <simon.varlow@d2l.com>

* Add failing IT for has_roles?

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Add negative IT and fix uncovered issue

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Fix Rubocop issue

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Fix integration test

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Fix Rubocop issues and unit tests

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Pin AWS dependency to '~> 2'

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>
This commit is contained in:
Chris Redekop 2017-10-26 15:56:32 -04:00 committed by Dominik Richter
parent 1a31425e81
commit c8d4244ef4
6 changed files with 135 additions and 20 deletions

View file

@ -4,7 +4,7 @@ gem 'rake'
gem 'inspec', '~> 1'
gem 'rubocop', '~> 0.44.0'
gem 'highline', '~> 1.6.0'
gem 'aws-sdk'
gem 'aws-sdk', '~> 2'
gem 'nokogiri'
gem 'minitest', '5.10.1'

View file

@ -53,7 +53,7 @@ control "aws-1" do
impact 0.7
title 'Checks the machine is running'
describe aws_ec2('i-my-ec2-instance-id') do
describe aws_ec2_instance('my-ec2-machine') do
it { should be_running }
end
end
@ -61,7 +61,7 @@ end
### Available Resources
* `aws_ec2` - This resource reads information about an ec2 instance
* `aws_ec2_instance` - This resource reads information about an ec2 instance
* `aws_iam_access_key` - Verifies settings for AWS IAM access keys
* `aws_iam_password_policy` - Verifies iam password policy
* `aws_iam_root_user` - Verifies settings for AWS root account

View file

@ -1,5 +1,4 @@
# author: Christoph Hartmann
class AwsEc2Instance < Inspec.resource(1)
name 'aws_ec2_instance'
desc 'Verifies settings for an EC2 instance'
@ -7,10 +6,12 @@ class AwsEc2Instance < Inspec.resource(1)
example "
describe aws_ec2_instance('i-123456') do
it { should be_running }
it { should have_roles }
end
describe aws_ec2_instance(name: 'my-instance') do
it { should be_running }
it { should have_roles }
end
"
@ -19,6 +20,7 @@ class AwsEc2Instance < Inspec.resource(1)
@opts.is_a?(Hash) ? @display_name = @opts[:name] : @display_name = opts
@ec2_client = conn.ec2_client
@ec2_resource = conn.ec2_resource
@iam_resource = conn.iam_resource
end
def id
@ -86,6 +88,20 @@ class AwsEc2Instance < Inspec.resource(1)
"EC2 Instance #{@display_name}"
end
def has_roles?
instance_profile = instance.iam_instance_profile
if instance_profile
roles = @iam_resource.instance_profile(
instance_profile.arn.gsub(%r{^.*\/}, ''),
).roles
else
roles = nil
end
roles && !roles.empty?
end
private
def instance

View file

@ -4,12 +4,48 @@ terraform {
provider "aws" {}
resource "aws_iam_role" "example" {
name = "${terraform.env}.example"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_instance_profile" "example" {
name = "${terraform.env}.example"
role = "${aws_iam_role.example.name}"
}
resource "aws_instance" "example" {
ami = "ami-0d729a60"
instance_type = "t2.micro"
iam_instance_profile = "${aws_iam_instance_profile.example.name}"
tags {
Name = "${terraform.env}.Example"
X-Project = "inspec"
}
}
resource "aws_instance" "no_roles_instance" {
ami = "ami-0d729a60"
instance_type = "t2.micro"
tags {
Name = "${terraform.env}.Example"
Name = "${terraform.env}.NoRoles"
X-Project = "inspec"
}
}
@ -56,3 +92,7 @@ output "example_ec2_name" {
output "example_ec2_id" {
value = "${aws_instance.example.id}"
}
output "no_roles_ec2_id" {
value = "${aws_instance.no_roles_instance.id}"
}

View file

@ -6,7 +6,12 @@ example_ec2_id = attribute(
example_ec2_name = attribute(
'example_ec2_name',
default: 'default.Example',
description: 'Name of exapmle ec2 instance')
description: 'Name of example ec2 instance')
no_roles_ec2_id = attribute(
'no_roles_ec2_id',
default: 'default.no_roles_ec2_id',
description: 'ID of no-roles ec2 instance')
describe aws_ec2_instance(name: example_ec2_name) do
it { should exist }
@ -18,21 +23,15 @@ describe aws_ec2_instance(example_ec2_id) do
it { should exist }
its('image_id') { should eq 'ami-0d729a60' }
its('instance_type') { should eq 't2.micro' }
it { should have_roles }
end
describe aws_ec2(name: example_ec2_name) do
describe aws_ec2_instance(no_roles_ec2_id) do
it { should exist }
its('image_id') { should eq 'ami-0d729a60' }
its('instance_type') { should eq 't2.micro' }
it { should_not have_roles }
end
describe aws_ec2(example_ec2_id) do
it { should exist }
its('image_id') { should eq 'ami-0d729a60' }
its('instance_type') { should eq 't2.micro' }
end
# must use a real EC2 instance name, as the SDK will first check to see if its well formed before sending requests
# must use a real EC2 instance name, as the SDK will first check to see if it's well formed before sending requests
describe aws_ec2_instance('i-06b4bc106e0d03dfd') do
it { should_not exist }
end

View file

@ -3,14 +3,18 @@ require 'aws_ec2_instance'
class TestEc2 < Minitest::Test
Id = 'instance-id'.freeze
InstanceProfile = 'instance-role'.freeze
Arn = 'arn:aws:iam::123456789012:instance-profile/instance-role'.freeze
def setup
@mock_conn = Minitest::Mock.new
@mock_client = Minitest::Mock.new
@mock_resource = Minitest::Mock.new
@mock_iam_resource = Minitest::Mock.new
@mock_conn.expect :ec2_client, @mock_client
@mock_conn.expect :ec2_resource, @mock_resource
@mock_conn.expect :iam_resource, @mock_iam_resource
end
def test_that_id_returns_id_directly_when_constructed_with_an_id
@ -29,10 +33,10 @@ class TestEc2 < Minitest::Test
mock_instance = Object.new
@mock_resource.expect :instance, mock_instance, [Id]
assert_same mock_instance, AwsEc2Instance.new(
Id,
@mock_conn,
).send(:instance)
assert_same(
mock_instance,
AwsEc2Instance.new(Id, @mock_conn).send(:instance),
)
end
def test_that_instance_returns_nil_when_instance_does_not_exist
@ -55,4 +59,60 @@ class TestEc2 < Minitest::Test
@mock_resource.expect :instance, mock_instance, [Id]
assert !AwsEc2Instance.new(Id, @mock_conn).exists?
end
def stub_iam_instance_profile
OpenStruct.new({ arn: Arn })
end
def stub_instance_profile(roles)
OpenStruct.new({ roles: roles })
end
def test_that_has_roles_returns_false_when_roles_is_empty
mock_instance = Minitest::Mock.new
mock_instance.expect :iam_instance_profile, stub_iam_instance_profile
@mock_resource.expect :instance, mock_instance, [Id]
mock_roles = Minitest::Mock.new
mock_roles.expect :empty?, true
@mock_iam_resource.expect(
:instance_profile,
stub_instance_profile(mock_roles),
[InstanceProfile],
)
refute AwsEc2Instance.new(Id, @mock_conn).has_roles?
end
def test_that_has_roles_returns_true_when_roles_is_not_empty
mock_instance = Minitest::Mock.new
mock_instance.expect :iam_instance_profile, stub_iam_instance_profile
@mock_resource.expect :instance, mock_instance, [Id]
mock_roles = Minitest::Mock.new
mock_roles.expect :empty?, false
@mock_iam_resource.expect(
:instance_profile,
stub_instance_profile(mock_roles),
[InstanceProfile],
)
assert AwsEc2Instance.new(Id, @mock_conn).has_roles?
end
def test_that_has_roles_returns_false_when_roles_does_not_exist
mock_instance = Minitest::Mock.new
mock_instance.expect :iam_instance_profile, stub_iam_instance_profile
@mock_resource.expect :instance, mock_instance, [Id]
@mock_iam_resource.expect(
:instance_profile,
stub_instance_profile(nil),
[InstanceProfile],
)
refute AwsEc2Instance.new(Id, @mock_conn).has_roles?
end
end