-
Notifications
You must be signed in to change notification settings - Fork 427
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using multiple AWS profiles #204
Comments
Did you find a way to do this? Im facing this issue right now too. |
pynamodb uses botocore under the hood, which should honor environment variables like AWS_DEFAULT_PROFILE. Have you tried something like: AWS_DEFAULT_PROFILE=alt-profile python my-pynamodb-code.py |
It would be better if a pre-configured boto session could be passed somewhere rather than relying on the user environment. |
@use-sparingly yeah that would be nice. The model Meta has a If you have an immediate need and don't want to set the environment variable, you could always monkeypatch |
I ran into this too. This is contorted around some child classes, but here's the gist of it:
A cleaner option would be appreciated. |
More control would also be preferable in the case where you have to assume role before using pynamodb, as it stands @bedge solution works okay for the time being. |
@brandond can you explain your comment a little more and/or write an example code? I'm lost.
|
@alexanderfanz since _session is now thread-local, I don't think it's safe to set within the model any longer. Monkeypatching is probably your best option. Something like this - either in the module that holds your model definitions as shown in this example, or somewhere else that's called once during app startup - should do the trick. from pynamodb.models import Model
from pynamodb.attributes import UnicodeAttribute, NumberAttribute
class MyModel(Model):
class Meta:
table_name = 'mytable'
group = UnicodeAttribute(hash_key=True)
id = NumberAttribute(range_key=True)
name = UnicodeAttribute()
def monkeypatch_connection(profile=None):
from botocore.session import Session
from pynamodb.connection.base import Connection
@property
def session(self):
if getattr(self._local, 'session', None) is None:
self._local.session = Session(profile=profile)
return self._local.session
Connection.session = session
monkeypatch_connection(profile='my-aws-profile') |
In general, we would love a good way of performing a role assumption and caching credentials. I would be happy to submit a PR for this if I knew where to look. Profiles aren't great for programmatic and dynamic credential needs. |
Any updates for this issue? |
@garrettheel, any thoughts on that? I would rather have an API where models aren't dealing with auth or host. For that we'd need a public API for setting it globally. A context manager which overrides things like that in thread local-storage might be a good idea too. What do you think? |
I'm not sure that I fully understand the use case here, so I'd want to gather a little more information. We intentionally expose as little of the boto/botocore interface as possible so that it's possible to optimize/change this under the hood without breaking users. Is is that we want to configure a specific |
"Is there a desire to apply different profiles to different model classes/instances?"
|
Gotcha. We already allow configuring region, host, etc. in |
From my point of view, the most flexible approach is to be able to pass a whole Boto session object. It would also be beneficial to be able to connect tables to multiple DynamoDB instances from different accounts. Therefore, it would be great to be able to bind the Boto session and tablename at runtime. Perhaps on the method (E.g. |
PynamoDB models are also effectively "tables", i.e. they deal with the details of how tables and their indices are defined. Perhaps instead of trying to create a new "table" class (do we duplicate the get/query methods to be on this new class? should model subclass table?) it should be encouraged to define new model subclasses in runtime with their own metas? |
+1 on this, want to use dynamic credentials via IAM roles assigned to cognito users. Without this feature I'm going to have to use the regular boto3 api |
really need this for code that interact with dynamodb tables in multiple accounts |
not sure if it helps but the solution in code is actually really simple from what I could tell. The only issue is that it doesn't handle multiple profiles well (which was also mentioned). I just add this line before I'm retrieving any items or saving anything to table using the PynamoDB model. os.environ['AWS_PROFILE'] = 'my-profile' For multiple profiles though, maybe there's actually a simple workaround. Like creating a context manager, which sets the |
One use case for being able to set the session is when you're using the AWS Multi-Account Strategy. This leads to the pattern of having one account that contains your (possibly serverless) application, and multiple single-tenancy client accounts (for security, data sovereignty issues). Combine that with assumed roles with minimum IAM privileges and separate dev, test and prod accounts, and the botocore session you wish to use can change from one lambda invocation to the next. In a case like this, setting the session becomes more complex that simply exporting environment variables or setting profile names, and so it makes more sense to abstract the session setting to a different module so that you don't need to deal with it every time you invoke a Model. This should also save you (the developers) a lot of effort - why reimplement all the code to use profiles, session tokens, credentials, etc when it's already implemented in botocore.session |
I've configured multiple AWS credential profiles on my system and usually select the right one via named profiles or environment variables such das
export AWS_DEFAULT_PROFILE=foo
.However, my created
User
Model will be fetched from my default configuration.Model definition:
How can I select the correct AWS profile?
The text was updated successfully, but these errors were encountered: