From f2ed8d9c4de37c7f9d604046362db186289c185a Mon Sep 17 00:00:00 2001 From: Varun Sharma Date: Wed, 17 Nov 2021 11:21:06 +0530 Subject: [PATCH 1/4] Added support for AWS::EMR::SecurityConfiguration. Doc pending Signed-off-by: Varun Sharma --- libraries/aws_emr_security_configuration.rb | 47 +++++++ libraries/aws_emr_security_configurations.rb | 55 ++++++++ test/integration/build/outputs.tf | 8 ++ .../configuration/aws_inspec_config.rb | 1 + .../aws_emr_security_configuration.rb | 35 +++++ .../aws_emr_security_configurations.rb | 29 +++++ .../aws_emr_security_configuration_test.rb | 64 ++++++++++ .../aws_emr_security_configurations_test.rb | 40 ++++++ .../aws_emr_security_configuration_mock.rb | 120 ++++++++++++++++++ 9 files changed, 399 insertions(+) create mode 100644 libraries/aws_emr_security_configuration.rb create mode 100644 libraries/aws_emr_security_configurations.rb create mode 100644 test/integration/verify/controls/aws_emr_security_configuration.rb create mode 100644 test/integration/verify/controls/aws_emr_security_configurations.rb create mode 100644 test/unit/resources/aws_emr_security_configuration_test.rb create mode 100644 test/unit/resources/aws_emr_security_configurations_test.rb create mode 100644 test/unit/resources/mock/aws_emr_security_configuration_mock.rb diff --git a/libraries/aws_emr_security_configuration.rb b/libraries/aws_emr_security_configuration.rb new file mode 100644 index 000000000..1618b5698 --- /dev/null +++ b/libraries/aws_emr_security_configuration.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'aws_backend' +require 'json' + +class AwsEmrClusterSecurityConfiguration < AwsResourceBase + name 'aws_emr_security_configuration' + desc 'Verifies security configuration for an EMR cluster.' + + example " + describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do + its('encryption_at_rest') { should eq true } + its('encryption_in_transit') { should eq true } + its('local_disk_encryption') { should eq true } + end + " + + attr_reader :security_configuration_name, :encryption_at_rest, :encryption_in_transit, :local_disk_encryption + + def initialize(opts = {}) + opts = { security_configuration_name: opts } if opts.is_a?(String) + super(opts) + validate_parameters(required: %i(security_configuration_name)) + catch_aws_errors do + @security_configuration_name = opts[:security_configuration_name] + + resp = @aws.emr_client.describe_security_configuration({ name: @security_configuration_name }) + return if resp.nil? || resp.empty? + json_security_configuration = resp.security_configuration + return if json_security_configuration.nil? || json_security_configuration.empty? + parsed_json = JSON.parse(json_security_configuration) + @encryption_at_rest = !parsed_json['EncryptionConfiguration']['EnableAtRestEncryption'].nil? && parsed_json['EncryptionConfiguration']['EnableAtRestEncryption'] + @encryption_in_transit = !parsed_json['EncryptionConfiguration']['EnableInTransitEncryption'].nil? && parsed_json['EncryptionConfiguration']['EnableInTransitEncryption'] + @local_disk_encryption = !parsed_json['EncryptionConfiguration']['AtRestEncryptionConfiguration'].nil? && + !parsed_json['EncryptionConfiguration']['AtRestEncryptionConfiguration']['LocalDiskEncryptionConfiguration'].nil? && + !parsed_json['EncryptionConfiguration']['AtRestEncryptionConfiguration']['LocalDiskEncryptionConfiguration'].empty? + end + end + + def exists? + !@security_configuration_name.nil? && !@security_configuration_name.empty? + end + + def to_s + "AWS EMR Cluster Security Configuration Name: #{@security_configuration_name}" + end +end diff --git a/libraries/aws_emr_security_configurations.rb b/libraries/aws_emr_security_configurations.rb new file mode 100644 index 000000000..44c636b98 --- /dev/null +++ b/libraries/aws_emr_security_configurations.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require 'aws_backend' +require 'json' + +class AwsEmrClusterSecurityConfigurations < AwsResourceBase + name 'aws_emr_security_configurations' + desc 'Verifies collection of security configuration for an EMR cluster.' + example " + describe aws_emr_security_configurations do + it { should exist } + end + " + attr_reader :table + + FilterTable.create + .register_column(:security_configuration_names, field: :security_configuration_name) + .register_column(:encryption_at_rests, field: :encryption_at_rest) + .register_column(:encryption_in_transits, field: :encryption_in_transit) + .register_column(:local_disk_encryptions, field: :local_disk_encryption) + .install_filter_methods_on_resource(self, :table) + + def initialize(opts = {}) + super(opts) + validate_parameters + @table = fetch_data + end + + def fetch_data + security_configuration_rows = [] + pagination_options = {} + resp_security_configurations = {} + catch_aws_errors do + resp_security_configurations = @aws.emr_client.list_security_configurations(pagination_options) + end + + return security_configuration_rows if !resp_security_configurations || resp_security_configurations.empty? + + resp_security_configurations.security_configurations.each do |s| + resp_security_configuration = @aws.emr_client.describe_security_configuration({ name: s.name }) + parsed_json = JSON.parse(resp_security_configuration.security_configuration) + encryption_at_rest = !parsed_json['EncryptionConfiguration']['EnableAtRestEncryption'].nil? && parsed_json['EncryptionConfiguration']['EnableAtRestEncryption'] + encryption_in_transit = !parsed_json['EncryptionConfiguration']['EnableInTransitEncryption'].nil? && parsed_json['EncryptionConfiguration']['EnableInTransitEncryption'] + local_disk_encryption = !parsed_json['EncryptionConfiguration']['AtRestEncryptionConfiguration'].nil? && + !parsed_json['EncryptionConfiguration']['AtRestEncryptionConfiguration']['LocalDiskEncryptionConfiguration'].nil? && + !parsed_json['EncryptionConfiguration']['AtRestEncryptionConfiguration']['LocalDiskEncryptionConfiguration'].empty? + + security_configuration_rows += [{ security_configuration_name: s.name, + encryption_at_rest: encryption_at_rest, + encryption_in_transit: encryption_in_transit, + local_disk_encryption: local_disk_encryption }] + end + @table = security_configuration_rows + end +end diff --git a/test/integration/build/outputs.tf b/test/integration/build/outputs.tf index f74b896f3..f1dc2aee1 100644 --- a/test/integration/build/outputs.tf +++ b/test/integration/build/outputs.tf @@ -1075,4 +1075,12 @@ output "aws_cloudwatch_log_group_name" { output "aws_cloudwatch_log_stream_arn" { value = aws_cloudwatch_log_stream.for_test.arn +} + +output "aws_emr_security_configuration_name" { + value = aws_emr_security_configuration.emr_security_configuration.name +} + +output "aws_emr_security_configuration_json" { + value = aws_emr_security_configuration.emr_security_configuration.configuration } \ No newline at end of file diff --git a/test/integration/configuration/aws_inspec_config.rb b/test/integration/configuration/aws_inspec_config.rb index 2468725a0..72bd12c96 100644 --- a/test/integration/configuration/aws_inspec_config.rb +++ b/test/integration/configuration/aws_inspec_config.rb @@ -138,6 +138,7 @@ def self.region_parser(raw) aws_elb_access_log_name: "elb-log-name-#{add_random_string}", aws_elb_access_log_prefix: "elb-log-prefix-#{add_random_string}", aws_elb_name: "elb-#{add_random_string}", + aws_emr_security_configuration_name: "emr-sec-config-#{add_random_string}", aws_flow_log_bucket_name: "aws-flow-log-bucket-#{add_random_string}", aws_iam_user_name: "iam-user-#{add_random_string}", aws_iam_user_policy_name: "iam-user-policy-#{add_random_string}", diff --git a/test/integration/verify/controls/aws_emr_security_configuration.rb b/test/integration/verify/controls/aws_emr_security_configuration.rb new file mode 100644 index 000000000..3d8dc6b00 --- /dev/null +++ b/test/integration/verify/controls/aws_emr_security_configuration.rb @@ -0,0 +1,35 @@ +require 'json' + +aws_emr_security_configuration_name = attribute(:aws_emr_security_configuration_name, value: '', description: 'The Name of the EMR Security Configuration.') +aws_emr_security_configuration_name.gsub!('"', '') +aws_emr_security_configuration_json = attribute(:aws_emr_security_configuration_json, value: '', description: 'The JSON formatted Security Configuration.') +aws_emr_security_configuration_json.gsub!('EOT', '') +aws_emr_security_configuration_json.gsub!('<<', '') + +parsed_json = JSON.parse(aws_emr_security_configuration_json.strip) +encryption_at_rest = !parsed_json['EncryptionConfiguration']['EnableAtRestEncryption'].nil? && parsed_json['EncryptionConfiguration']['EnableAtRestEncryption'] +encryption_in_transit = !parsed_json['EncryptionConfiguration']['EnableInTransitEncryption'].nil? && parsed_json['EncryptionConfiguration']['EnableInTransitEncryption'] +local_disk_encryption = !parsed_json['EncryptionConfiguration']['AtRestEncryptionConfiguration'].nil? && + !parsed_json['EncryptionConfiguration']['AtRestEncryptionConfiguration']['LocalDiskEncryptionConfiguration'].nil? && + !parsed_json['EncryptionConfiguration']['AtRestEncryptionConfiguration']['LocalDiskEncryptionConfiguration'].empty? + +control 'aws-emr-security-configuration-1.0' do + impact 1.0 + title 'Test single AWS EMR Security Configuration' + + describe aws_emr_security_configuration(security_configuration_name: aws_emr_security_configuration_name) do + it { should exist } + end + + describe aws_emr_security_configuration(security_configuration_name: aws_emr_security_configuration_name) do + its('encryption_at_rest'){ should eq encryption_at_rest } + end + + describe aws_emr_security_configuration(security_configuration_name: aws_emr_security_configuration_name) do + its('encryption_in_transit'){ should eq encryption_in_transit } + end + + describe aws_emr_security_configuration(security_configuration_name: aws_emr_security_configuration_name) do + its('local_disk_encryption'){ should eq local_disk_encryption } + end +end \ No newline at end of file diff --git a/test/integration/verify/controls/aws_emr_security_configurations.rb b/test/integration/verify/controls/aws_emr_security_configurations.rb new file mode 100644 index 000000000..a7f6df01c --- /dev/null +++ b/test/integration/verify/controls/aws_emr_security_configurations.rb @@ -0,0 +1,29 @@ +require 'json' + +aws_emr_security_configuration_name = attribute(:aws_emr_security_configuration_name, value: '', description: 'The Name of the EMR Security Configuration.') +aws_emr_security_configuration_name.gsub!('"', '') +aws_emr_security_configuration_json = attribute(:aws_emr_security_configuration_json, value: '', description: 'The JSON formatted Security Configuration.') +aws_emr_security_configuration_json.gsub!('EOT', '') +aws_emr_security_configuration_json.gsub!('<<', '') +parsed_json = JSON.parse(aws_emr_security_configuration_json.strip) +encryption_at_rest = !parsed_json['EncryptionConfiguration']['EnableAtRestEncryption'].nil? && parsed_json['EncryptionConfiguration']['EnableAtRestEncryption'] +encryption_in_transit = !parsed_json['EncryptionConfiguration']['EnableInTransitEncryption'].nil? && parsed_json['EncryptionConfiguration']['EnableInTransitEncryption'] +local_disk_encryption = !parsed_json['EncryptionConfiguration']['AtRestEncryptionConfiguration'].nil? && + !parsed_json['EncryptionConfiguration']['AtRestEncryptionConfiguration']['LocalDiskEncryptionConfiguration'].nil? && + !parsed_json['EncryptionConfiguration']['AtRestEncryptionConfiguration']['LocalDiskEncryptionConfiguration'].empty? + +control 'aws-emr-security-configurations-1.0' do + impact 1.0 + title 'Test AWS EMR Security Configuration in bulk' + + describe aws_emr_security_configurations do + it { should exist } + end + + describe aws_emr_security_configurations.where(security_configuration_name: aws_emr_security_configuration_name) do + it { should exist } + its('encryption_at_rests') { should include encryption_at_rest } + its('encryption_in_transits') { should include encryption_in_transit } + its('local_disk_encryptions') { should include local_disk_encryption } + end +end \ No newline at end of file diff --git a/test/unit/resources/aws_emr_security_configuration_test.rb b/test/unit/resources/aws_emr_security_configuration_test.rb new file mode 100644 index 000000000..c2e4dfc07 --- /dev/null +++ b/test/unit/resources/aws_emr_security_configuration_test.rb @@ -0,0 +1,64 @@ +require 'helper' +require 'aws_emr_security_configuration' +require 'aws-sdk-core' +require_relative 'mock/aws_emr_security_configuration_mock' + +class AwsEmrClusterSecurityConfigurationAtRestEncryptionEnabledPathTest < Minitest::Test + def setup + @cluster = AwsEmrClusterSecurityConfiguration.new(security_configuration_name: 'sample-security-config', + client_args: { stub_responses: true }, + stub_data: AwsEmrClusterSecurityConfigurationMock.new.stub_data(StubDataType::AT_REST_ENCRYPTION_ENABLED)) + end + + def test_encryption_at_rest_enabled + assert_equal(@cluster.encryption_at_rest, true) + end +end + +class AwsEmrClusterSecurityConfigurationAtRestEncryptionDisabledPathTest < Minitest::Test + def setup + @cluster = AwsEmrClusterSecurityConfiguration.new(security_configuration_name: 'j-27SM4YJB3YVPL', + client_args: { stub_responses: true }, + stub_data: AwsEmrClusterSecurityConfigurationMock.new.stub_data(StubDataType::AT_REST_ENCRYPTION_DISBALED)) + end + + def test_encryption_at_rest_disabled + assert_equal(@cluster.encryption_at_rest, false) + end +end + +class AwsEmrClusterSecurityConfigurationInTransitEncryptionEnabledPathTest < Minitest::Test + def setup + @cluster = AwsEmrClusterSecurityConfiguration.new(security_configuration_name: 'j-27SM4YJB3YVPL', + client_args: { stub_responses: true }, + stub_data: AwsEmrClusterSecurityConfigurationMock.new.stub_data(StubDataType::IN_TRANSIT_ENCRYPTION_ENABLED)) + end + + def test_encryption_in_transit_enabled + assert_equal(@cluster.encryption_in_transit, true) + end +end + +class AwsEmrClusterSecurityConfigurationInTransitEncryptionDisabledPathTest < Minitest::Test + def setup + @cluster = AwsEmrClusterSecurityConfiguration.new(security_configuration_name: 'j-27SM4YJB3YVPL', + client_args: { stub_responses: true }, + stub_data: AwsEmrClusterSecurityConfigurationMock.new.stub_data(StubDataType::IN_TRANSIT_ENCRYPTION_DISABLED)) + end + + def test_encryption_in_transit_disabled + assert_equal(@cluster.encryption_in_transit, false) + end +end + +class AwsEmrClusterSecurityConfigurationLocalDiskEncryptionEnabledPathTest < Minitest::Test + def setup + @cluster = AwsEmrClusterSecurityConfiguration.new(security_configuration_name: 'j-27SM4YJB3YVPL', + client_args: { stub_responses: true }, + stub_data: AwsEmrClusterSecurityConfigurationMock.new.stub_data(StubDataType::LOCAL_DISK_ENCRYPTION_ENABLED)) + end + + def test_encryption_local_disk_enabled + assert_equal(@cluster.local_disk_encryption, true) + end +end diff --git a/test/unit/resources/aws_emr_security_configurations_test.rb b/test/unit/resources/aws_emr_security_configurations_test.rb new file mode 100644 index 000000000..75063822e --- /dev/null +++ b/test/unit/resources/aws_emr_security_configurations_test.rb @@ -0,0 +1,40 @@ +require 'helper' +require 'aws_emr_security_configurations' +require 'aws-sdk-core' +require_relative 'mock/aws_emr_security_configuration_mock' + +class AwsEmrClusterSecurityConfigurationsHappyPathTest < Minitest::Test + def setup + mock_security_configurations = [] + mock_security_configuration1 = { name: 'sample_config_1' } + mock_security_configurations << mock_security_configuration1 + mock_security_configuration2 = { name: 'sample_config_2' } + mock_security_configurations << mock_security_configuration2 + + data_list = {} + data_list[:method] = :list_security_configurations + data_list[:data] = { security_configurations: mock_security_configurations } + data_list[:client] = Aws::EMR::Client + + mock_security_configurations_detailed = [] + mock_security_configuration_detailed1 = AwsEmrClusterSecurityConfigurationMock.new.mock_simple_security_configuration('sample_config_1') + mock_security_configurations_detailed << mock_security_configuration_detailed1 + mock_security_configuration_detailed2 = AwsEmrClusterSecurityConfigurationMock.new.mock_simple_security_configuration('sample_config_2') + mock_security_configurations_detailed << mock_security_configuration_detailed2 + + data_describe = {} + data_describe[:method] = :describe_security_configuration + data_describe[:data] = mock_security_configuration_detailed1 + data_describe[:client] = Aws::EMR::Client + + @clusters = AwsEmrClusterSecurityConfigurations.new(client_args: { stub_responses: true }, stub_data: [data_list, data_describe]) + end + + def test_clusters_exists + assert @clusters.exist? + end + + def test_clusters_running + assert @clusters.running? + end +end diff --git a/test/unit/resources/mock/aws_emr_security_configuration_mock.rb b/test/unit/resources/mock/aws_emr_security_configuration_mock.rb new file mode 100644 index 000000000..2d86d1429 --- /dev/null +++ b/test/unit/resources/mock/aws_emr_security_configuration_mock.rb @@ -0,0 +1,120 @@ +class AwsEmrClusterSecurityConfigurationMock < AwsBaseResourceMock + attr_accessor :cluster_id, :cluster_state, :cluster_arn + + def initialize + super + + @mock_cluster = { + id: 'j-27SM4YJB3YVPL', + status: { state: 'RUNNING' }, + cluster_arn: 'cluster-arn', + } + + @mock_cluster_sec_config_at_rest_encryption_enabled = {} + @mock_cluster_sec_config_at_rest_encryption_enabled[:name] = 'sec_config_at_rest_encryption_enabled' + @mock_cluster_sec_config_at_rest_encryption_enabled[:security_configuration] = ' + { + "EncryptionConfiguration": { + "EnableInTransitEncryption": false, + "EnableAtRestEncryption": true, + "AtRestEncryptionConfiguration": { + "S3EncryptionConfiguration": { + "EncryptionMode": "SSE-S3" + } + } + } + }' + + @mock_cluster_sec_config_at_rest_encryption_disabled = {} + @mock_cluster_sec_config_at_rest_encryption_disabled[:name] = 'sec_config_at_rest_encryption_disabled' + @mock_cluster_sec_config_at_rest_encryption_disabled[:security_configuration] = ' + { + "EncryptionConfiguration": { + "EnableInTransitEncryption": false, + "EnableAtRestEncryption": false + } + }' + + @mock_cluster_sec_config_in_transit_encryption_enabled = {} + @mock_cluster_sec_config_in_transit_encryption_enabled[:name] = 'sec_config_in_transit_encryption_enabled' + @mock_cluster_sec_config_in_transit_encryption_enabled[:security_configuration] = ' + { + "EncryptionConfiguration": { + "EnableInTransitEncryption": true, + "EnableAtRestEncryption": false, + "InTransitEncryptionConfiguration": { + "TLSCertificateConfiguration": { + "CertificateProviderType": "PEM", + "S3Object": "s3://MyConfigStore/artifacts/MyCerts.zip" + } + } + } + }' + + @mock_cluster_sec_config_in_transit_encryption_disabled = {} + @mock_cluster_sec_config_in_transit_encryption_disabled[:name] = 'sec_config_in_transit_encryption_disabled' + @mock_cluster_sec_config_in_transit_encryption_disabled[:security_configuration] = ' + { + "EncryptionConfiguration": { + "EnableInTransitEncryption": false, + "EnableAtRestEncryption": false + } + }' + + @mock_cluster_sec_config_local_disk_encryption_enabled = {} + @mock_cluster_sec_config_local_disk_encryption_enabled[:name] = 'sec_config_local_disk_encryption_enabled' + @mock_cluster_sec_config_local_disk_encryption_enabled[:security_configuration] = ' + { + "EncryptionConfiguration": { + "EnableInTransitEncryption": false, + "EnableAtRestEncryption": true, + "AtRestEncryptionConfiguration": { + "S3EncryptionConfiguration": { + "EncryptionMode": "SSE-S3" + }, + "LocalDiskEncryptionConfiguration": { + "EncryptionKeyProviderType": "AwsKms", + "AwsKmsKey": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012" + } + } + } + }' + end + + def mock_simple_security_configuration(security_configuration_name = 'sample-security-configuration-name') + @mock_cluster_sec_config_at_rest_encryption_enabled[:name] = security_configuration_name + @mock_cluster_sec_config_at_rest_encryption_enabled + end + + def stub_data(stub_type) + security_configuration_data = '' + case stub_type + when StubDataType::AT_REST_ENCRYPTION_ENABLED + security_configuration_data = @mock_cluster_sec_config_at_rest_encryption_enabled + when StubDataType::AT_REST_ENCRYPTION_DISBALED + security_configuration_data = @mock_cluster_sec_config_at_rest_encryption_disabled + when StubDataType::IN_TRANSIT_ENCRYPTION_ENABLED + security_configuration_data = @mock_cluster_sec_config_in_transit_encryption_enabled + when StubDataType::IN_TRANSIT_ENCRYPTION_DISABLED + security_configuration_data = @mock_cluster_sec_config_in_transit_encryption_disabled + when StubDataType::LOCAL_DISK_ENCRYPTION_ENABLED + security_configuration_data = @mock_cluster_sec_config_local_disk_encryption_enabled + end + + describe_security_configuration = { + client: Aws::EMR::Client, + method: 'describe_security_configuration', + data: security_configuration_data, + } + [describe_security_configuration] + end +end + +module StubDataType + SIMPLE = 0 + AT_REST_ENCRYPTION_ENABLED = 1 + AT_REST_ENCRYPTION_DISBALED = 2 + IN_TRANSIT_ENCRYPTION_ENABLED = 3 + IN_TRANSIT_ENCRYPTION_DISABLED = 4 + LOCAL_DISK_ENCRYPTION_ENABLED = 5 +end From 8bd914a4ba24690506b6a02f302dc99244a64c17 Mon Sep 17 00:00:00 2001 From: Varun Sharma Date: Wed, 17 Nov 2021 18:35:18 +0530 Subject: [PATCH 2/4] Added documentation, modified as per review comments Signed-off-by: Varun Sharma --- .../aws_emr_security_configuration.md | 92 +++++++++++++++++++ .../aws_emr_security_configurations.md | 67 ++++++++++++++ libraries/aws_emr_security_configuration.rb | 1 + .../aws_emr_security_configuration.rb | 9 -- 4 files changed, 160 insertions(+), 9 deletions(-) create mode 100644 docs/resources/aws_emr_security_configuration.md create mode 100644 docs/resources/aws_emr_security_configurations.md diff --git a/docs/resources/aws_emr_security_configuration.md b/docs/resources/aws_emr_security_configuration.md new file mode 100644 index 000000000..b0d0ab884 --- /dev/null +++ b/docs/resources/aws_emr_security_configuration.md @@ -0,0 +1,92 @@ +--- +title: About the aws_emr_security_configuration Resource +platform: aws +--- + +# aws\_emr\_security\_configuration + +Use the `aws_emr_security_configuration` InSpec audit resource to test properties of the singular resource of AWS EMR Security Configuration. + +## Syntax + +An `aws_emr_security_configuration` resource block declares the tests for a single AWS EMR Security Configuration by `security_configuration_name`. +```ruby +describe aws_emr_security_configuration(security_configuration_name: 'SECURITY_CONFIGURATION_NAME') do + it { should exist } +end +``` +```ruby +describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do + it { should exist } +end +``` +#### Parameters + +##### `security_configuration_name` _(required)_ + +This resource requires a single parameter, the EMR Security Configuration name. +This can be passed either as a string or as a `security_configuration_name: 'value'` key-value entry in a hash. + +See also the [AWS documentation on AWS EMR Security Configuration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-emr-securityconfiguration.html). + +## Properties + +|Property | Description| +| --- | --- | +|encryption\_at\_rest | Specifies whether at-rest encryption is enabled for the culster.| +|encryption\_in\_transit | Specifies whether in-transit encryption is enabled for the culster.| +|local\_disk\_encryption | Specifies whether local-disk encryption is enabled for the cluster. | + +## Examples + + +#### Test that an EMR Cluster does not exist +```ruby +describe aws_emr_security_configuration(security_configuration_name: 'INVALID_SECURITY_CONFIGURATION_NAME') do + it { should_not exist } +end +``` +#### Test that an EMR Security Configuration's at-rest encryption is enabled +```ruby +describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do + its ('encryption_at_rest') { should eq true } +end +``` +#### Test that an EMR Security Configuration's in-transit encryption is enabled +```ruby +describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do + its ('encryption_in_transit') { should eq true } +end +``` +#### Test that an EMR Security Configuration's local-disk encryption is enabled +```ruby +describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do + its ('local_disk_encryption') { should eq true } +end +``` +## Matchers + +This InSpec audit resource has the following special matchers. For a full list of available matchers, please visit our [matchers page](https://www.inspec.io/docs/reference/matchers/). + +#### exist + +The control will pass if the describe returns at least one result. + +Use `should` to test the entity should exist. +```ruby +describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do + it { should exist } +end +``` + +Use `should_not` to test the entity should not exist. +```ruby +describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do + it { should_not exist } +end +``` + +## AWS Permissions + +Your [Principal](https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal) will need the `EMR:Client:DescribeSecurityConfigurationOutput` action set to allow. + diff --git a/docs/resources/aws_emr_security_configurations.md b/docs/resources/aws_emr_security_configurations.md new file mode 100644 index 000000000..737bef0ef --- /dev/null +++ b/docs/resources/aws_emr_security_configurations.md @@ -0,0 +1,67 @@ +--- +title: About the aws_emr_security_configurationss Resource +platform: aws +--- + +# aws\_emr\_security\_configurations + +Use the `aws_emr_security_configurations` resource to test the properties of collection for AWS EMR Security Configuration. + +## Syntax + +```ruby +describe aws_emr_security_configurations do + it { should exist } +end +``` +#### Parameters + +This resource does not expect any parameters. + +See also the [AWS documentation on AWS EMR Security Configuration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-emr-securityconfiguration.html). + +## Properties + +|Property | Description|Fields +| --- | --- |---| +|security_configuration_names |The name of the security configuration.|name| +|encryption\_at\_rest | Specifies whether at-rest encryption is enabled for the culster.|security_configuration(EncryptionConfiguration(EnableAtRestEncryption))| +|encryption\_in\_transit | Specifies whether in-transit encryption is enabled for the culster.|security_configuration(EncryptionConfiguration(EnableInTransitEncryption))| +|local\_disk\_encryption | Specifies whether local-disk encryption is enabled for the cluster. |security_configuration(EncryptionConfiguration(AtRestEncryptionConfiguration(LocalDiskEncryptionConfiguration)))| + +## Examples + +#### Ensure AWS EMR Security Configurations exists +```ruby +describe aws_emr_security_configurations do + it { should exist } + its('encryption_at_rests') { should include encryption_at_rest } + its('encryption_in_transits') { should include encryption_in_transit } + its('local_disk_encryptions') { should include local_disk_encryption } +end +``` +## Matchers + +For a full list of available matchers, please visit our [matchers page](https://docs.chef.io/inspec/matchers/). + +#### exist + +The control will pass if the describe returns at least one result. + +Use `should` to test the entity should exist. +```ruby +describe aws_emr_security_configurations.where(security_configuration_name: 'SECURITY_CONFIGURATION_NAME') do + it { should exist } +end +``` +Use `should_not` to test the entity should not exist. +```ruby +describe aws_emr_security_configurations.where(security_configuration_name: 'INVALID_SECURITY_CONFIGURATION_NAME') do + it { should_not exist } +end +``` + +## AWS Permissions + +Your [Principal](https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal) will need the `EMR:Client:DescribeSecurityConfigurationOutput` & `EMR:Client:ListSecurityConfigurationsOutput` action sets to allow. + diff --git a/libraries/aws_emr_security_configuration.rb b/libraries/aws_emr_security_configuration.rb index 1618b5698..856fda50e 100644 --- a/libraries/aws_emr_security_configuration.rb +++ b/libraries/aws_emr_security_configuration.rb @@ -9,6 +9,7 @@ class AwsEmrClusterSecurityConfiguration < AwsResourceBase example " describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do + it { should exist } its('encryption_at_rest') { should eq true } its('encryption_in_transit') { should eq true } its('local_disk_encryption') { should eq true } diff --git a/test/integration/verify/controls/aws_emr_security_configuration.rb b/test/integration/verify/controls/aws_emr_security_configuration.rb index 3d8dc6b00..d1bf3ae99 100644 --- a/test/integration/verify/controls/aws_emr_security_configuration.rb +++ b/test/integration/verify/controls/aws_emr_security_configuration.rb @@ -19,17 +19,8 @@ describe aws_emr_security_configuration(security_configuration_name: aws_emr_security_configuration_name) do it { should exist } - end - - describe aws_emr_security_configuration(security_configuration_name: aws_emr_security_configuration_name) do its('encryption_at_rest'){ should eq encryption_at_rest } - end - - describe aws_emr_security_configuration(security_configuration_name: aws_emr_security_configuration_name) do its('encryption_in_transit'){ should eq encryption_in_transit } - end - - describe aws_emr_security_configuration(security_configuration_name: aws_emr_security_configuration_name) do its('local_disk_encryption'){ should eq local_disk_encryption } end end \ No newline at end of file From 7b141362d13c328038c3996c4160bb096071dbcc Mon Sep 17 00:00:00 2001 From: Varun Sharma Date: Thu, 18 Nov 2021 12:53:32 +0530 Subject: [PATCH 3/4] Adding emr dependency in aws_backend.rb Signed-off-by: Varun Sharma --- libraries/aws_backend.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/aws_backend.rb b/libraries/aws_backend.rb index c93e26113..cd098c201 100644 --- a/libraries/aws_backend.rb +++ b/libraries/aws_backend.rb @@ -51,6 +51,7 @@ require 'aws-sdk-mq' require 'aws-sdk-networkmanager' require 'aws-sdk-signer' +require 'aws-sdk-emr' # AWS Inspec Backend Classes # @@ -291,6 +292,10 @@ def network_manager_client def mq_client aws_client(Aws::MQ::Client) end + + def emr_client + aws_client(Aws::EMR::Client) + end end # Base class for AWS resources From 92f7bb5a6e70ae8b2a251e1258f8cd5c26265a1e Mon Sep 17 00:00:00 2001 From: Ian Maddaus Date: Thu, 18 Nov 2021 12:16:47 -0500 Subject: [PATCH 4/4] Docs edits Signed-off-by: Ian Maddaus --- .../aws_emr_security_configuration.md | 51 ++++++++++--------- .../aws_emr_security_configurations.md | 39 +++++++------- 2 files changed, 47 insertions(+), 43 deletions(-) diff --git a/docs/resources/aws_emr_security_configuration.md b/docs/resources/aws_emr_security_configuration.md index b0d0ab884..e6c90becd 100644 --- a/docs/resources/aws_emr_security_configuration.md +++ b/docs/resources/aws_emr_security_configuration.md @@ -3,76 +3,77 @@ title: About the aws_emr_security_configuration Resource platform: aws --- -# aws\_emr\_security\_configuration +# aws_emr_security_configuration -Use the `aws_emr_security_configuration` InSpec audit resource to test properties of the singular resource of AWS EMR Security Configuration. +Use the `aws_emr_security_configuration` InSpec audit resource to test properties of the singular resource of AWS EMR security configuration. ## Syntax -An `aws_emr_security_configuration` resource block declares the tests for a single AWS EMR Security Configuration by `security_configuration_name`. +An `aws_emr_security_configuration` resource block declares the tests for a single AWS EMR security configuration by `security_configuration_name`. + ```ruby describe aws_emr_security_configuration(security_configuration_name: 'SECURITY_CONFIGURATION_NAME') do it { should exist } end ``` + ```ruby describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do it { should exist } end ``` -#### Parameters -##### `security_configuration_name` _(required)_ +## Parameters + +`security_configuration_name` _(required)_ -This resource requires a single parameter, the EMR Security Configuration name. +This resource requires a single parameter, the EMR security configuration name. This can be passed either as a string or as a `security_configuration_name: 'value'` key-value entry in a hash. -See also the [AWS documentation on AWS EMR Security Configuration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-emr-securityconfiguration.html). +See also the [AWS documentation on AWS EMR security configuration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-emr-securityconfiguration.html). ## Properties |Property | Description| | --- | --- | -|encryption\_at\_rest | Specifies whether at-rest encryption is enabled for the culster.| -|encryption\_in\_transit | Specifies whether in-transit encryption is enabled for the culster.| -|local\_disk\_encryption | Specifies whether local-disk encryption is enabled for the cluster. | - +|encryption_at_rest | Specifies whether at-rest encryption is enabled for the cluster.| +|encryption_in_transit | Specifies whether in-transit encryption is enabled for the cluster.| +|local_disk_encryption | Specifies whether local-disk encryption is enabled for the cluster. | + ## Examples +### Test that an EMR security configuration has at-rest encryption enabled -#### Test that an EMR Cluster does not exist -```ruby -describe aws_emr_security_configuration(security_configuration_name: 'INVALID_SECURITY_CONFIGURATION_NAME') do - it { should_not exist } -end -``` -#### Test that an EMR Security Configuration's at-rest encryption is enabled ```ruby describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do its ('encryption_at_rest') { should eq true } end ``` -#### Test that an EMR Security Configuration's in-transit encryption is enabled + +### Test that an EMR security configuration has in-transit encryption enabled + ```ruby describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do its ('encryption_in_transit') { should eq true } end ``` -#### Test that an EMR Security Configuration's local-disk encryption is enabled + +### Test that an EMR security configuration has local-disk encryption enabled + ```ruby describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do its ('local_disk_encryption') { should eq true } end ``` + ## Matchers This InSpec audit resource has the following special matchers. For a full list of available matchers, please visit our [matchers page](https://www.inspec.io/docs/reference/matchers/). -#### exist - -The control will pass if the describe returns at least one result. +### exist Use `should` to test the entity should exist. + ```ruby describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do it { should exist } @@ -80,6 +81,7 @@ end ``` Use `should_not` to test the entity should not exist. + ```ruby describe aws_emr_security_configuration('SECURITY_CONFIGURATION_NAME') do it { should_not exist } @@ -88,5 +90,4 @@ end ## AWS Permissions -Your [Principal](https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal) will need the `EMR:Client:DescribeSecurityConfigurationOutput` action set to allow. - +Your [Principal](https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal) will need the `EMR:Client:DescribeSecurityConfigurationOutput` action with `Effect` set to `Allow`. diff --git a/docs/resources/aws_emr_security_configurations.md b/docs/resources/aws_emr_security_configurations.md index 737bef0ef..03de729c7 100644 --- a/docs/resources/aws_emr_security_configurations.md +++ b/docs/resources/aws_emr_security_configurations.md @@ -3,9 +3,9 @@ title: About the aws_emr_security_configurationss Resource platform: aws --- -# aws\_emr\_security\_configurations +# aws_emr_security_configurations -Use the `aws_emr_security_configurations` resource to test the properties of collection for AWS EMR Security Configuration. +Use the `aws_emr_security_configurations` resource to test the properties of collection for AWS EMR security configuration. ## Syntax @@ -14,24 +14,26 @@ describe aws_emr_security_configurations do it { should exist } end ``` -#### Parameters + +### Parameters This resource does not expect any parameters. -See also the [AWS documentation on AWS EMR Security Configuration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-emr-securityconfiguration.html). +See also the [AWS documentation on AWS EMR security configuration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-emr-securityconfiguration.html). ## Properties -|Property | Description|Fields -| --- | --- |---| -|security_configuration_names |The name of the security configuration.|name| -|encryption\_at\_rest | Specifies whether at-rest encryption is enabled for the culster.|security_configuration(EncryptionConfiguration(EnableAtRestEncryption))| -|encryption\_in\_transit | Specifies whether in-transit encryption is enabled for the culster.|security_configuration(EncryptionConfiguration(EnableInTransitEncryption))| -|local\_disk\_encryption | Specifies whether local-disk encryption is enabled for the cluster. |security_configuration(EncryptionConfiguration(AtRestEncryptionConfiguration(LocalDiskEncryptionConfiguration)))| - +|Property | Description|Fields | +| --- | --- |---| +|security_configuration_names |The name of the security configuration.|name| +|encryption_at_rest | Specifies whether at-rest encryption is enabled for the cluster.|security_configuration(EncryptionConfiguration(EnableAtRestEncryption))| +|encryption_in_transit | Specifies whether in-transit encryption is enabled for the cluster.|security_configuration(EncryptionConfiguration(EnableInTransitEncryption))| +|local_disk_encryption | Specifies whether local-disk encryption is enabled for the cluster. |security_configuration(EncryptionConfiguration(AtRestEncryptionConfiguration(LocalDiskEncryptionConfiguration)))| + ## Examples -#### Ensure AWS EMR Security Configurations exists +#### Ensure AWS EMR security configurations exists + ```ruby describe aws_emr_security_configurations do it { should exist } @@ -40,21 +42,23 @@ describe aws_emr_security_configurations do its('local_disk_encryptions') { should include local_disk_encryption } end ``` + ## Matchers For a full list of available matchers, please visit our [matchers page](https://docs.chef.io/inspec/matchers/). -#### exist +### exist -The control will pass if the describe returns at least one result. +Use `should` to test an entity that should exist. -Use `should` to test the entity should exist. ```ruby describe aws_emr_security_configurations.where(security_configuration_name: 'SECURITY_CONFIGURATION_NAME') do it { should exist } end ``` -Use `should_not` to test the entity should not exist. + +Use `should_not` to test an entity that should not exist. + ```ruby describe aws_emr_security_configurations.where(security_configuration_name: 'INVALID_SECURITY_CONFIGURATION_NAME') do it { should_not exist } @@ -63,5 +67,4 @@ end ## AWS Permissions -Your [Principal](https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal) will need the `EMR:Client:DescribeSecurityConfigurationOutput` & `EMR:Client:ListSecurityConfigurationsOutput` action sets to allow. - +Your [Principal](https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal) will need the `EMR:Client:DescribeSecurityConfigurationOutput` action with `Effect` set to `Allow`.