def configure_generic_account(sts, event, region, role): """ Fetches the kms_arn from the deployment account main region and adds the it plus the deployment_account_id parameter to the target account so it can be consumed in CloudFormation. These are required for the global.yml in all target accounts. """ try: deployment_account_role = sts.assume_cross_account_role( 'arn:aws:iam::{0}:role/{1}'.format( event['deployment_account_id'], event['cross_account_access_role'] ), 'configure_generic' ) parameter_store_deployment_account = ParameterStore( event['deployment_account_region'], deployment_account_role ) parameter_store_target_account = ParameterStore( region, role ) kms_arn = parameter_store_deployment_account.fetch_parameter('/cross_region/kms_arn/{0}'.format(region)) except (ClientError, ParameterNotFoundError): raise GenericAccountConfigureError( 'Account {0} cannot yet be bootstrapped ' 'as the Deployment Account has not yet been bootstrapped. ' 'Have you moved your Deployment account into the deployment OU?'.format(event['account_id']) ) parameter_store_target_account.put_parameter('kms_arn', kms_arn) parameter_store_target_account.put_parameter('deployment_account_id', event['deployment_account_id'])
def configure_generic_account(sts, event, region, role): """ Fetches the kms_arn from the deployment account main region and adds the it plus the deployment_account_id parameter to the target account so it can be consumed in CloudFormation. These are required for the global.yml in all target accounts. """ try: deployment_account_id = event['deployment_account_id'] cross_account_access_role = event['cross_account_access_role'] role_arn = f'arn:{PARTITION}:iam::{deployment_account_id}:role/{cross_account_access_role}' deployment_account_role = sts.assume_cross_account_role( role_arn=role_arn, role_session_name='configure_generic') parameter_store_deployment_account = ParameterStore( event['deployment_account_region'], deployment_account_role) parameter_store_target_account = ParameterStore(region, role) kms_arn = parameter_store_deployment_account.fetch_parameter( f'/cross_region/kms_arn/{region}') bucket_name = parameter_store_deployment_account.fetch_parameter( f'/cross_region/s3_regional_bucket/{region}') except (ClientError, ParameterNotFoundError): raise GenericAccountConfigureError( f'Account {event["account_id"]} cannot yet be bootstrapped ' 'as the Deployment Account has not yet been bootstrapped. ' 'Have you moved your Deployment account into the deployment OU?' ) from None parameter_store_target_account.put_parameter('kms_arn', kms_arn) parameter_store_target_account.put_parameter('bucket_name', bucket_name) parameter_store_target_account.put_parameter( 'deployment_account_id', event['deployment_account_id'])
def ensure_generic_account_can_be_setup(sts, config, account_id): """ If the target account has been configured returns the role to assume """ try: return sts.assume_cross_account_role( 'arn:aws:iam::{0}:role/{1}'.format( account_id, config.cross_account_access_role), 'base_update') except ClientError as error: raise GenericAccountConfigureError(error)
def ensure_generic_account_can_be_setup(sts, config, account_id): """ If the target account has been configured returns the role to assume """ try: return sts.assume_cross_account_role( 'arn:aws:iam::{0}:role/{1}'.format( account_id, config.cross_account_access_role), 'base_update') except BaseException: raise GenericAccountConfigureError( 'Generic Account cannot yet be setup, ' 'Base stack is not present')
def _create_change_set(self): """Creates a Cloudformation change set from a template """ LOGGER.debug("%s - calling _create_change_set for %s", self.account_id, self.stack_name) try: self.template_url = self.template_url if self.template_url is not None else self.get_template_url( ) if self.template_url: self.validate_template() self.client.create_change_set( StackName=self.stack_name, TemplateURL=self.template_url, Parameters=self.parameters if self.parameters is not None else self.get_parameters(), Capabilities=[ 'CAPABILITY_NAMED_IAM', ], Tags=[{ 'Key': 'createdBy', 'Value': 'ADF' }], ChangeSetName=self.stack_name, ChangeSetType=self._get_change_set_type()) self._wait_change_set() return True return False except ClientError as error: raise GenericAccountConfigureError(error) except WaiterError as error: err = error.last_response if CloudFormation._change_set_failed_due_to_empty( err["Status"], err["StatusReason"]): LOGGER.debug( "%s - The submitted information does not contain changes.", self.account_id) self._delete_change_set() return False LOGGER.error("%s - ERROR: %s", self.account_id, err["StatusReason"], exc_info=1) self._delete_change_set() raise