Skip to content

inspec/inspec-aws

Repository files navigation

InSpec for AWS

  • Project State: Maintained

For more information on project states and SLAs, see this documentation.

This InSpec resource pack uses the AWS Ruby SDK v3 and provides the required resources to write tests for resources in AWS.

Prerequisites

AWS Credentials

Valid AWS credentials are required, see AWS Documentation

There are multiple ways to set the AWS credentials, as shown below:

1) Environment Variables

Set your AWS credentials in a .envrc file or export them in your shell. (See example .envrc file)

    # Example configuration
    export AWS_ACCESS_KEY_ID="AKIAJUMP347SLS66IGCQ"
    export AWS_SECRET_ACCESS_KEY="vD2lfoNvPdwsofqyuO9jRuWUkZIMqisdfeFmkHTy7ON+w"
    export AWS_REGION="eu-west-3"
    export AWS_AVAILABILITY_ZONE="eu-west-3a"  
2) Configuration File

Set your AWS credentials in ~/.aws/config and ~/.aws/credentials file. (See example aws configure credentials)

Example ~/.aws/credentials :

   [default]
   aws_access_key_id=AKIAIOSFODNN7EXAMPLE
   aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
   
   [engineering]
   aws_access_key_id=AKIAIOSFODNN7EXAMPLF
   aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY1

Example ~/.aws/config :

   [default]
   region=us-west-2
   
   [engineering]
   region=us-east-2

AWS SDK selects the default credentials unless aws_profile is set in an .envrc.

    # Example configuration
    export AWS_PROFILE="engineering"
The credentials precedence is
  1. Credentials set in .envrc OR as an Environment variable.
  2. Credentials set in ~/.aws/credentials AND ~/.aws/config AND AWS_PROFILE set as an Environment variable.
  3. Credentials set in ~/.aws/credentials AND ~/.aws/config AND AWS_PROFILE is NOT set as an Environment variable. Default credentials are used.

AWS Region

The aws_region parameter queries resources in a specific region. If not provided, the AWS region set in environment variables or configuration files are used.

Example:

describe aws_ec2_instances(aws_region: 'us-west-2') do
  its('count') { should eq 10 }
end

Assuming an IAM role

Assuming an IAM role allows an IAM users gain additional (or different) permissions to perform actions in a different AWS account. (See example aws configure IAM role)

Example:

   [profile example_profile]
   role_arn = arn:aws:iam::123456789012:role/example_profile
   source_profile = user1

Permissions

Each resource requires specific permissions to perform the operations required for testing. For example, to test an AWS EC2 instance, your service principal requires the ec2:DescribeInstances and iam:GetInstanceProfile permissions. You can find a comprehensive list of each resource's permissions needed in the documentation.

Use the Resources

Since this is an InSpec resource pack, it defines the InSpec resources and includes example tests only. To use the AWS resources in your tests, do the following:

inspec init profile --platform aws my-profile

The above command generates a sample inspec.yml that depends on master. We recommend this is pinned to a release of the resource pack as follows:

name: my-profile
title: My own AWS profile
version: 0.1.0
inspec_version: '>= 4.6.9'
depends:
  - name: inspec-aws
    url: https://github.com/inspec/inspec-aws/archive/x.tar.gz
supports:
  - platform: aws

Use the Resources

Since this is an InSpec resource pack, it only defines InSpec resources. To use these resources in your controls, create your profile:

Create a profile

inspec init profile --platform aws my-profile

The above command generates a sample inspec.yml that depends on master. We recommend this is pinned to a release of the resource pack as follows.

Example inspec.yml:

name: my-profile
title: My own AWS profile
version: 0.1.0
inspec_version: '>= 4.6.9'
depends:
 - name: inspec-aws
   url: https://github.com/inspec/inspec-aws/archive/x.tar.gz
supports:
 - platform: aws

(For available inspec-aws versions, see this list of inspec-aws versions.)

If a resource is in local, change the url to path.

name: my-profile
title: My own AWS profile
version: 0.1.0
inspec_version: '>= 4.6.9'
depends:
 - name: inspec-aws
   path: ../my-profile
supports:
 - platform: aws

(For available inspec-aws versions, see this list of inspec-aws versions.)

Add some tests and run the profile via:

inspec exec my-profile -t aws://

Resource documentation

This resource pack allows the testing of the following AWS resources. If a resource you wish to test is not listed, please feel free to open an Issue. As an open-source project, we also welcome public contributions via Pull Request.

InSpec AWS Supported Resources https://docs.chef.io/inspec/resources/

