class AwsEc2Instance
author: Christoph Hartmann
def catch_aws_errors
TODO: DRY up, see https://github.com/chef/inspec/issues/2633
def catch_aws_errors yield rescue Aws::Errors::MissingCredentialsError # The AWS error here is unhelpful: # "unable to sign request without credentials set" Inspec::Log.error "It appears that you have not set your AWS credentials. You may set them using environment variables, or using the 'aws://region/aws_credentials_profile' target. See https://www.inspec.io/docs/reference/platforms for details." fail_resource('No AWS credentials available') rescue Aws::Errors::ServiceError => e fail_resource e.message end
def exists?
def exists? return false if instance.nil? instance.exists? end
def has_roles?
def has_roles? catch_aws_errors do 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 end
def id
def id return @instance_id if defined?(@instance_id) catch_aws_errors do if @opts.is_a?(Hash) first = @ec2_resource.instances( { filters: [{ name: 'tag:Name', values: [@opts[:name]], }], }, ).first # catch case where the instance is not known @instance_id = first.id unless first.nil? else @instance_id = @opts end end end
def initialize(opts, conn = nil)
def initialize(opts, conn = nil) @opts = opts @opts.is_a?(Hash) ? @display_name = @opts[:name] : @display_name = opts @ec2_client = conn ? conn.ec2_client : inspec_runner.backend.aws_client(Aws::EC2::Client) @ec2_resource = conn ? conn.ec2_resource : inspec_runner.backend.aws_resource(Aws::EC2::Resource, {}) @iam_resource = conn ? conn.iam_resource : inspec_runner.backend.aws_resource(Aws::IAM::Resource, {}) end
def inspec_runner
TODO: DRY up, see https://github.com/chef/inspec/issues/2633
def inspec_runner # When running under inspec-cli, we have an 'inspec' method that # returns the runner. When running under unit tests, we don't # have that, but we still have to call this to pass something # (nil is OK) to the backend. # TODO: remove with https://github.com/chef/inspec-aws/issues/216 # TODO: remove after rewrite to include AwsSingularResource inspec if respond_to?(:inspec) end
def instance
def instance catch_aws_errors { @instance ||= @ec2_resource.instance(id) } end
def security_group_ids
def security_group_ids catch_aws_errors do @security_group_ids ||= instance.security_groups.map(&:group_id) end end
def security_groups
Don't document this - it's a bit hard to use. Our current doctrine
def security_groups catch_aws_errors do @security_groups ||= instance.security_groups.map { |sg| { id: sg.group_id, name: sg.group_name } } end end
def state
def state catch_aws_errors do instance&.state&.name end end
def tags
def tags catch_aws_errors do @tags ||= instance.tags.map { |tag| { key: tag.key, value: tag.value } } end end
def to_s
def to_s "EC2 Instance #{@display_name}" end