From 6804d6955769012fba48148444fa5a078aec74f6 Mon Sep 17 00:00:00 2001 From: "Rune T. Sorensen" Date: Mon, 20 Mar 2017 22:19:40 +0100 Subject: [PATCH] [cloud][contrib] IAM role support for EC2 dynamic inventory (#15196) * EC2 inventory can now connect using an IAM role * Fix comment indentation * Make sure that Ec2Inventory.iam_role is always defined * Add missing import --- contrib/inventory/ec2.ini | 5 +++++ contrib/inventory/ec2.py | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/contrib/inventory/ec2.ini b/contrib/inventory/ec2.ini index f3171eac10..1cb9309dcd 100644 --- a/contrib/inventory/ec2.ini +++ b/contrib/inventory/ec2.ini @@ -179,6 +179,11 @@ stack_filters = False # (ex. webservers15, webservers1a, webservers123 etc) # instance_filters = tag:Name=webservers1* +# An IAM role can be assumed, so all requests are run as that role. +# This can be useful for connecting across different accounts, or to limit user +# access +# iam_role = role-arn + # A boto configuration profile may be used to separate out credentials # see http://boto.readthedocs.org/en/latest/boto_config_tut.html # boto_profile = some-boto-profile-name diff --git a/contrib/inventory/ec2.py b/contrib/inventory/ec2.py index 03b9820412..be1821caee 100755 --- a/contrib/inventory/ec2.py +++ b/contrib/inventory/ec2.py @@ -132,6 +132,7 @@ from boto import ec2 from boto import rds from boto import elasticache from boto import route53 +from boto import sts import six from ansible.module_utils import ec2 as ec2_utils @@ -421,6 +422,12 @@ class Ec2Inventory(object): else: self.replace_dash_in_groups = True + # IAM role to assume for connection + if config.has_option('ec2', 'iam_role'): + self.iam_role = config.get('ec2', 'iam_role') + else: + self.iam_role = None + # Configure which groups should be created. group_by_options = [ 'group_by_instance_id', @@ -548,6 +555,13 @@ class Ec2Inventory(object): connect_args['profile_name'] = self.boto_profile self.boto_fix_security_token_in_profile(connect_args) + if self.iam_role: + sts_conn = sts.connect_to_region(region, **connect_args) + role = sts_conn.assume_role(self.iam_role, 'ansible_dynamic_inventory') + connect_args['aws_access_key_id'] = role.credentials.access_key + connect_args['aws_secret_access_key'] = role.credentials.secret_key + connect_args['security_token'] = role.credentials.session_token + conn = module.connect_to_region(region, **connect_args) # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported if conn is None: