EnterpriseDB / barman

Barman - Backup and Recovery Manager for PostgreSQL
https://www.pgbarman.org/
GNU General Public License v3.0
2.07k stars 191 forks source link

barman-cli-cloud does not work with IMDSv2 #949

Open smcaine opened 3 months ago

smcaine commented 3 months ago

Hi,

I want to be able to ship backups to S3. In AWS we use recommended IMDSv2 (http token required) on all of our EC2 instances, we do not store AWS credentials on any instances or containers, this is not recommended, we only use IRSA to auth to other AWS services.

barman-cli-cloud only works like this if i set http-token as optional in my EC2 metadata config, see here for more details:

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html

Please can some logic be added to fix this to work with a token required?

**Updated

add flag for aws irsa:

    s3_arguments.add_argument(
        "--aws-irsa",
        help="bypasses credentials/profile and uses iam service account",
        action="store_true",
        default=False,
    )

and then just condition to use irsa or not, which can use local environment variables and sts to get a session:

      # barman/cloud_providers/aws_s3.py
        if self.aws_irsa:
            client = boto3.client('sts')
            with open(os.getenv("AWS_WEB_IDENTITY_TOKEN_FILE"), 'r') as content_file:
                web_identity_token = content_file.read()

            response = client.assume_role_with_web_identity(
                    RoleArn=os.environ['AWS_ROLE_ARN'],
                    RoleSessionName='barman',
                    WebIdentityToken=web_identity_token,
                    # DurationSeconds=3600 # defaults to an hour, must not be greater than 
                    # the iam role max duration session (this is also default 1 hour)
                )
            credentials = response['Credentials']
            session = boto3.Session(  aws_access_key_id=credentials['AccessKeyId'],
                                        aws_secret_access_key=credentials['SecretAccessKey'],
                                        aws_session_token=credentials['SessionToken'])
        else:
            session = boto3.Session(profile_name=self.profile_name)

        self.s3 = session.resource("s3", endpoint_url=self.endpoint_url, config=config)

thanks!