Module Name Services Resource & Property Reference Singular Resource Plural Resource
AmazonMQ Application Integration AWS::AmazonMQ::Broker aws_mq_broker aws_mq_brokers
AWS::AmazonMQ::Configuration aws_mq_configuration aws_mq_configurations
Amplify Console Front-end Web & Mobile AWS::Amplify::App aws_amplify_app aws_amplify_apps
AWS::Amplify::Branch aws_amplify_branch aws_amplify_branches
API Gateway Networking & Content Delivery AWS::ApiGateway::Account aws_apigateway_account No Plural Resource
AWS::ApiGateway::ApiKey aws_apigateway_api_key aws_apigateway_api_keys
AWS::ApiGateway::Authorizer aws_apigateway_authorizer aws_apigateway_authorizers
AWS::ApiGateway::BasePathMapping aws_apigateway_base_path_mapping aws_apigateway_base_path_mappings
AWS::ApiGateway::ClientCertificate aws_apigateway_client_certificate aws_apigateway_client_certificates
AWS::ApiGateway::Deployment aws_api_gateway_deployment aws_api_gateway_deployments
AWS::ApiGateway::DocumentationPart aws_api_gateway_documentation_part aws_api_gateway_documentation_parts
AWS::ApiGateway::DocumentationVersion aws_api_gateway_documentation_version aws_api_gateway_documentation_versions
AWS::ApiGateway::DomainName aws_api_gateway_domain_name aws_api_gateway_domain_names
AWS::ApiGateway::GatewayResponse aws_api_gateway_response aws_api_gateway_responses
AWS::ApiGateway::Method aws_api_gateway_method aws_api_gateway_methods
AWS::ApiGateway::Model aws_api_gateway_model aws_api_gateway_models
AWS::ApiGateway::RequestValidator aws_api_gateway_request_validator aws_api_gateway_request_validators
AWS::ApiGateway::Resource aws_api_gateway_resource aws_api_gateway_resources
AWS::ApiGateway::RestApi aws_api_gateway_restapi aws_api_gateway_restapis
AWS::ApiGateway::Stage aws_api_gateway_stage aws_api_gateway_stages
AWS::ApiGateway::UsagePlan aws_api_gateway_usage_plan aws_api_gateway_usage_plans
AWS::ApiGateway::UsagePlanKey aws_api_gateway_usage_plan_key aws_api_gateway_usage_plan_keys
AWS::ApiGateway::VpcLink aws_api_gateway_vpc_link aws_api_gateway_vpc_links
Application Auto Scaling Compute AWS::ApplicationAutoScaling::ScalableTarget aws_application_autoscaling_scalable_target aws_application_autoscaling_scalable_targets
AWS::ApplicationAutoScaling::ScalingPolicy aws_application_autoscaling_scaling_policy aws_application_autoscaling_scaling_policies
Athena Analytics AWS::Athena::WorkGroup aws_athena_work_group aws_athena_work_groups
Amazon EC2 Auto Scaling Compute AWS::AutoScaling::AutoScalingGroup aws_auto_scaling_group aws_auto_scaling_groups
AWS::AutoScaling::LaunchConfiguration aws_launch_configuration No Plural Resource
AWS::AutoScaling::ScalingPolicy aws_autoscaling_scaling_policy aws_autoscaling_scaling_policies
AWS Batch Compute AWS::Batch::ComputeEnvironment aws_batch_compute_environment aws_batch_compute_environments
AWS::Batch::JobDefinition aws_batch_job_definition aws_batch_job_definitions
AWS::Batch::JobQueue aws_batch_job_queue aws_batch_job_queues
CloudFormation Management & Governance AWS::CloudFormation::Stack aws_cloudformation_stack aws_cloudformation_stacks
AWS::CloudFormation::StackSet aws_cloud_formation_stack_set aws_cloud_formation_stack_sets
Others aws_cloudformation_template No Plural Resource
CloudFront Networking & Content Delivery AWS::CloudFront::CachePolicy aws_cloudfront_cache_policy aws_cloudfront_cache_policies
AWS::CloudFront::CloudFrontOriginAccessIdentity aws_cloudfront_origin_access_identity aws_cloudfront_origin_access_identities
AWS::CloudFront::Distribution aws_cloudfront_distribution aws_cloudfront_distributions
AWS::CloudFront::KeyGroup aws_cloudfront_key_group aws_cloudfront_key_groups
AWS::CloudFront::OriginRequestPolicy aws_cloud_front_origin_request_policy No Plural Resource
AWS::CloudFront::PublicKey aws_cloudfront_public_key aws_cloudfront_public_keys
AWS::CloudFront::RealtimeLogConfig aws_cloudfront_realtime_log_config aws_cloudfront_realtime_log_configs
AWS::CloudFront::StreamingDistribution aws_cloudfront_streaming_distribution aws_cloudfront_streaming_distributions
CloudTrail Management & Governance AWS::CloudTrail::Trail aws_cloudtrail_trail aws_cloudtrail_trails
CloudWatch Management & Governance AWS::CloudWatch::Alarm aws_cloudwatch_alarm No Plural Resource
AWS::CloudWatch::AnomalyDetector aws_cloudwatch_anomaly_detector aws_cloudwatch_anomaly_detectors
AWS::CloudWatch::CompositeAlarm aws_cloudwatch_composite_alarm aws_cloudwatch_composite_alarms
AWS::CloudWatch::Dashboard aws_cloudwatch_dashboard aws_cloudwatch_dashboards
AWS::CloudWatch::InsightRule No Singular Resource aws_cloudwatch_insight_rules
AWS::CloudWatch::MetricStream aws_cloudwatch_metric_stream aws_cloudwatch_metric_streams
CloudWatch Logs Management & Governance AWS::Logs::Destination aws_cloudwatchlogs_destination aws_cloudwatchlogs_destinations
AWS::Logs::LogGroup aws_cloudwatch_log_group No Plural Resource
AWS::Logs::LogStream aws_cloudwatchlogs_log_stream aws_cloudwatchlogs_log_streams
AWS::Logs::MetricFilter aws_cloudwatch_log_metric_filter No Plural Resource
aws_logs_metric_filter aws_logs_metric_filters
AWS::Logs::SubscriptionFilter aws_cloudwatchlogs_subscription_filter aws_cloudwatchlogs_subscription_filters
Amazon Cognito Security, Identity, & Compliance AWS::Cognito::IdentityPool aws_cognito_identity_pool aws_cognito_identity_pools
AWS::Cognito::UserPool aws_cognito_userpool aws_cognito_userpools
AWS::Cognito::UserPoolClient aws_cognito_userpool_client aws_cognito_userpool_clients
Config Management & Governance AWS::Config::ConfigurationRecorder aws_config_recorder No Plural Resource
AWS::Config::DeliveryChannel aws_config_delivery_channel No Plural Resource
DMS Compute AWS::DMS::Endpoint aws_dms_endpoint aws_dms_endpoints
AWS::DMS::ReplicationInstance aws_dms_replication_instance aws_dms_replication_instances
AWS::DMS::ReplicationSubnetGroup aws_dms_replication_subnet_group aws_dms_replication_subnet_groups
DynamoDB Database AWS::DynamoDB::Table aws_dynamodb_table aws_dynamodb_tables
EC2 Compute AWS::EC2::CapacityReservation aws_ec2_capacity_reservation aws_ec2_capacity_reservations
AWS::EC2::CarrierGateway aws_ec2_carrier_gateway aws_ec2_carrier_gateways
AWS::EC2::CustomerGateway aws_ec2_customer_gateway aws_ec2_customer_gateways
AWS::EC2::DHCPOptions No Singular Resource aws_dhcp_options
aws_ec2_dhcp_option aws_ec2_dhcp_options
AWS::EC2::Fleet aws_ec2_fleet aws_ec2_fleets
AWS::EC2::EgressOnlyInternetGateway aws_ec2_egress_only_internet_gateway aws_ec2_egress_only_internet_gateways
AWS::EC2::EIP aws_ec2_eip aws_ec2_eips
AWS::EC2::EIPAssociation aws_ec2_eip_association aws_ec2_eip_associations
AWS::EC2::FlowLog aws_flow_log No Plural Resource
AWS::EC2::Host aws_ec2_host aws_ec2_hosts
AWS::EC2::Instance aws_ec2_instance aws_ec2_instances
AWS::EC2::InternetGateway aws_ec2_internet_gateway aws_ec2_internet_gateways
aws_internet_gateway aws_internet_gateways
AWS::EC2::LaunchTemplate aws_ec2_launch_template aws_ec2_launch_templates
AWS::EC2::NatGateway aws_nat_gateway aws_nat_gateways
AWS::EC2::NetworkAcl aws_network_acl aws_network_acls
AWS::EC2::NetworkAclEntry aws_network_acl aws_network_acls
AWS::EC2::NetworkInsightsAnalysis aws_ec2_network_insights_analysis aws_ec2_network_insights_analysis_plural
AWS::EC2::NetworkInsightsPath aws_ec2_network_insights_path aws_ec2_network_insights_paths
AWS::EC2::NetworkInterface aws_ec2_network_interface aws_ec2_network_interfaces
AWS::EC2::NetworkInterfaceAttachment aws_ec2_network_interface_attachment aws_ec2_network_interface_attachments
AWS::EC2::NetworkInterfacePermission aws_ec2_network_interface_permission aws_ec2_network_interface_permission
AWS::EC2::PlacementGroup aws_ec2_placement_group aws_ec2_placement_groups
AWS::EC2::PrefixList aws_ec2_prefix_list aws_ec2_prefix_lists
AWS::EC2::Route aws_route_table aws_route_tables
AWS::EC2::RouteTable aws_route_table aws_route_tables
AWS::EC2::SecurityGroup aws_security_group aws_security_groups
AWS::EC2::SecurityGroupEgress aws_security_group aws_security_groups
AWS::EC2::SecurityGroupIngress aws_security_group aws_security_groups
AWS::EC2::SpotFleet aws_ec2_spot_fleet aws_ec2_spot_fleets
AWS::EC2::Subnet aws_subnet aws_subnets
AWS::EC2::TrafficMirrorFilter aws_ec2_traffic_mirror_filter aws_ec2_traffic_mirror_filters
AWS::EC2::TrafficMirrorSession aws_ec2_traffic_mirror_session aws_ec2_traffic_mirror_sessions
AWS::EC2::TrafficMirrorTarget aws_ec2_traffic_mirror_target aws_ec2_traffic_mirror_targets
AWS::EC2::TransitGateway aws_transit_gateway No Plural Resource
AWS::EC2::TransitGatewayAttachment aws_ec2_transit_gateway_attachment aws_ec2_transit_gateway_attachments
AWS::EC2::TransitGatewayConnect aws_transit_gateway_connect aws_transit_gateway_connects
AWS::EC2::TransitGatewayMulticastDomain aws_transit_gateway_multicast_domain aws_transit_gateway_multicast_domains
AWS::EC2::TransitGatewayMulticastDomainAssociation aws_transit_gateway_multicast_domain_association aws_transit_gateway_multicast_domain_associations
AWS::EC2::TransitGatewayMulticastGroupMember aws_transit_gateway_multicast_group_member aws_transit_gateway_multicast_group_members
AWS::EC2::TransitGatewayMulticastGroupSource aws_transit_gateway_multicast_group_source aws_transit_gateway_multicast_group_sources
AWS::EC2::TransitGatewayRoute aws_transit_gateway_route aws_transit_gateway_routes
AWS::EC2::TransitGatewayRouteTable aws_ec2_transit_gateway_route_table aws_ec2_transit_gateway_route_tables
AWS::EC2::TransitGatewayRouteTableAssociation aws_ec2_transit_gateway_route_table_association aws_ec2_transit_gateway_route_table_associations
AWS::EC2::TransitGatewayRouteTablePropagation aws_ec2_transit_gateway_route_table_propagation aws_ec2_transit_gateway_route_table_propagations
AWS::EC2::Volume aws_ebs_volume aws_ebs_volumes
AWS::EC2::VolumeAttachment No Singular Resource aws_ec2_volume_attachments
AWS::EC2::VPC aws_vpc aws_vpcs
AWS::EC2::VPCEndpoint aws_vpc_endpoint aws_vpc_endpoints
AWS::EC2::VPCEndpointConnectionNotification aws_vpc_endpoint_connection_notification aws_vpc_endpoint_connection_notifications
aws_vpc_endpoint_notification aws_vpc_endpoint_notifications
AWS::EC2::VPCEndpointService aws_vpc_endpoint_service aws_vpc_endpoint_services
AWS::EC2::VPCEndpointServicePermissions aws_vpc_endpoint_service_permission aws_vpc_endpoint_service_permissions
AWS::EC2::VPCPeeringConnection aws_ec2_vpc_peering_connection aws_ec2_vpc_peering_connections
AWS::EC2::VPNConnection No Singular Resource aws_vpn_connections
AWS::EC2::VPNConnectionRoute No Singular Resource aws_ec2_vpn_connection_routes
AWS::EC2::VPNGateway aws_vpn_gateway aws_vpn_gateways
AWS::EC2::VPNGatewayRoutePropagation aws_ec2_vpn_gateway_route_propagation aws_ec2_vpn_gateway_route_propagations
Others aws_region aws_regions
aws_ebs_snapshot aws_ebs_snapshots
aws_ami aws_amis
Amazon ECR Containers AWS::ECR::PublicRepository aws_ecrpublic_repository aws_ecrpublic_repositories
AWS::ECR::Repository aws_ecr_repository aws_ecr_repositories
Amazon ECS Containers AWS::ECS::Cluster aws_ecs_cluster aws_ecs_clusters
AWS::ECS::Service aws_ecs_service aws_ecs_services
AWS::ECS::TaskDefinition aws_ecs_task_definition aws_ecs_task_definitions
Others aws_ecr_repository_policy No Plural Resource
aws_ecr No Plural Resource
aws_ecr_image aws_ecr_images
EFS Storage AWS::EFS::FileSystem aws_efs_file_system aws_efs_file_systems
AWS::EFS::MountTarget aws_efs_mount_target aws_efs_mount_targets
EKS Containers AWS::EKS::Cluster aws_eks_cluster aws_eks_clusters
ElasticCache Database AWS::ElastiCache::CacheCluster aws_elasticache_cluster aws_elasticache_clusters
AWS::ElastiCache::ReplicationGroup aws_elasticache_replication_group aws_elasticache_replication_groups
aws_elasticache_cluster_node No Plural Resource
Elasticsearch Analytics AWS::Elasticsearch::Domain aws_elasticsearchservice_domain aws_elasticsearchservice_domains
ElasticLoadBalancingV2 Networking & Content Delivery AWS::ElasticLoadBalancingV2::Listener aws_elasticloadbalancingv2_listener aws_elasticloadbalancingv2_listeners
AWS::ElasticLoadBalancingV2::ListenerCertificate aws_elasticloadbalancingv2_listener_certificate aws_elasticloadbalancingv2_listener_certificates
AWS::ElasticLoadBalancingV2::ListenerRule aws_elasticloadbalancingv2_listener_rule aws_elasticloadbalancingv2_listener_rules
AWS::ElasticLoadBalancingV2::LoadBalancer aws_elb aws_elbs
aws_alb aws_albs
AWS::ElasticLoadBalancingV2::TargetGroup aws_elasticloadbalancingv2_target_group aws_elasticloadbalancingv2_target_groups
Amazon EMR Analytics AWS::EMR::Cluster aws_emr_cluster aws_emr_clusters
AWS::EMR::SecurityConfiguration aws_emr_security_configuration aws_emr_security_configurations
Amazon EventBridge Application Integration AWS::Events::Rule aws_eventbridge_rule aws_eventbridge_rules
AWS Glue Analytics AWS::Glue::Crawler aws_glue_crawler aws_glue_crawlers
AWS::Glue::Database aws_glue_database aws_glue_databases
GuardDuty Security, Identity, & Compliance AWS::GuardDuty::Detector aws_guardduty_detector aws_guardduty_detectors
IAM Security, Identity, & Compliance AWS::IAM::AccessKey aws_iam_access_key aws_iam_access_keys
No Singular Resource aws_iam_account_alias
aws_iam_ssh_public_key aws_iam_ssh_public_keys
AWS::IAM::Group aws_iam_group aws_iam_groups
AWS::IAM::InstanceProfile aws_iam_instance_profile aws_iam_instance_profiles
AWS::IAM::ManagedPolicy aws_iam_managed_policy aws_iam_managed_policies
AWS::IAM::OIDCProvider aws_iam_oidc_provider aws_iam_oidc_providers
AWS::IAM::Policy aws_iam_policy aws_iam_policies
aws_iam_password_policy No Plural Resource
aws_iam_inline_policy No Plural Resource
AWS::IAM::Role aws_iam_role aws_iam_roles
AWS::IAM::SAMLProvider aws_iam_saml_provider aws_iam_saml_providers
AWS::IAM::ServerCertificate aws_iam_server_certificate aws_iam_server_certificates
AWS::IAM::ServiceLinkedRole aws_iam_service_linked_role_deletion_status No Plural Resource
AWS::IAM::User aws_iam_user aws_iam_users
aws_iam_root_user No Plural Resource
AWS::IAM::VirtualMFADevice No Singular Resource aws_iam_virtual_mfa_devices
Others aws_iam_ssh_public_key aws_iam_ssh_public_keys
KMS Security, Identity, & Compliance AWS::KMS::Key aws_kms_key aws_kms_keys
Lambda Compute AWS::Lambda::Alias aws_lambda_alias aws_lambda_aliases
AWS::Lambda::CodeSigningConfig aws_lambda_code_signing_config aws_lambda_code_signing_configs
AWS::Lambda::EventInvokeConfig aws_lambda_event_invoke_config aws_lambda_event_invoke_configs
AWS::Lambda::EventSourceMapping aws_lambda_event_source_mapping aws_lambda_event_source_mappings
AWS::Lambda::Function aws_lambda aws_lambdas
AWS::Lambda::LayerVersionPermission aws_lambda_layer_version_permission No Plural Resource
AWS::Lambda::Permission aws_lambda_permission aws_lambda_permissions
AWS::Lambda::Version aws_lambda_version aws_lambda_versions
Network Firewall Security, Identity, & Compliance AWS::NetworkFirewall::Firewall aws_network_firewall_firewall aws_network_firewall_firewalls
AWS::NetworkFirewall::FirewallPolicy aws_network_firewall_firewall_policy aws_network_firewall_firewall_policies
AWS::NetworkFirewall::LoggingConfiguration aws_network_firewall_logging_configuration No Plural Resource
AWS::NetworkFirewall::RuleGroup aws_network_firewall_rule_group aws_network_firewall_rule_groups
NetworkManager Networking & Content Delivery AWS::NetworkManager::CustomerGatewayAssociation aws_network_manager_customer_gateway_association aws_network_manager_customer_gateway_associations
AWS::NetworkManager::Device aws_network_manager_device aws_network_manager_devices
AWS::NetworkManager::GlobalNetwork aws_network_manager_global_network aws_network_manager_global_networks
Organizations Management & Governance AWS::Organizations::Member aws_organizations_member No Plural Resource
RAM Security, Identity, & Compliance AWS::RAM::ResourceShare aws_ram_resource_share aws_ram_resource_shares
RDS Database AWS::RDS::DBCluster aws_rds_cluster aws_rds_clusters
aws_rds_db_cluster_snapshot aws_rds_db_cluster_snapshots
AWS::RDS::DBInstance aws_rds_instance aws_rds_instances
AWS::RDS::DBParameterGroup aws_db_parameter_group aws_db_parameter_groups
AWS::RDS::DBProxy aws_rds_db_proxy No Plural Resource
AWS::RDS::DBProxyEndpoint aws_rds_db_proxy_endpoint aws_rds_db_proxy_endpoints
AWS::RDS::DBProxyTargetGroup aws_rds_db_proxy_target_group aws_rds_db_proxy_target_groups
AWS::RDS::DBSecurityGroup aws_rds_db_security_group aws_rds_db_security_groups
AWS::RDS::DBSubnetGroup aws_db_subnet_group aws_db_subnet_groups
AWS::RDS::EventSubscription aws_rds_event_subscription aws_rds_event_subscriptions
AWS::RDS::GlobalCluster aws_rds_global_cluster aws_rds_global_clusters
AWS::RDS::OptionGroup aws_rds_group_option aws_rds_group_options
Others aws_rds_snapshot aws_rds_snapshots
No Singular Resource aws_rds_snapshot_attributes
Amazon Redshift Analytics AWS::Redshift::Cluster aws_redshift_cluster aws_redshift_clusters
AWS::Redshift::ClusterParameterGroup aws_redshift_cluster_parameter_group aws_redshift_cluster_parameter_groups
Route 53 Networking & Content Delivery AWS::Route53::HostedZone aws_hosted_zone aws_hosted_zones
AWS::Route53::RecordSet aws_route53_record_set aws_route53_record_sets
Route 53 Resolver Networking & Content Delivery AWS::Route53Resolver::ResolverEndpoint aws_route53resolver_resolver_endpoint aws_route53resolver_resolver_endpoints
AWS::Route53Resolver::ResolverRule aws_route53resolver_resolver_rule aws_route53resolver_resolver_rules
AWS::Route53Resolver::ResolverRuleAssociation aws_route53resolver_resolver_rule_association aws_route53resolver_resolver_rule_associations
Amazon S3 Compute AWS::S3::AccessPoint aws_s3_access_point aws_s3_access_points
AWS::S3::Bucket aws_s3_bucket aws_s3_buckets
AWS::S3::BucketPolicy aws_s3_bucket_policy No Plural Resource
Others aws_s3_bucket_object aws_s3_bucket_objects
Secrets Manager Security, Identity, & Compliance AWS::SecretsManager::Secret aws_secretsmanager_secret aws_secretsmanager_secrets
Service Catalog Management & Governance AWS::ServiceCatalog::CloudFormationProduct aws_servicecatalog_cloud_formation_product No Plural Resource
AWS::ServiceCatalog::LaunchRoleConstraint aws_servicecatalog_launch_role_constraint aws_servicecatalog_launch_role_constraints
AWS::ServiceCatalog::PortfolioPrincipalAssociation aws_servicecatalog_portfolio_principal_association aws_servicecatalog_portfolio_principal_associations
AWS::ServiceCatalog::PortfolioProductAssociation aws_servicecatalog_portfolio_product_association aws_servicecatalog_portfolio_product_associations
Shield Security, Identity, & Compliance AWS::Shield::Subscription aws_shield_subscription No Plural Resource
SecurityHub Security, Identity, & Compliance AWS::SecurityHub::Hub aws_securityhub_hub No Plural Resource
Amazon SES Business Applications AWS::SES::ReceiptRule aws_ses_receipt_rule No Plural Resource
AWS::SES::ReceiptRuleSet aws_ses_receipt_rule_set aws_ses_receipt_rule_sets
AWS::SES::Template aws_ses_template aws_ses_templates
Amazon SimpleDB Simple Database Service AWS::SDB::Domain No Singular Resource aws_sdb_domains
Signer Security, Identity, & Compliance AWS::Signer::ProfilePermission No Singular Resource aws_signer_profile_permissions
AWS::Signer::SigningProfile aws_signer_signing_profile aws_signer_signing_profiles
Amazon SNS Application Integration AWS::SNS::Subscription aws_sns_subscription aws_sns_subscriptions
AWS::SNS::Topic aws_sns_topic aws_sns_topics
AWS::SNS::TopicPolicy aws_sns_topic aws_sns_topics
Amazon SQS Application Integration AWS::SQS::Queue aws_sqs_queue aws_sqs_queues
AWS::SQS::QueuePolicy aws_sqs_queue aws_sqs_queues
SSO Security, Identity, & Compliance AWS::SSO::Assignment aws_sso_assignment aws_sso_assignments
AWS::SSO::InstanceAccessControlAttributeConfiguration aws_sso_instance_access_control_attribute_configuration aws_sso_instance_access_control_attribute_configurations
AWS::SSO::PermissionSet aws_sso_permission_set aws_sso_permission_sets
Step Functions Application Integration AWS::StepFunctions::Activity aws_stepfunctions_activity aws_stepfunctions_activities
AWS::StepFunctions::StateMachine aws_stepfunctions_state_machine aws_stepfunctions_state_machines
STS Security, Identity, & Compliance AWS::STS::CallerIdentity aws_sts_caller_identity No Plural Resource
CloudWatch Synthetics Synthetics AWS::Synthetics::Canary aws_synthetics_canary aws_synthetics_canaries
System Manager Management & Governance AWS::SSM::Association aws_ssm_association aws_ssm_associations
AWS::SSM::Document aws_ssm_document aws_ssm_documents
AWS::SSM::MaintenanceWindow aws_ssm_maintenance_window aws_ssm_maintenance_windows
AWS::SSM::MaintenanceWindowTarget aws_ssm_maintenance_window_target aws_ssm_maintenance_window_targets
AWS::SSM::MaintenanceWindowTask aws_ssm_maintenance_window_task aws_ssm_maintenance_window_tasks
AWS::SSM::Parameter aws_ssm_parameter aws_ssm_parameters
AWS::SSM::PatchBaseline aws_ssm_patch_baseline aws_ssm_patch_baselines
AWS::SSM::ResourceDataSync No Singular Resources aws_ssm_resource_data_syncs
Others aws_ssm_activation aws_ssm_activations
aws_ssm_resource_compliance_summary aws_ssm_resource_compliance_summaries
Amazon Timestream Migration & Transfer AWS::Transfer::User aws_transfer_user aws_transfer_users
WAF Security, Identity, & Compliance AWS::WAF::ByteMatchSet aws_waf_byte_match_set aws_waf_byte_match_sets
AWS::WAF::IPSet aws_waf_ip_set aws_waf_ip_sets
AWS::WAF::Rule aws_waf_rule aws_waf_rules
AWS::WAF::SizeConstraintSet aws_waf_size_constraint_set aws_waf_size_constraint_sets
AWS::WAF::SqlInjectionMatchSet aws_waf_sql_injection_match_set aws_waf_sql_injection_match_sets
AWS::WAF::WebACL aws_waf_web_acl aws_waf_web_acls
AWS::WAF::XssMatchSet aws_waf_xss_match_set aws_waf_xss_match_sets

