Open ryansb opened 6 years ago
This looks similar as the proposal I did at #81, where we have a similar need for REST-based modules.
I would not make the solution cloud-specific, the solution should be generically applicable to any module, or set of modules.
Yeah, we don't have a content-hosted way to do that today in Azure either. We implemented something akin to boto profiles just for the Azure modules, but they live in ~/.azure/credentials, not next to the content.
Microsoft has since come up with "CLI profiles", but IIRC they don't actually let you store the credentials- merely a set of properties like "username/cloud", then they prompt for a password or open a browser window to complete auth and give you a 12h token which can be used transparently by the SDK. I also don't think you can have multiple of those going at a time- IIRC the CLI credentials can only have one set "active" at a time.
I proposed a similar thing a couple years ago for exactly this scenario (before proposals were a thing), and actually even had a sample implementation, but it got shot down. IIRC there were concerns around the security of carving off sensitive hostvars and blindly sending them to modules. In some ways it's a similar problem to allowing modules access to the add_host functionality; we probably need a config-based whitelist or something to enable it, set to some sane defaults. Since that's gotten a lot easier with the new config stuff, maybe people would be more open to it now.
Environment variables (as used with the block/environment
scenario) also don't fly when debugging modules. Module arguments get preserved by explode
, environment variables are passed outside of python. Presumably this also means they leak at -vvv
level.
I don't think it would be a blind-sending, any more than environment variables are already auto-sent to every executing module. I think it would be, at worst, the same security surface area as the current way that users (and AWX) ship in environment variables.
@ryansb we don't automatically ship environment variables with modules, those plugins will only get them if they execute locally via normal process inheritance. The environment
keyword would not be a change for 'local' execution but it would be very different for 'remote execution'.
https://github.com/ansible/proposals/issues/24 <= a general version of this, not just cloud but any credentials that get reused
Proposal: Common Cloud Credentials
Author: @ryansb
Date: 2017/12/18
Motivation
Current ways of handling cloud credentials for AWS and other providers is inconsistent, and some of the common usages result in accidentally creating resources in the wrong region/account
Requirements
Configuration
This would (probably) be implemented as a plugin similarly to the hostvars plugin, that can use things that are vaulted.
Alternative
Bless a few magic variable names, so we take advantage of the existing vaulted-vars and such, allowing all plugins of such-and-such cloud to reach into the vars system and demand those variables be passed if they exist. I think this would have to be implemented as a plugin that, when a task is called, checks if the module is registered as one that needs those special variables.
The blessed variables would have to be specific enough to not break existing playbooks, so something like:
Would be specific enough, and extensible to include any new provider.
Precedence (most to least specific)
~/.aws/credentials
and~/.aws/config
/etc/boto.cfg
Considered and not-quite-right
Repeated Variables
The most common way in examples & playbooks I see around is to set variables
aws_*_key
andaws_region
and use those throughout:I also have seen lots of IRC problems where people forget to copy/paste the
region
on all tasks, and are then surprised their playbook doesn't work right outside us-east-1 (the default region).Environment Variables
Today, Tower passes AWS credentials in this way. It sets the
AWS_ACCESS/SECRET_KEY
variables and those env vars are used as normal. Tower provides a nice UI for this so most users of Tower wouldn't need/notice a new way of providing cloud credentials.For sections of plays, users can do:
But that means users have to sometimes put full playbooks inside of blocks, and if they want to have separate error/rescue handling they then have to nest blocks.
YAML Anchors
YAML has a feature that lets you create prototypes based on an item, you declare it with
&your_anchor_name
and then it can be exploded into any similar type. In some tests we use a YAML anchor to share credentials among all the AWS tasks instead of repeating var-usage (not-quite-right #1)Other Considerations
Also to consider: MFA/role users. I don't want to reimplement boto profiles because madness lies down that path, but for other cloud providers we're going to have similar requirements and their MFA/SDK situation isn't as nice.