backstage: πŸ› Bug Report: `AwsOrganizationCloudAccountProcessor` no longer respects provided `roleArn` in configuration

πŸ“œ Description

In our Backstage instance, we utilize the AwsOrganizationCloudAccountProcessor to consume AWS accounts from our Principal Org (Backstage runs in a different AWS account). To do this, we assume a role outside of the AWS account our Backstage instance runs in order to have access to the ListAccounts organization endpoint.

Here is what our configuration looks like for AwsOrganizationCloudAccountProcessor

catalog:
  processors:
    awsOrganization:
      provider:
        roleArn: 'arn:aws:iam::<other-account-id>:role/<list-organizations-role-name>'

After upgrading to 1.14.1, we noticed that there was now new necessary required configuration to support the new DefaultAwsCredentialsManager since the AwsOrganizationCloudAccountProcessor uses the credentials manager to find the Credentials to use for the <other-account-id> specified in our roleArn (source)

However, the creds determined there do not respect the catalog.processors.awsOrganization.provider.roleArn configuration since awsCredentialsManager.getCredentialProvider() does not use the provided ARN to assume the role unless we use the following full set of configuration

catalog:
  processors:
    awsOrganization:
      provider:
        roleArn: 'arn:aws:iam::<other-account-id>:role/<list-organizations-role-name>'

aws:
  accounts:
    - accountId: "<other-account-id>"
      roleName: <list-organizations-role-name>

We want to always utilize the default provider credential chain and be able to optionally assume roles for specific processors/providers. This configuration makes it so that is not possible, we will always cache credentials assumed as <list-organizations-role-name> anywhere else we want to access the <other-account-id> AWS account.

πŸ‘ Expected behavior

The AwsOrganizationCloudAccountProcessor should still properly assume the catalog.processors.awsOrganization.provider.roleArn role with the following minimal configuration

catalog:
  processors:
    awsOrganization:
      provider:
        roleArn: 'arn:aws:iam::<other-account-id>:role/<list-organizations-role-name>'

aws:
  accounts:
    - accountId: "<other-account-id>"

This makes it so that we always use the default credentials chain and are able to assume arbitrary roles for specific purposes

πŸ‘Ž Actual Behavior with Screenshots

We must globally configure a specific roleName for a specific accountId, which prevents us from having dedicated roles for specific providers/processors

Without specifying roleName in the aws.accounts configuration, we receive the following error:

2023-05-31T20:40:36.328Z catalog warn Processor AwsOrganizationCloudAccountProcessor threw an error while reading aws-cloud-accounts:<ID>; caused by AccessDeniedException: You don't have permissions to access this resource. 

πŸ‘Ÿ Reproduction steps

  1. create a specific AWS Role that grants ListAccounts access that Backstage should assume
  2. add the following config
catalog:
  processors:
    awsOrganization:
      provider:
        roleArn: 'arn:aws:iam::<other-account-id>:role/<list-organizations-role-name>'

aws:
  accounts:
    - accountId: "<other-account-id>"
  1. integrate the AwsOrganizationCloudAccountProcessor with a location entity for the org to consume accounts from
  2. Run backstage with AWS credentials in the environment for a role that can assume arn:aws:iam::<other-account-id>:role/<list-organizations-role-name>
  3. hit the error

πŸ“ƒ Provide the context for the Bug.

Currently, the duplication of specifying the roleArn and roleName is annoying and not ideal, but moving forward, we would love to be able to not be tied to a specific role for any given AWS account for the DefaultAwsCredentialsManager.

We heavily make use of AWS roles to limit exposure and would like to not grant multiple unrelated permissions globally to our application role if not necessary.

πŸ–₯️ Your Environment