Examples

Ensure Security Groups disallow FTP

For disallowing FTP, we check that there is no ingress from 0.0.0.0/0 on port 21. The below sample control loops across all regions, checking all security groups for the account:

title 'Test AWS Security Groups Across All Regions For an Account Disallow FTP'

control 'aws-multi-region-security-group-ftp-1.0' do

  impact 1.0
  title 'Ensure AWS Security Groups disallow FTP ingress from 0.0.0.0/0.'

  aws_regions.region_names.each do |region|
    aws_security_groups(aws_region: region).group_ids.each do |security_group_id|
      describe aws_security_group(aws_region: region, group_id: security_group_id) do
        it { should exist }
        it { should_not allow_in(ipv4_range: '0.0.0.0/0', port: 21) }
      end
    end
  end
end

Test that an EC2 instance is running and using the correct AMI

    describe aws_ec2_instance(name: 'ProdWebApp') do
      it              { should be_running }
      its('image_id') { should eq 'ami-27a58d5c' }
    end

Ensure all AWS Users have MFA enabled

    describe aws_iam_users.where( has_mfa_enabled: false) do
      it { should_not exist }
    end

Properties Applying to All InSpec AWS Resources

aws_region

To provide multi-region support, the aws_region property is specified to a resource. This property affects AWS resources that have a region dependency. For example, security groups. One special case worth mentioning is the aws_s3_bucket resource that updates its region based on the location returned from S3.

