Cloudwatch Data Source error using Role ARN

Hi Support et al,
Unable to connect to CloudWatch using ARN Role.
Grafana v5.2.2 (commit: aeaf7b2)

Created AWS Role
Assume Role ARN: arn:aws:iam::NNNNNNNNNNNN:role/grafana-cloudwatch

I am trying to connect to my AWS CloudWatch logs using grafana. I have created an IAM Policy:
{
“Version”: “2012-10-17”,
“Statement”: [
{
“Sid”: “VisualEditor0”,
“Effect”: “Allow”,
“Action”: [
“cloudwatch:Describe*”,
“cloudwatch:Get*”,
“cloudwatch:List*”
],
“Resource”: “*”
}
]
}
The IAM Role has the following trusted entities assigned:
{
“Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”,
“Principal”: {
“Service”: “ec2.amazonaws.com
},
“Action”: “sts:AssumeRole”
}
]
}

Error message in Grafana.log file:
“Metric request error” logger=context userid=1 orgId=1 uname=admin error"NoCredentialProviders: no valid providers in chain. Depreciated. \n\t For verbose messaging see aws.Config.CredentialChainVerboseErrors"

Please help

Fixed by performing a couple of things.

  1. Assign the role to the AWS EC2 Instance Grafana is running on.
  2. In the trusted Entities assigned portion of the role, add the following Service underneath the EC2 Service
    “AWS”: “arn:aws:iam::935675756790:role/grafana-cloudwatch”
2 Likes

so your saying that I would just add:

“AWS”: “arn:aws:iam::935675756790:role/grafana-cloudwatch”

and the 9356{accountNumber} is account where the grafana ec2 instance is?
to look like

{
“Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”,
“Principal”: {
“Service”: “ec2.amazonaws.com
“AWS”: “arn:aws:iam::935675756790:role/grafana-cloudwatch”
},
“Action”: “sts:AssumeRole”
}
]
}

so something like that?

I had this very problem and until I added the role to the Principal object as described. However, it’s now working, which is an improvement!!! :¬D

You will need a comma:

{
“Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”,
“Principal”: {
“Service”: “[ec2.amazonaws.com](http://ec2.amazonaws.com/)”,
“AWS”: “arn:aws:iam::935675756790:role/grafana-cloudwatch”
},
“Action”: “sts:AssumeRole”
}
]
}

My issue now is how to describe this in Terraform; it seems to be a circular dependency: the Role needs an Assume Role Policy, but this needs to know the ARN of the former…!

OK. For completeness, I’ve worked out how to set this up properly without a self-reference (which is a circular dependency in Terraform, so is a big dead-end).

  1. Set up a role for the EC2 instance which Grafana is running on, this is assumable by the EC2 Service (i.e. "Principle":{"Service":"ec2.amazonaws.com"}).
  2. Set up a second role which is can be assumed by the ARN of the former role (i.e. "Principle":{"AWS": "arn:aws:iam::[...etc...]"}).
  3. Attach the permissions for CloudWatch, etc., to this latter role
    (i.e. the ones documented here: https://grafana.com/docs/features/datasources/cloudwatch/)
  4. Use the ARN of the latter role in the definition of the Grafana CloudWatch datasource.

Of course, the Terraform has different syntax, but is something like:

# First role, for the server itself
resource aws_iam_role metrics_server {
  name               = "metrics-server-role"
  assume_role_policy = "${data.aws_iam_policy_document.metrics_server_assume_role.json}"
}

# Trust policy document allowing EC2 service to adopt this role
data aws_iam_policy_document metrics_server_assume_role {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      identifiers = ["ec2.amazonaws.com"]
      type = "Service"
    }

    effect  = "Allow"
  }
}

# Second role, to give to Grafana
resource aws_iam_role grafana_datasource {
  name               = "grafana-datasource-role"
  assume_role_policy = "${data.aws_iam_policy_document.grafana_datasource_assume_role.json}"
}

# Trust policy document to allow Grafana, running in the metric server EC2 instance, to assume this role
data aws_iam_policy_document grafana_datasource_assume_role {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      identifiers = ["${aws_iam_role.metrics_server.arn}"]
      type = "AWS"
    }

    effect  = "Allow"
  }
}

# Policy attachment to allow Grafana the rights to get metrics, etc, cf., https://grafana.com/docs/features/datasources/cloudwatch/
resource aws_iam_role_policy grafana_datasource {
  role = "${aws_iam_role.grafana_datasource.name}"
  policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowReadingMetricsFromCloudWatch",
            "Effect": "Allow",
            "Action": [
                "cloudwatch:ListMetrics",
                "cloudwatch:GetMetricStatistics",
                "cloudwatch:GetMetricData"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowReadingTagsInstancesRegionsFromEC2",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeTags",
                "ec2:DescribeInstances",
                "ec2:DescribeRegions"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowReadingResourcesForTags",
            "Effect" : "Allow",
            "Action" : "tag:GetResources",
            "Resource" : "*"
        }
    ]
}
EOF
}

# IAM Instance profile for use when setting up the EC2 instance
resource aws_iam_instance_profile metrics_server {
  name = "${aws_iam_role.metrics_server.name}"
  role = "${aws_iam_role.metrics_server.name}"
}

:¬)

1 Like