Percona-Lab / mongodb_consistent_backup

A tool for performing consistent backups of MongoDB Clusters or Replica Sets
https://www.percona.com
Apache License 2.0
276 stars 81 forks source link

S3 upload does not support using credentials from IAM role #259

Open warp3r opened 6 years ago

warp3r commented 6 years ago

Hi there,

when trying to use mongodb-consistent-backup in AWS , with support enabled for S3 upload and using credentials in IAM role of an EC2 instance rather than explicit key and access tokens, it fails.

Checking the S3Session.py file I see

                self._conn = boto.s3.connect_to_region(
                    self.region,
                    aws_access_key_id=self.access_key,
                    aws_secret_access_key=self.secret_key,
                    is_secure=self.secure,
                    calling_format=self.calling_format

This way only explicit AWS keys will work with mongodb-consistent-backup , which is an anti-pattern when working inside AWS. Using IAM roles avoids the need of rotating keys as this is automatically performed by AWS.

Take this link as documentation (even if its for the PHP SDK, it also works for python):

https://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/credentials.html#instance-profile-credentials

My proposal is to change the following lines in S3.py:

        if None in (self.access_key, self.secret_key, self.region):
            raise OperationError("Invalid or missing AWS S3 access key, secret key or region detected!")

to

        if None in (self.region):
            raise OperationError("Invalid or missing AWS region detected!")

and also change the following ins S3Session.py

                self._conn = boto.s3.connect_to_region(
                    self.region,
                    aws_access_key_id=self.access_key,
                    aws_secret_access_key=self.secret_key,
                    is_secure=self.secure,
                    calling_format=self.calling_format

for something similar to:

                if aws_access_key_id is not None and aws_secret_access_key is not None:
                  self._conn = boto.s3.connect_to_region(
                    self.region,
                    aws_access_key_id=self.access_key,
                    aws_secret_access_key=self.secret_key,
                    is_secure=self.secure,
                    calling_format=self.calling_format
                    ...
                else:
                  self._conn = boto.s3.connect_to_region(
                    self.region,
                    is_secure=self.secure,
                    calling_format=self.calling_format
                    ...

I may fork the code and do a PR myself in the following weeks, just wanted to open the ticket in case somebody has the time to do so before.

kind regards