The aws_regions resource is used to loop across all regions.

  aws_regions.region_names.each do |region|
    <use region in other resources here>
  end

aws_endpoint

A custom endpoint URL can optionally be specified to resources for testing other compatible providers. This propagates to the AWS client configuration. An example is provided below for Minio S3 compatible buckets.

title 'Test For Minio Buckets Existing at a Custom Endpoint'

endpoint = attribute(:minio_server, value: 'http://127.0.0.1:9000', description: 'The Minio server custom endpoint.')

control 'minio-buckets-1.0' do
  impact 1.0
  title 'Ensure Minio buckets exist.'

  describe aws_s3_bucket(aws_endpoint: endpoint, bucket_name: 'miniobucket') do
    it { should exist }
  end

  describe aws_s3_bucket(aws_endpoint: endpoint, bucket_name: 'notthere') do
    it { should_not exist }
  end
end

{{< note >}}

The InSpec AWS assumes full compatibility with the underlying AWS SDK, and unsupported operations cause failures. Hence, depending on the external provider implementation, your mileage may vary!

{{< /note >}}

aws_retry_limit and aws_retry_backoff

In certain cases, AWS implements rate-limiting. To mitigate this issue, the Retry Limit and Retry Backoff can be set in two ways:

1) Environment Variables

Setting AWS_RETRY_LIMIT and AWS_RETRY_BACKOFF environment variables is implemented at the session level.

   export AWS_RETRY_LIMIT=5
   export aws_retry_limit=5

Note environment variables are case insensitive.

2) InSpec Control

InSpec AWS resources now support setting the Retry Limit and Retry Backoff at the control level, as shown below.

  describe aws_config_recorder(recorder_name: aws_config_recorder_name, aws_retry_limit=5, aws_retry_backoff=5) do
    it { should exist }
    its('recorder_name') { should eq aws_config_recorder_name }
  end

#####The aws_retry_limit and aws_retry_backoff precedence:

  1. Set at Inspec control level.
  2. Set at Environment level.

Retry Limit and Retry Backoff documentation

NullResponse

InSpec AWS resources returns NullResponse when an undefined property is tested from version 1.24 onwards instead of raising a NoMethodError.

describe aws_ec2_instance(instance_id: 'i-12345678') do
  its('fake_property') { should be_nil }
end
# =>   EC2 Instance i-12345678
#          ✔  fake_property is expected to be nil

describe aws_ec2_instance(instance_id: 'i-12345678') do
  its('instance_ID') { should eq 'i-12345678' }
end
# =>  ×  instance_ID is expected to eq "i-12345678"    
#     expected: "i-12345678"
#          got: #<#<Class:0x00007ffc4aa24c68>::NullResponse:0x00007ffc39f16070>    
#     (compared using ==)

Prior to version 1.24.