OS: Darwin 22.4.0 - darwin/x64
node: v16.14.0
backstage: 1.14.1
Dependencies:
    @backstage/app-defaults: 1.3.1
    @backstage/backend-app-api: 0.4.3
    @backstage/backend-common: 0.18.5
    @backstage/backend-dev-utils: 0.1.1
    @backstage/backend-plugin-api: 0.5.2
    @backstage/backend-tasks: 0.5.2
    @backstage/backend-test-utils: 0.1.37
    @backstage/catalog-client: 1.4.1
    @backstage/catalog-model: 1.2.0, 1.3.0
    @backstage/cli-common: 0.1.12
    @backstage/cli-node: 0.1.0
    @backstage/cli: 0.22.7
    @backstage/config-loader: 1.3.0
    @backstage/config: 1.0.7
    @backstage/core-app-api: 1.8.0
    @backstage/core-components: 0.12.4, 0.12.5, 0.13.1
    @backstage/core-plugin-api: 1.0.6, 1.5.1
    @backstage/dev-utils: 1.0.15
    @backstage/errors: 1.1.5
    @backstage/eslint-plugin: 0.1.3
    @backstage/integration-aws-node: 0.1.3
    @backstage/integration-react: 1.1.13
    @backstage/integration: 1.4.5
    @backstage/plugin-analytics-module-ga: 0.1.29
    @backstage/plugin-api-docs-module-protoc-gen-doc: 0.1.2
    @backstage/plugin-api-docs: 0.9.3
    @backstage/plugin-app-backend: 0.3.45
    @backstage/plugin-auth-backend: 0.18.3
    @backstage/plugin-auth-node: 0.2.14
    @backstage/plugin-catalog-backend-module-aws: 0.2.0
    @backstage/plugin-catalog-backend-module-github: 0.3.0
    @backstage/plugin-catalog-backend: 1.9.1
    @backstage/plugin-catalog-common: 1.0.13
    @backstage/plugin-catalog-graph: 0.2.30
    @backstage/plugin-catalog-node: 1.3.6
    @backstage/plugin-catalog-react: 1.2.1, 1.6.0
    @backstage/plugin-catalog: 1.11.0
    @backstage/plugin-devtools-backend: 0.1.0
    @backstage/plugin-devtools-common: 0.1.0
    @backstage/plugin-devtools: 0.1.0
    @backstage/plugin-events-backend-module-github: 0.1.7
    @backstage/plugin-events-backend-test-utils: 0.1.7
    @backstage/plugin-events-backend: 0.2.6
    @backstage/plugin-events-node: 0.2.6
    @backstage/plugin-explore-backend: 0.0.7
    @backstage/plugin-explore-common: 0.0.1
    @backstage/plugin-explore-react: 0.0.28
    @backstage/plugin-explore: 0.4.3
    @backstage/plugin-github-actions: 0.5.18
    @backstage/plugin-github-pull-requests-board: 0.1.12
    @backstage/plugin-home: 0.5.2
    @backstage/plugin-kubernetes-backend: 0.11.0
    @backstage/plugin-kubernetes-common: 0.6.3
    @backstage/plugin-kubernetes: 0.9.1
    @backstage/plugin-org: 0.6.8
    @backstage/plugin-pagerduty: 0.5.11
    @backstage/plugin-permission-common: 0.7.5
    @backstage/plugin-permission-node: 0.7.8
    @backstage/plugin-permission-react: 0.4.12
    @backstage/plugin-proxy-backend: 0.2.39
    @backstage/plugin-scaffolder-backend: 1.14.0
    @backstage/plugin-scaffolder-common: 1.3.0
    @backstage/plugin-scaffolder-node: 0.1.3
    @backstage/plugin-scaffolder-react: 1.4.0
    @backstage/plugin-scaffolder: 1.13.1
    @backstage/plugin-search-backend-module-catalog: 0.1.1
    @backstage/plugin-search-backend-module-elasticsearch: 1.3.0
    @backstage/plugin-search-backend-module-explore: 0.1.1
    @backstage/plugin-search-backend-module-pg: 0.5.6
    @backstage/plugin-search-backend-node: 1.2.1
    @backstage/plugin-search-backend: 1.3.1
    @backstage/plugin-search-common: 1.2.3
    @backstage/plugin-search-react: 1.6.0
    @backstage/plugin-search: 1.3.0
    @backstage/plugin-shortcuts: 0.3.10
    @backstage/plugin-tech-insights-backend-module-jsonfc: 0.1.29
    @backstage/plugin-tech-insights-backend: 0.5.11
    @backstage/plugin-tech-insights-common: 0.2.10
    @backstage/plugin-tech-insights-node: 0.4.3
    @backstage/plugin-tech-insights: 0.3.10
    @backstage/plugin-user-settings-backend: 0.1.9
    @backstage/plugin-user-settings: 0.7.3
    @backstage/release-manifests: 0.0.9
    @backstage/test-utils: 1.3.1
    @backstage/theme: 0.2.19, 0.3.0
    @backstage/types: 1.0.2
    @backstage/version-bridge: 1.0.4

πŸ‘€ Have you spent some time to check if this bug has been raised before?

  • I checked and didn’t find similar issue

🏒 Have you read the Code of Conduct?

Are you willing to submit PR?

None

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Reactions: 2
  • Comments: 24 (22 by maintainers)

Most upvoted comments

thank you @alecjacobs5401, the location was the missing part! I’ll create a PR to update the Readme

@wanisfahmyDE Thats about what we have configured for our app-config.yaml and packages/backend/src/plugins/catalog.ts.

Do you have a Location entity defined to tell the processor to where to consume AWS accounts from?

You’ll need one that looks like

apiVersion: backstage.io/v1alpha1
kind: Location
metadata:
  name: aws-organization
spec:
  type: aws-cloud-accounts
  target: <aws-org-id>

Can’t find the docs for it specifically, but some code spelunking highlights the need