Grafana can only directly query CloudWatch metrics from the AWS account it’s configured in, forcing you to set up separate Grafana instances for each account or dig into complex cross-account IAM roles.
Let’s see how to make Grafana talk to CloudWatch in other AWS accounts. We’ll use a scenario where your Grafana instance is in Account-A and you want to pull metrics from Account-B and Account-C.
First, you need a Grafana instance running, with the CloudWatch data source plugin installed. If you don’t have it, grafana-cli plugins install grafana-cloudwatch-datasource will get it for you.
The Core Problem: IAM Permissions
Grafana’s CloudWatch data source needs IAM permissions to cloudwatch:ListMetrics and cloudwatch:GetMetricStatistics (and a few others, but these are the main ones). When Grafana is running outside AWS (e.g., on-prem or in another cloud), you typically provide these via an IAM user’s access key and secret key.
When Grafana is inside AWS (e.g., on an EC2 instance or in EKS), it usually assumes an IAM role attached to the EC2 instance or Kubernetes service account. This is the preferred method.
The challenge for cross-account access is giving the Grafana instance (or its assumed role) permission to access resources in other accounts.
Solution: Cross-Account IAM Roles
The standard AWS way to grant access between accounts is via IAM roles. Here’s the breakdown:
-
In the target AWS accounts (Account-B, Account-C):
- Create an IAM role. Let’s call it
GrafanaCrossAccountReader. - Trust Relationship: This is key. The trust policy must allow the principal running Grafana (e.g., the EC2 instance profile role in
Account-A, or a specific IAM user ARN if Grafana is external) tosts:AssumeRole.- Example Trust Policy for Account-B’s
GrafanaCrossAccountReaderrole:
Replace{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNT-A-ID:root" // OR if Grafana is on EC2 in Account-A: // "AWS": "arn:aws:iam::ACCOUNT-A-ID:role/YourGrafanaEC2Role" }, "Action": "sts:AssumeRole" } ] }ACCOUNT-A-IDwith the actual AWS account ID ofAccount-A. If you know the specific ARN of the role Grafana assumes in Account-A, use that for a more granular permission.
- Example Trust Policy for Account-B’s
- Permissions Policy: Attach a policy to this role that grants read-only access to CloudWatch.
- Example Permissions Policy for
GrafanaCrossAccountReader:
You can scope this down further by region or specific metric namespaces if needed, but{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "cloudwatch:ListMetrics", "cloudwatch:GetMetricStatistics", "cloudwatch:DescribeAlarms" // Often useful too ], "Resource": "*" } ] }Resource: "*"is common for broad read access.
- Example Permissions Policy for
- Create an IAM role. Let’s call it
-
In the Grafana AWS account (Account-A):
- Grafana Instance’s IAM Role: Ensure the IAM role that your Grafana instance (e.g., EC2 instance profile role) is using has permissions to
sts:AssumeRolefor the roles you just created inAccount-BandAccount-C.- Example Policy to attach to Grafana’s role in Account-A:
Replace{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": [ "arn:aws:iam::ACCOUNT-B-ID:role/GrafanaCrossAccountReader", "arn:aws:iam::ACCOUNT-C-ID:role/GrafanaCrossAccountReader" ] } ] }ACCOUNT-B-IDandACCOUNT-C-IDwith their respective AWS account IDs.
- Example Policy to attach to Grafana’s role in Account-A:
- Grafana Instance’s IAM Role: Ensure the IAM role that your Grafana instance (e.g., EC2 instance profile role) is using has permissions to
-
Configure Grafana Data Source:
- In Grafana, go to Configuration -> Data Sources.
- Add a new CloudWatch data source or edit an existing one.
- Authentication: Select
Credentials fileorIAM roledepending on your Grafana setup.- If using IAM role (recommended for EC2/EKS), Grafana will automatically use the role it’s running under.
- If Grafana is external, you might need to configure
~/.aws/credentialson the Grafana server with a profile that hassts:AssumeRolepermissions.
- Region: Select the AWS region for the metrics you want to query (e.g.,
us-east-1). - Access & Metrics: This is where you specify the cross-account details.
- Default Auth: Leave as
Default (Instance Role or Credentials File). - Assume Role ARN: This is the crucial field. Enter the ARN of the
GrafanaCrossAccountReaderrole you created in the target account.- For Account-B:
arn:aws:iam::ACCOUNT-B-ID:role/GrafanaCrossAccountReader - For Account-C:
arn:aws:iam::ACCOUNT-C-ID:role/GrafanaCrossAccountReader
- For Account-B:
- Custom Metrics Namespaces: (Optional) If you have custom metrics, you might need to specify them here.
- Default Auth: Leave as
- Save & Test: Click "Save & Test". Grafana will attempt to assume the specified role and query CloudWatch in that account.
Adding Multiple Accounts
You’ll repeat this process for each AWS account you want to query. You can configure multiple CloudWatch data sources in Grafana, each pointing to a different Assume Role ARN for a different account.
For example:
- Data Source 1: Name
CloudWatch-Account-A, Regionus-east-1, Assume Role ARN (empty or Account-A’s role) - Data Source 2: Name
CloudWatch-Account-B, Regionus-east-1, Assume Role ARNarn:aws:iam::ACCOUNT-B-ID:role/GrafanaCrossAccountReader - Data Source 3: Name
CloudWatch-Account-C, Regionus-east-1, Assume Role ARNarn:aws:iam::ACCOUNT-C-ID:role/GrafanaCrossAccountReader
Then, when creating dashboards, you can select the appropriate data source for each panel.
The "Next Error"
After successfully configuring cross-account access, the next common hurdle is dealing with metric resolution and aggregation across accounts, especially when panels try to display data from different time granularities or when Sum aggregation across multiple instances in different accounts doesn’t yield the expected results due to differing metric publication rates.