describe aws_ec2_instance(instance_id: 'i-12345678') do
  its('fake_property') { should be_nil }
end
# => EC2 Instance i-12345678
#          ×  fake_property 
#          undefined method `fake_property' for EC2 Instance i-12345678

describe aws_ec2_instance(instance_id: 'i-12345678') do
  its('instance_ID') { should eq 'i-12345678' }
end
# => undefined method `instance_ID' for EC2 Instance i-12345678

Environment and Setup Notes

Train and InSpec Dependencies

InSpec AWS depends on version 3 of the AWS SDK provided via Train AWS. InSpec depends on Train AWS, so this is not explicitly listed in the Gemfile here.

Running a sample profile using Docker

A Dockerfile is provided at the root of this resource pack repository.

cd inspec-aws
docker build -t inspec-aws -f Dockerfile
docker run -it inspec-aws /bin/bash
export AWS_ACCESS_KEY_ID=<your creds here>
export AWS_SECRET_ACCESS_KEY=<your creds here>
bundle exec inspec exec sample_profile -t aws://

If successful, output similar to below code is seen:

# bundle exec inspec exec sample_profile -t aws://

Profile: AWS InSpec Profile (InSpec AWS Sample Profile)
Version: 0.1.0
Target:  aws://us-east-1

  ✔  aws-vpcs-multi-region-status-check: Check AWS VPCs in all regions have status "available"
     ✔  VPC vpc-1234abcd in eu-north-1 should exist
     ✔  VPC vpc-1234abcd in eu-north-1 should be available
<curtailing> ...


Profile: Amazon Web Services  Resource Pack (inspec-aws)
Version: 0.1.0
Target:  aws://us-east-1

     No tests were executed.

Profile Summary: 1 successful control, 0 control failures, 0 controls skipped
Test Summary: 50 successful, 0 failures, 0 skipped

Running a single unit test

rake test TEST=inspec-aws/test/unit/resources/aws_alb_test.rb

The above example is for running the aws_alb_test.rb file.

Running the unit and integration tests

Run the linting and unit tests via the below:

$ bundle exec rake
Running RuboCop...
Inspecting 2 files
..

2 files inspected, no offenses detected
/Users/spaterson/.rubies/ruby-2.4.3/bin/ruby -I"lib:libraries:test/unit" -I"/Users/spaterson/.rubies/ruby-2.4.3/lib/ruby/gems/2.4.0/gems/rake-12.3.1/lib" "/Users/spaterson/.rubies/ruby-2.4.3/lib/ruby/gems/2.4.0/gems/rake-12.3.1/lib/rake/rake_test_loader.rb" "test/unit/resources/aws_vpc_test.rb"
Run options: --seed 64195

# Running:

.................

Fabulous run in 0.253300s, 67.1141 runs/s, 51.3225 assertions/s.

17 runs, 13 assertions, 0 failures, 0 errors, 0 skips
bundle exec inspec check /Users/spaterson/Documents/workspace/aws/inspec-aws
Location:    /Users/spaterson/Documents/workspace/aws/inspec-aws
Profile:     inspec-aws
Controls:    0
Timestamp:   2018-11-29T15:02:33+00:00
Valid:       true

  !  No controls or tests were defined.

Summary:     0 errors, 1 warnings

Conversely, run using within a docker container, using the make file:

To run unit tests and linting:

make sure

Will result in...

make sure

docker-compose run --rm builder 
Running RuboCop...
Inspecting 68 files
....................................................................

