mirror of
https://github.com/inspec/inspec
synced 2024-11-22 12:43:07 +00:00
Use terraform environments to avoid integration test collisions
* When running integration tests with Rakefile use terraform environment based on environment variable INSPEC_TERRAFORM_ENV ** If INSPEC_TERRAFORM_ENV is not provided, a random string will be used * Use terraform environment as a namespace for AWS artifacts * Use attribute file for inspec to be aware of the terraform environment used Signed-off-by: Miles Tjandrawidjaja <miles@tjandrawidjaja.com>
This commit is contained in:
parent
5581762c64
commit
69434fec48
6 changed files with 88 additions and 18 deletions
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -1,4 +1,8 @@
|
|||
.attribute.yml
|
||||
.bundle/
|
||||
.terraform/
|
||||
inspec.lock
|
||||
Gemfile.lock
|
||||
terraform.tfstate
|
||||
terraform.tfstate.backup
|
||||
terraform.tfstate*
|
||||
terraform.tfstate.backup
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ bundle exec rake test
|
|||
### Integration tests
|
||||
|
||||
To run the integration tests, please make sure all required environment variables like `AWS_ACCESS_KEY_ID`
|
||||
, `AWS_SECRET_ACCESS_KEY` and `AWS_DEFAULT_REGION` are set properly. (`AWS_DEFAULT_REGION` **must** be set to **us-east-1** when running the integration tests.) We use terraform to create the AWS setup and InSpec to verify the all aspects. Integration tests can be executed via:
|
||||
, `AWS_SECRET_ACCESS_KEY` and `AWS_DEFAULT_REGION` are set properly. (`AWS_DEFAULT_REGION` **must** be set to **us-east-1** when running the integration tests.) We use terraform to create the AWS setup and InSpec to verify the all aspects. If you want to use a specific terraform environment, set environment variable `INSPEC_TERRAFORM_ENV`. Integration tests can be executed via:
|
||||
|
||||
```
|
||||
bundle exec rake test:integration
|
||||
|
@ -105,9 +105,11 @@ bundle exec rake test:integration
|
|||
|
||||
This task sets up test AWS resources, runs the integration tests, and then cleans up the resources. To perform these tasks independently, please call them individually:
|
||||
|
||||
* `bundle exec rake test:configure_test_environment`
|
||||
* `bundle exec rake test:setup_integration_tests`
|
||||
* `bundle exec rake test:run_integration_tests`
|
||||
* `bundle exec rake test:cleanup_integration_tests`
|
||||
* `bundle exec rake test:destroy_test_environment`
|
||||
|
||||
## Kudos
|
||||
|
||||
|
|
30
Rakefile
30
Rakefile
|
@ -3,6 +3,7 @@
|
|||
|
||||
require 'rake/testtask'
|
||||
require 'rubocop/rake_task'
|
||||
require 'securerandom'
|
||||
|
||||
# Rubocop
|
||||
desc 'Run Rubocop lint checks'
|
||||
|
@ -25,23 +26,36 @@ task lint: [:rubocop]
|
|||
task default: [:lint, :test]
|
||||
|
||||
namespace :test do
|
||||
integration_dir = "test/integration"
|
||||
terraform_env = ENV['INSPEC_TERRAFORM_ENV'] || SecureRandom.urlsafe_base64(5)
|
||||
project_dir = File.dirname(__FILE__)
|
||||
attribute_file = File.join(project_dir, ".attribute.yml")
|
||||
integration_dir = File.join(project_dir, "test/integration")
|
||||
|
||||
# run inspec check to verify that the profile is properly configured
|
||||
task :check do
|
||||
dir = File.join(File.dirname(__FILE__))
|
||||
sh("bundle exec inspec check #{dir}")
|
||||
sh("bundle exec inspec check #{project_dir}")
|
||||
end
|
||||
|
||||
task :configure_test_environment do
|
||||
puts "----> Creating terraform environment"
|
||||
sh("cd #{integration_dir}/build/ && terraform env new #{terraform_env}")
|
||||
end
|
||||
|
||||
task :setup_integration_tests do
|
||||
puts "----> Setup"
|
||||
sh("cd #{integration_dir}/build/ && terraform plan")
|
||||
sh("cd #{integration_dir}/build/ && terraform apply")
|
||||
sh("cd #{integration_dir}/build/ && terraform output > #{attribute_file}")
|
||||
|
||||
raw_output = File.read(attribute_file)
|
||||
yaml_output = raw_output.gsub(" = ", " : ")
|
||||
File.open(attribute_file, "w") {|file| file.puts yaml_output}
|
||||
end
|
||||
|
||||
|
||||
task :run_integration_tests do
|
||||
puts "----> Run"
|
||||
sh("bundle exec inspec exec #{integration_dir}/verify")
|
||||
sh("bundle exec inspec exec #{integration_dir}/verify --attrs #{attribute_file}")
|
||||
end
|
||||
|
||||
task :cleanup_integration_tests do
|
||||
|
@ -49,10 +63,18 @@ namespace :test do
|
|||
sh("cd #{integration_dir}/build/ && terraform destroy -force")
|
||||
end
|
||||
|
||||
task :destroy_test_environment do
|
||||
puts "----> Destroying terraform environment"
|
||||
sh("cd #{integration_dir}/build/ && terraform env select default")
|
||||
sh("cd #{integration_dir}/build && terraform env delete #{terraform_env}")
|
||||
end
|
||||
|
||||
task :integration do
|
||||
Rake::Task["test:configure_test_environment"].execute
|
||||
Rake::Task["test:cleanup_integration_tests"].execute
|
||||
Rake::Task["test:setup_integration_tests"].execute
|
||||
Rake::Task["test:run_integration_tests"].execute
|
||||
Rake::Task["test:cleanup_integration_tests"].execute
|
||||
Rake::Task["test:destroy_test_environment"].execute
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,17 +5,17 @@ resource "aws_instance" "example" {
|
|||
instance_type = "t2.micro"
|
||||
|
||||
tags {
|
||||
Name = "Example"
|
||||
Name = "${terraform.env}.Example"
|
||||
X-Project = "inspec"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_iam_user" "mfa_not_enabled_user" {
|
||||
name = "mfa_not_enabled_user"
|
||||
name = "${terraform.env}.mfa_not_enabled_user"
|
||||
}
|
||||
|
||||
resource "aws_iam_user" "console_password_enabled_user" {
|
||||
name = "console_password_enabled_user"
|
||||
name = "${terraform.env}.console_password_enabled_user"
|
||||
force_destroy = true
|
||||
}
|
||||
|
||||
|
@ -23,3 +23,19 @@ resource "aws_iam_user_login_profile" "u" {
|
|||
user = "${aws_iam_user.console_password_enabled_user.name}"
|
||||
pgp_key = "${var.login_profile_pgp_key}"
|
||||
}
|
||||
|
||||
output "mfa_not_enabled_user" {
|
||||
value = "${aws_iam_user.mfa_not_enabled_user.name}"
|
||||
}
|
||||
|
||||
output "console_password_enabled_user" {
|
||||
value = "${aws_iam_user.console_password_enabled_user.name}"
|
||||
}
|
||||
|
||||
output "example_ec2_name" {
|
||||
value = "${aws_instance.example.tags.Name}"
|
||||
}
|
||||
|
||||
output "example_ec2_id" {
|
||||
value = "${aws_instance.example.id}"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,20 @@
|
|||
describe aws_ec2(name: 'Example') do
|
||||
example_ec2_id = attribute(
|
||||
'example_ec2_id',
|
||||
default: 'default.example_ec2_id',
|
||||
description: 'ID of example ec2 instance')
|
||||
|
||||
example_ec2_name = attribute(
|
||||
'example_ec2_name',
|
||||
default: 'default.Example',
|
||||
description: 'Name of exapmle ec2 instance')
|
||||
|
||||
describe aws_ec2(name: example_ec2_name) do
|
||||
it { should exist }
|
||||
its('image_id') { should eq 'ami-0d729a60' }
|
||||
its('instance_type') { should eq 't2.micro' }
|
||||
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' }
|
||||
|
|
|
@ -1,8 +1,18 @@
|
|||
describe aws_iam_user('mfa_not_enabled_user') do
|
||||
its('has_mfa_enabled?') { should be false }
|
||||
its('has_console_password?') { should be false }
|
||||
end
|
||||
|
||||
describe aws_iam_user('console_password_enabled_user') do
|
||||
its('has_console_password?') { should be true }
|
||||
mfa_not_enabled_user = attribute(
|
||||
'mfa_not_enabled_user',
|
||||
default: 'default.mfa_not_enabled_user',
|
||||
description: 'Name of IAM user mfa_not_enabled_user')
|
||||
|
||||
console_password_enabled_user = attribute(
|
||||
'console_password_enabled_user',
|
||||
default: 'default.console_password_enabled_user',
|
||||
description: 'Name of IAM user console_password_enabled_user')
|
||||
|
||||
describe aws_iam_user(mfa_not_enabled_user) do
|
||||
its('has_mfa_enabled?') { should be false }
|
||||
its('has_console_password?') { should be false }
|
||||
end
|
||||
|
||||
describe aws_iam_user(console_password_enabled_user) do
|
||||
its('has_console_password?') { should be true }
|
||||
end
|
Loading…
Reference in a new issue