From 9d7109eb17322b9b2a2243c30e509d9171355cf5 Mon Sep 17 00:00:00 2001 From: "Maxine E. Aubrey" Date: Fri, 23 Oct 2020 15:14:21 +0200 Subject: [PATCH 1/7] aws_ssm: add profile support in connections --- plugins/connection/aws_ssm.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/plugins/connection/aws_ssm.py b/plugins/connection/aws_ssm.py index 1d96cc5a223..720a09eb093 100644 --- a/plugins/connection/aws_ssm.py +++ b/plugins/connection/aws_ssm.py @@ -53,6 +53,11 @@ vars: - name: ansible_aws_ssm_plugin default: '/usr/local/bin/session-manager-plugin' + profile: + description: Sets AWS profile to use. + vars: + - name: ansible_aws_ssm_profile + default: '' retries: description: Number of attempts to connect. default: 3 @@ -304,10 +309,10 @@ def start_session(self): raise AnsibleError("failed to find the executable specified %s." " Please verify if the executable exists and re-try." % executable) - profile_name = '' + profile_name = self.get_option('profile') region_name = self.get_option('region') ssm_parameters = dict() - client = self._get_boto_client('ssm', region_name=region_name) + client = self._get_boto_client('ssm', region_name=region_name, profile_name=profile_name) self._client = client response = client.start_session(Target=self.instance_id, Parameters=ssm_parameters) self._session_id = response['SessionId'] @@ -504,7 +509,7 @@ def _get_url(self, client_method, bucket_name, out_path, http_method): client = self._get_boto_client('s3', region_name) return client.generate_presigned_url(client_method, Params={'Bucket': bucket_name, 'Key': out_path}, ExpiresIn=3600, HttpMethod=http_method) - def _get_boto_client(self, service, region_name=None): + def _get_boto_client(self, service, region_name=None, profile_name=None): ''' Gets a boto3 client based on the STS token ''' aws_access_key_id = self.get_option('access_key_id') @@ -518,12 +523,15 @@ def _get_boto_client(self, service, region_name=None): if aws_session_token is None: aws_session_token = os.environ.get("AWS_SESSION_TOKEN", None) - client = boto3.client( - service, + session = boto3.session.Session( aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, aws_session_token=aws_session_token, region_name=region_name, + profile_name=profile_name + ) + client = session.client( + service, config=Config(signature_version="s3v4") ) return client From ce0f311647d09275534e137d5d11d5e7034dcd8d Mon Sep 17 00:00:00 2001 From: Maxine Aubrey Date: Tue, 27 Oct 2020 20:51:48 +0100 Subject: [PATCH 2/7] aws_ssm: fix entry for profile --- plugins/connection/aws_ssm.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/connection/aws_ssm.py b/plugins/connection/aws_ssm.py index 720a09eb093..74d7d749999 100644 --- a/plugins/connection/aws_ssm.py +++ b/plugins/connection/aws_ssm.py @@ -54,10 +54,9 @@ - name: ansible_aws_ssm_plugin default: '/usr/local/bin/session-manager-plugin' profile: - description: Sets AWS profile to use. vars: - name: ansible_aws_ssm_profile - default: '' + version_added: 1.5.0 retries: description: Number of attempts to connect. default: 3 From bd5db9ee27345dcbf0aa35aea60e3e21d21326a3 Mon Sep 17 00:00:00 2001 From: "Maxine E. Aubrey" Date: Wed, 28 Oct 2020 11:50:25 +0100 Subject: [PATCH 3/7] aws_ssm: readd description to profile entry --- plugins/connection/aws_ssm.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/connection/aws_ssm.py b/plugins/connection/aws_ssm.py index 74d7d749999..83cafa1eed9 100644 --- a/plugins/connection/aws_ssm.py +++ b/plugins/connection/aws_ssm.py @@ -54,6 +54,7 @@ - name: ansible_aws_ssm_plugin default: '/usr/local/bin/session-manager-plugin' profile: + description: Sets AWS profile to use. vars: - name: ansible_aws_ssm_profile version_added: 1.5.0 From 909ac4e8b4e933825315da947c5518189b5e1ead Mon Sep 17 00:00:00 2001 From: Maxine Aubrey Date: Mon, 16 Nov 2020 21:01:11 +0100 Subject: [PATCH 4/7] aws_ssm: fallback value when profile_name is unset `cmd` in `start_session` needs `profile_name` to be set to a string we oblige by having a fallback when it's set to None, changing it to be an empty string instead --- plugins/connection/aws_ssm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/connection/aws_ssm.py b/plugins/connection/aws_ssm.py index 83cafa1eed9..a93d87ef877 100644 --- a/plugins/connection/aws_ssm.py +++ b/plugins/connection/aws_ssm.py @@ -309,7 +309,7 @@ def start_session(self): raise AnsibleError("failed to find the executable specified %s." " Please verify if the executable exists and re-try." % executable) - profile_name = self.get_option('profile') + profile_name = self.get_option('profile') or '' region_name = self.get_option('region') ssm_parameters = dict() client = self._get_boto_client('ssm', region_name=region_name, profile_name=profile_name) From c0b0945c0eb009694b9b4220af2032202413cafe Mon Sep 17 00:00:00 2001 From: Maxine Aubrey Date: Mon, 16 Nov 2020 21:03:04 +0100 Subject: [PATCH 5/7] aws_ssm: set profile for all clients not all uses of _get_boto_client had a profile passed to them, now s3 sessions will also use the specified profile --- plugins/connection/aws_ssm.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/plugins/connection/aws_ssm.py b/plugins/connection/aws_ssm.py index a93d87ef877..d8c417c796d 100644 --- a/plugins/connection/aws_ssm.py +++ b/plugins/connection/aws_ssm.py @@ -503,10 +503,10 @@ def _flush_stderr(self, subprocess): return stderr - def _get_url(self, client_method, bucket_name, out_path, http_method): + def _get_url(self, client_method, bucket_name, out_path, http_method, profile_name): ''' Generate URL for get_object / put_object ''' region_name = self.get_option('region') or 'us-east-1' - client = self._get_boto_client('s3', region_name) + client = self._get_boto_client('s3', region_name=region_name, profile_name=profile_name) return client.generate_presigned_url(client_method, Params={'Bucket': bucket_name, 'Key': out_path}, ExpiresIn=3600, HttpMethod=http_method) def _get_boto_client(self, service, region_name=None, profile_name=None): @@ -544,18 +544,20 @@ def _file_transport_command(self, in_path, out_path, ssm_action): s3_path = path_unescaped.replace('\\', '/') bucket_url = 's3://%s/%s' % (self.get_option('bucket_name'), s3_path) + profile_name = self.get_option('profile') + if self.is_windows: put_command = "Invoke-WebRequest -Method PUT -InFile '%s' -Uri '%s' -UseBasicParsing" % ( - in_path, self._get_url('put_object', self.get_option('bucket_name'), s3_path, 'PUT')) + in_path, self._get_url('put_object', self.get_option('bucket_name'), s3_path, 'PUT', profile_name)) get_command = "Invoke-WebRequest '%s' -OutFile '%s'" % ( - self._get_url('get_object', self.get_option('bucket_name'), s3_path, 'GET'), out_path) + self._get_url('get_object', self.get_option('bucket_name'), s3_path, 'GET', profile_name), out_path) else: put_command = "curl --request PUT --upload-file '%s' '%s'" % ( - in_path, self._get_url('put_object', self.get_option('bucket_name'), s3_path, 'PUT')) + in_path, self._get_url('put_object', self.get_option('bucket_name'), s3_path, 'PUT', profile_name)) get_command = "curl '%s' -o '%s'" % ( - self._get_url('get_object', self.get_option('bucket_name'), s3_path, 'GET'), out_path) + self._get_url('get_object', self.get_option('bucket_name'), s3_path, 'GET', profile_name), out_path) - client = self._get_boto_client('s3') + client = self._get_boto_client('s3', profile_name=profile_name) if ssm_action == 'get': (returncode, stdout, stderr) = self.exec_command(put_command, in_data=None, sudoable=False) with open(to_bytes(out_path, errors='surrogate_or_strict'), 'wb') as data: From e6dfc25731ea1b05335124afd977efce1eb01ebb Mon Sep 17 00:00:00 2001 From: Maxine Aubrey Date: Wed, 24 Feb 2021 16:19:10 +0100 Subject: [PATCH 6/7] changelog --- changelogs/fragments/278-aws_ssm-profile-support.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/278-aws_ssm-profile-support.yml diff --git a/changelogs/fragments/278-aws_ssm-profile-support.yml b/changelogs/fragments/278-aws_ssm-profile-support.yml new file mode 100644 index 00000000000..4056065172c --- /dev/null +++ b/changelogs/fragments/278-aws_ssm-profile-support.yml @@ -0,0 +1,2 @@ +minor_changes: +- aws_ssm connection plugin - add support for specifying a profile to be used when connecting (https://github.com/ansible-collections/community.aws/pull/278). From 8a9f5f9aef0033da2bf4a8154b6e292978167223 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sat, 10 Apr 2021 08:28:16 +0200 Subject: [PATCH 7/7] Avoid setting profile_name when profile isn't set --- plugins/connection/aws_ssm.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/connection/aws_ssm.py b/plugins/connection/aws_ssm.py index d8c417c796d..b013ff5a71a 100644 --- a/plugins/connection/aws_ssm.py +++ b/plugins/connection/aws_ssm.py @@ -522,14 +522,19 @@ def _get_boto_client(self, service, region_name=None, profile_name=None): aws_secret_access_key = os.environ.get("AWS_SECRET_ACCESS_KEY", None) if aws_session_token is None: aws_session_token = os.environ.get("AWS_SESSION_TOKEN", None) + if not profile_name: + profile_name = os.environ.get("AWS_PROFILE", None) - session = boto3.session.Session( + session_args = dict( aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, aws_session_token=aws_session_token, region_name=region_name, - profile_name=profile_name ) + if profile_name: + session_args['profile_name'] = profile_name + session = boto3.session.Session(**session_args) + client = session.client( service, config=Config(signature_version="s3v4")