68 files inspected, no offenses detected
/usr/local/bin/ruby -I"lib:libraries:test/unit" -I"/usr/local/bundle/gems/rake-12.3.3/lib" "/usr/local/bundle/gems/rake-12.3.3/lib/rake/rake_test_loader.rb" "test/unit/resources/aws_alb_test.rb" "test/unit/resources/aws_auto_scaling_group_test.rb" "test/unit/resources/aws_cloudformation_stack_test.rb" "test/unit/resources/aws_cloudtrail_trail_test.rb" "test/unit/resources/aws_cloudtrail_trails_test.rb" "test/unit/resources/aws_cloudwatch_alarm_test.rb" "test/unit/resources/aws_cloudwatch_log_metric_filter_test.rb" "test/unit/resources/aws_config_delivery_channel_test.rb" "test/unit/resources/aws_config_recorder_test.rb" "test/unit/resources/aws_dynamodb_table_test.rb" "test/unit/resources/aws_ebs_volume_test.rb" "test/unit/resources/aws_ebs_volumes_test.rb" "test/unit/resources/aws_ec2_instance_test.rb" "test/unit/resources/aws_ec2_instances_test.rb" "test/unit/resources/aws_ecr_test.rb" "test/unit/resources/aws_ecs_cluster_test.rb" "test/unit/resources/aws_eks_cluster_test.rb" "test/unit/resources/aws_eks_clusters_test.rb" "test/unit/resources/aws_elb_test.rb" "test/unit/resources/aws_flow_log_test.rb" "test/unit/resources/aws_hosted_zones_test.rb" "test/unit/resources/aws_iam_account_alias_test.rb" "test/unit/resources/aws_iam_group_test.rb" "test/unit/resources/aws_iam_password_policy_test.rb" "test/unit/resources/aws_iam_policy_test.rb" "test/unit/resources/aws_iam_role_test.rb" "test/unit/resources/aws_iam_root_user_test.rb" "test/unit/resources/aws_iam_saml_provider_test.rb" "test/unit/resources/aws_iam_user_test.rb" "test/unit/resources/aws_kms_key_test.rb" "test/unit/resources/aws_kms_keys_test.rb" "test/unit/resources/aws_launch_configuration_test.rb" "test/unit/resources/aws_organizations_member_test.rb" "test/unit/resources/aws_rds_instance_test.rb" "test/unit/resources/aws_rds_instances_test.rb" "test/unit/resources/aws_region_test.rb" "test/unit/resources/aws_regions_test.rb" "test/unit/resources/aws_route_table_test.rb" "test/unit/resources/aws_route_tables_test.rb" "test/unit/resources/aws_s3_bucket_object_test.rb" "test/unit/resources/aws_s3_bucket_test.rb" "test/unit/resources/aws_s3_buckets_test.rb" "test/unit/resources/aws_security_group_test.rb" "test/unit/resources/aws_security_groups_test.rb" "test/unit/resources/aws_sns_subscription_test.rb" "test/unit/resources/aws_sns_topic_test.rb" "test/unit/resources/aws_sns_topics_test.rb" "test/unit/resources/aws_sqs_queue_test.rb" "test/unit/resources/aws_sts_caller_identity_test.rb" "test/unit/resources/aws_subnet_test.rb" "test/unit/resources/aws_subnets_test.rb" "test/unit/resources/aws_vpc_test.rb" "test/unit/resources/aws_vpcs_test.rb" 
Run options: --seed 22010

# Running:

..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

Fabulous run in 4.613042s, 155.6457 runs/s, 172.3375 assertions/s.

718 runs, 795 assertions, 0 failures, 0 errors, 0 skips

To run the full suite of tests, run

make doubly_sure

This test runs the unit tests, creates the target infrastructure, and runs the intergration tests. If successful, the test automatically destroy everything. If it fails, it will keep the environment up, testing then can be achieved by running:

make int_test

The AWS credentials can either be supplied via environmental variables or files located on ./aws folder.

This requires docker, docker-compose and make, see Three Musketeers Pattern for details.

Running the integration tests (after setup_integration_tests):

$ bundle exec rake test:run_integration_tests
----> Run
bundle exec inspec exec test/integration/verify --attrs test/integration/build/aws-inspec-attributes.yaml; rc=$?; if [ $rc -eq 0 ] || [ $rc -eq 101 ]; then exit 0; else exit 1; fi

Profile: Amazon Web Services  Resource Pack (inspec-aws)
Version: 0.1.0
Target:  aws://eu-west-2

  ✔  aws-vpc-1.0: Ensure AWS VPC has the correct properties.
     ✔  VPC vpc-0373aeb7284407ffd should exist
     ✔  VPC vpc-0373aeb7284407ffd should not be default
     ✔  VPC vpc-0373aeb7284407ffd cidr_block should eq "10.0.0.0/27"
     ✔  VPC vpc-0373aeb7284407ffd instance_tenancy should eq "dedicated"
     ✔  VPC vpc-0373aeb7284407ffd vpc_id should eq "vpc-0373aeb7284407ffd"
     ✔  VPC vpc-0373aeb7284407ffd state should eq "available"
     ✔  VPC vpc-0373aeb7284407ffd dhcp_options_id should eq "dopt-f557819d"
     ✔  VPC default should exist
     ✔  VPC default should be default
     ✔  VPC default vpc_id should eq "vpc-1ea06476"
     ✔  VPC vpc-0373aeb7284407ffd should exist
     ✔  VPC vpc-0373aeb7284407ffd should not be default
     ✔  VPC vpc-0373aeb7284407ffd vpc_id should eq "vpc-0373aeb7284407ffd"
...

Profile: Amazon Web Services  Resource Pack (inspec-aws)
Version: 0.1.0
Target:  aws://eu-west-2

     No tests were executed.

Profile Summary: 50 successful controls, 0 control failures, 3 controls skipped
Test Summary: 602 successful, 0 failures, 18 skipped

FAQ

Failure running "inspec exec" on my AWS profile

If an error occurs when running "inspec exec" on a newly created AWS profile, check that the AWS transport is specified as below:

inspec exec . -t aws://

If a method missing error occurs and all the steps documented above is followed try running the following command within the profile directory:

inspec vendor --overwrite

Support

The InSpec AWS resources are community-supported. For bugs and features, please open a GitHub issue and label it appropriately.

Kudos

This work builds on the InSpec 2 AWS resources that are originally shipped as part of InSpec.