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.
- Assign the role to the AWS EC2 Instance Grafana is running on.
- 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”
1 Like
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).
- 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"}
).
- 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...]"}
).
- Attach the permissions for CloudWatch, etc., to this latter role
(i.e. the ones documented here: https://grafana.com/docs/features/datasources/cloudwatch/)
- 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