I need to get MetricData in Node.js application for my AWS Lambda
Error received:
AccessDenied: User: arn:aws:sts::123456789012:assumed-role/dev-rohit-ap-southeast-1-lambdaRole/dev-rohit-uploader is not authorized to perform: cloudwatch:GetMetricData\n at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/query.js:50:29)\n at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)\n at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)\n at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)\n at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)\n at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)\n at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10\n at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)\n at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)\n at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
Serverless.yaml
- Effect: "Allow"
Action:
- "lambda:GetMetricData"
Resource: arn:aws:lambda:${self:custom.region}:${self:custom.accountId}:function:${self:service}-${opt:stage}-uploader
Getting Metric Data function
exports.getMetrics = async () => {
const params = {
EndTime: '2021-09-07T03:04:00Z',
MetricDataQueries: [
{
Id: 'concurrencycount',
Label: 'Average concurrency',
MetricStat: {
Metric: {
Dimensions: [
{
Name: 'upload',
Value: process.env.S3_UPLOAD_BUCKET
},
],
MetricName: 'Invocations',
Namespace: 'AWS/Lambda'
},
Period: '300',
Stat: 'Average',
Unit: 'Count'
},
ReturnData: false
},
],
StartTime: '2021-09-07T03:01:00Z',
//ScanBy: TimestampDescending
};
try {
return await client().getMetricData(params).promise()
} catch (error) {
logger.error(error, 'Error getting metrics from Lambda Cloudwatch')
throw error
}
}
What I tried :
Updated Action in serverless.yaml
Action:
Updated ARN to
Resource: arn:aws:lambda:${self:custom.region}:${self:custom.accountId}:function:${self:service}-${opt:stage}-uploader
Updated
Resource: arn:aws:logs:${self:custom.region}:${self:custom.accountId}:log-group:/aws/lambda/${self:service}-${opt:stage}-uploader:*
didn't work.
Resources: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CloudWatch.html#getMetricData-property
Can someone please help me?
You have to set the Resource to *
and use condition keys to limit the access scope:
https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/iam-cw-condition-keys-namespace.html
So your policy statement might look something like:
- Effect: "Allow"
Action:
- "cloudwatch:GetMetricData"
Resource: "*"
Condition:
StringEquals:
"cloudwatch:namespace": "AWS/Lambda"