mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2025-10-24 21:14:00 -07:00 
			
		
		
		
	Allow ec2 inventory to use a boto profile
This allows the EC2 inventory plugin to be used with the same configuration against different EC2 accounts Profile can be passed using --profile variable or using EC2_PROFILE environment variable e.g. ``` EC2_PROFILE=prod ansible-playbook -i ec2.py playbook.yml ``` Added documentation on profiles to EC2 dynamic inventory doc Only tries to use profiles if --profile argument is given or EC2_PROFILE is set to maintain compatibility will boto < 2.24. Works around a minor bug in boto where if you try and use a security token with a profile it fails (boto/boto#2100)
This commit is contained in:
		
					parent
					
						
							
								fd267989fb
							
						
					
				
			
			
				commit
				
					
						9c967dd054
					
				
			
		
					 2 changed files with 61 additions and 4 deletions
				
			
		|  | @ -22,6 +22,12 @@ you need to define: | |||
| 
 | ||||
|     export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus | ||||
| 
 | ||||
| If you're using boto profiles (requires boto>=2.24.0) you can choose a profile  | ||||
| using the --profile command line argument (e.g. ec2.py --profile prod) or using | ||||
| the EC2_PROFILE variable: | ||||
| 
 | ||||
|     EC2_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml | ||||
| 
 | ||||
| For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html | ||||
| 
 | ||||
| When run against a specific host, this script returns the following variables: | ||||
|  | @ -148,9 +154,20 @@ class Ec2Inventory(object): | |||
|         # Index of hostname (address) to instance ID | ||||
|         self.index = {} | ||||
| 
 | ||||
|         # Read settings and parse CLI arguments | ||||
|         self.read_settings() | ||||
|         # Parse CLI arguments and read settings | ||||
|         self.parse_cli_args() | ||||
|         self.read_settings() | ||||
| 
 | ||||
|         # boto profile to use (if any) | ||||
|         # Make sure that profile_name is not passed at all if not set | ||||
|         # as pre 2.24 boto will fall over otherwise | ||||
|         if self.args.profile: | ||||
|             if not hasattr(boto.ec2.EC2Connection, 'profile_name'): | ||||
|                 sys.stderr.write("boto version must be >= 2.24 to use profile\n") | ||||
|                 sys.exit(1) | ||||
|             self.profile = dict(profile_name=self.args.profile) | ||||
|         else: | ||||
|             self.profile = dict() | ||||
| 
 | ||||
|         # Cache | ||||
|         if self.args.refresh_cache: | ||||
|  | @ -292,6 +309,8 @@ class Ec2Inventory(object): | |||
| 
 | ||||
|         # Cache related | ||||
|         cache_dir = os.path.expanduser(config.get('ec2', 'cache_path')) | ||||
|         if self.args.profile: | ||||
|             cache_dir = os.path.join(cache_dir, 'profile_' + self.args.profile) | ||||
|         if not os.path.exists(cache_dir): | ||||
|             os.makedirs(cache_dir) | ||||
| 
 | ||||
|  | @ -373,6 +392,8 @@ class Ec2Inventory(object): | |||
|                            help='Get all the variables about a specific instance') | ||||
|         parser.add_argument('--refresh-cache', action='store_true', default=False, | ||||
|                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)') | ||||
|         parser.add_argument('--profile', action='store', default=os.environ.get('EC2_PROFILE'), | ||||
|                            help='Use boto profile for connections to EC2') | ||||
|         self.args = parser.parse_args() | ||||
| 
 | ||||
| 
 | ||||
|  | @ -405,6 +426,21 @@ class Ec2Inventory(object): | |||
|             self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region) | ||||
|         return conn | ||||
| 
 | ||||
|     def boto_fix_security_token_in_profile(self, conn): | ||||
|         ''' monkey patch for boto issue boto/boto#2100 ''' | ||||
|         profile = 'profile ' + self.profile.get('profile_name') | ||||
|         if boto.config.has_option(profile, 'aws_security_token'): | ||||
|             conn.provider.set_security_token(boto.config.get(profile, 'aws_security_token')) | ||||
|         return conn | ||||
| 
 | ||||
| 
 | ||||
|     def connect_to_aws(self, module, region): | ||||
|         conn = module.connect_to_region(region, **self.profile) | ||||
|         if 'profile_name' in self.profile: | ||||
|             conn = self.boto_fix_security_token_in_profile(conn) | ||||
|         return conn | ||||
| 
 | ||||
| 
 | ||||
|     def get_instances_by_region(self, region): | ||||
|         ''' Makes an AWS EC2 API call to the list of instances in a particular | ||||
|         region ''' | ||||
|  | @ -416,8 +452,14 @@ class Ec2Inventory(object): | |||
|                 for filter_key, filter_values in self.ec2_instance_filters.items(): | ||||
|                     reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values })) | ||||
|             else: | ||||
|                 reservations = conn.get_all_instances() | ||||
|                 conn = self.connect_to_aws(ec2, region) | ||||
| 
 | ||||
|             # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported | ||||
|             if conn is None: | ||||
|                 print("region name: %s likely not supported, or AWS is down.  connection to region failed." % region) | ||||
|                 sys.exit(1) | ||||
| 
 | ||||
|             reservations = conn.get_all_instances() | ||||
|             for reservation in reservations: | ||||
|                 for instance in reservation.instances: | ||||
|                     self.add_instance(instance, region) | ||||
|  | @ -430,12 +472,13 @@ class Ec2Inventory(object): | |||
|                 error = "Error connecting to %s backend.\n%s" % (backend, e.message) | ||||
|             self.fail_with_error(error, 'getting EC2 instances') | ||||
| 
 | ||||
| 
 | ||||
|     def get_rds_instances_by_region(self, region): | ||||
|         ''' Makes an AWS API call to the list of RDS instances in a particular | ||||
|         region ''' | ||||
| 
 | ||||
|         try: | ||||
|             conn = rds.connect_to_region(region) | ||||
|             conn = self.connect_to_aws(rds, region) | ||||
|             if conn: | ||||
|                 instances = conn.get_all_dbinstances() | ||||
|                 for instance in instances: | ||||
|  |  | |||
|  | @ -101,6 +101,20 @@ You can test the script by itself to make sure your config is correct:: | |||
| 
 | ||||
| After a few moments, you should see your entire EC2 inventory across all regions in JSON. | ||||
| 
 | ||||
| If you use boto profiles to manage multiple AWS accounts, you can pass ``--profile PROFILE`` name to the ``ec2.py`` script. An example profile might be:: | ||||
| 
 | ||||
|     [profile dev] | ||||
|     aws_access_key_id = <dev access key> | ||||
|     aws_secret_access_key = <dev secret key> | ||||
| 
 | ||||
|     [profile prod] | ||||
|     aws_access_key_id = <prod access key> | ||||
|     aws_secret_access_key = <prod secret key> | ||||
| 
 | ||||
| You can then run ``ec2.py --profile prod`` to get the inventory for the prod account, or run playbooks with: ``ansible-playbook -i 'ec2.py --profile prod' myplaybook.yml``. | ||||
| 
 | ||||
| Alternatively, use the ``EC2_PROFILE`` variable - e.g. ``EC2_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml`` | ||||
| 
 | ||||
| Since each region requires its own API call, if you are only using a small set of regions, feel free to edit ``ec2.ini`` and list only the regions you are interested in. There are other config options in ``ec2.ini`` including cache control, and destination variables. | ||||
| 
 | ||||
| At their heart, inventory files are simply a mapping from some name to a destination address. The default ``ec2.ini`` settings are configured for running Ansible from outside EC2 (from your laptop for example) -- and this is not the most efficient way to manage EC2. | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue