What is the best way to manage multiple Amazon Web Services (AWS) accounts through boto
?
I am familiar with BotoConfig files, which I'm using. But each file describes only a single account...and I am working with more than just the one organization. For all the usual legal, financial, and security reasons, those accounts cannot be commingled.
Currently I am using one boto
config file per account. E.g.:
~/.boto
default account~/.boto_clowncollege
for "clowncollege" account~/.boto_razorassoc
for "razorassoc" account~/.boto_xyz
for "xyz" accountThen something like:
def boto_config_path(account=None): """ Given an account name, return the path to the corresponding boto configuration file. If no account given, return the default config file. """ path = '~/.boto' + ('_' + account if account else '') clean_path = os.path.abspath(os.path.expanduser(path)) if os.path.isfile(clean_path): return clean_path else: errmsg = "cannot find boto config file {} for {}".format(clean_path, account) raise ValueError(errmsg) def aws_credentials(account=None): """ Return a tuple of AWS credentials (access key id and secret access key) for the given account. """ try: cfg = INIConfig(open(boto_config_path(account))) return ( cfg.Credentials.aws_access_key_id, cfg.Credentials.aws_secret_access_key ) except Exception: raise conn = EC2Connection(*aws_credentials('razorassoc'))
Good, bad, or indifferent? Suggested improvements?
Today, AWS launched AWS Organizations: a new way for you to centrally manage all the AWS accounts your organization owns. Now you can arrange your AWS accounts into groups called organizational units (OUs) and apply policies to OUs or directly to accounts.
How to store and manage secrets with AWS Secrets Manager. To protect secrets in AWS, configure them in AWS Secrets Manager, then insert a descriptive reference to them in the application code. For example, the password for a production database can be stored in Secrets Manager and named my_db_password_production.
updated 2015-02-06, corrected 2015-03-19 by following top section
Since boto 2.29 there is new easy way for sharing BOTO and AWS CLI credentials as described by Mike Garnaat in A New and Standardized Way to Manage Credentials in the AWS SDKs
The aim is to:
Create the file ~/.aws/credentials
(Mac/Linux) or %USERPROFILE%\.aws\credentials
(Windwos) as follows:
[default] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr region = eu-west-1 [jekyl] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr region = eu-west-1 [hyde] aws_access_key_id = AxxxZ aws_secret_access_key = CxxxZ region = eu-west-1
From now on, you may use a code like this:
import boto con = boto.connect_s3()
AWS_PROFILE
env. var(this is my favourite option keeping profile name out of code and still giving the deployer of my application a chance to pick specific profile)
$ export AWS_PROFILE=jekyl
and keep your code as simple as before:
import boto con = boto.connect_s3()
import boto con = boto.connect_s3(profile_name="jekyl")
This is all you typically need to do
The logic for picking proper credentials is described in boto issue #2292 as follows:
The loading order from highest to lowest precedence:
1.Directly passed from code
Environment variables for key/secret
Environment variables for profile
Shared credential file explicit profile
Shared credential file default profile
Config file explicit profile
Config file Credentials section
A profile passed from code overrides any set in an environment variable.
To keep things clean and simple, it is good to get rid of older methods, so remove any old style files (like ~/.aws/config
or ~/.boto
), unset environmental varialbe BOTO_CONFIG
if set and possibly also the file, to which such variable points to.
And that is really all for boto >=2.29.0
Note: Do not attempt to control location of config file by env.variable (like AWS_CONFIG_FILE
), it does not work as expected.
Following description is kept here only for those, who cannot upgrade to boto 2.29.0 or higher
Since boto 2.24.0 there is a feature called profile_name
In your ~/.boto
file you already have your [Credentials] section, this will serve as fallback option, and then [profile ] sections serving for different profiles:
[Credentials] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr [profile jekyl] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr [profile hyde] aws_access_key_id = AxxxZ aws_secret_access_key = CxxxZ
Then, when creating connection, you use this way:
import boto con = boto.connect_s3(profile_name="jekyl")
Note, that this feature is available since boto 2.24.0.
Tutorial is here http://docs.pythonboto.org/en/latest/boto_config_tut.html?highlight=profile
There are even some notes about using keyrings, but I will first get used to this profile stuff, which I was dreaming of few years.
AWSCLI became really great tool. As format of config file is almost the same, I use it in following way:
~/.aws/config
file as created by AWSCLI (this is default location)[default]
and rename it to [Credentials]
(leaving the same values inside).BOTO_CONFIG
variable to point to this ~/.aws/config
file.The ~/.boto
would then become `~/.aws/config with following content:
[default] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr [Credentials] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr [profile jekyl] aws_access_key_id = AxxxA aws_secret_access_key = Zxxxr [profile hyde] aws_access_key_id = AxxxZ aws_secret_access_key = CxxxZ
This way, it gets shared for both AWSCLI and boto including profiles.
In the future, boto will provide better tools to help you manage multiple credentials but at the moment, there are a couple of environment variables that might help out.
First, you can set BOTO_CONFIG to point to a boto config file that you want to use and it will override any config file found in the normal locations.
Secondly, you can set BOTO_PATH to a colon-separated list of places to look for a boto config file and it will search there first, prior to the normal search locations.
Neither of those give you exactly what you want but it may make it easier to accomplish with a bit less code.
If you have ideas about how you would like this to work in boto, please let me know!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With