只读 AWS CLI 访问严格的 CloudWatch 计费指标
Read only AWS CLI access to strictly CloudWatch billing metrics
我需要向某人提供对我们的 CloudWatch 计费指标的只读 AWS CLI 访问权限。我不确定如何执行此操作,因为 CloudWatch 没有任何可以控制访问的特定资源。这意味着在 IAM 策略中没有要指定的 ARN,因此,策略中的任何资源指定都是“*”。有关 CloudWatch ARN 限制的更多信息,请参见 here. I looked into using namespaces,但我相信 "aws-portal" 命名空间适用于控制台。非常感谢任何方向或想法。
在当前的 CloudWatch ARN 限制下,IAM 策略看起来像这样。
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"cloudwatch:DescribeMetricData",
"cloudwatch:GetMetricData"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
如您所说,您将无法在 CloudWatch 中实现此目的。根据 docs:
CloudWatch doesn't have any specific resources for you to control access to... For example, you can't give a user access to CloudWatch data for only a specific set of EC2 instances or a specific load balancer. Permissions granted using IAM cover all the cloud resources you use or monitor with CloudWatch.
另一种选择可能是:
在 lambda 函数上使用 Scheduled events 定期将相关计费指标从 Cloudwatch 导出到 S3 存储桶。例如,使用 Python SDK,lambda 可能如下所示:
import boto3
from datetime import datetime, timedelta
def lambda_handler(event, context):
try:
bucket_name = "so-billing-metrics"
filename = '-'.join(['billing', datetime.now().strftime("%Y-%m-%d-%H")])
region_name = "us-east-1"
dimensions = {'Name': 'Currency', 'Value':'USD'}
metric_name = 'EstimatedCharges'
namespace = 'AWS/Billing'
start_time = datetime.now() - timedelta(hours = 1)
end_time = datetime.now()
# Create CloudWatch client
cloudwatch = boto3.client('cloudwatch', region_name=region_name)
# Get billing metrics for the last hour
metrics = cloudwatch.get_metric_statistics(
Dimensions=[dimensions],
MetricName=metric_name,
Namespace=namespace,
StartTime=start_time,
EndTime=end_time,
Period=60,
Statistics=['Sum'])
# Save data to temp file
with open('/tmp/billingmetrics', 'wb') as f:
# Write header and data
f.write("Timestamp, Cost")
for entry in metrics['Datapoints']:
f.write(",".join([entry['Timestamp'].strftime('%Y-%m-%d %H:%M:%S'), str(entry['Sum']), entry['Unit']]))
# Upload temp file to S3
s3 = boto3.client('s3')
with open('/tmp/billingmetrics', 'rb') as data:
s3.upload_fileobj(data, bucket_name, filename)
except Exception as e:
print str(e)
return 0
return 1
注意:您需要确保 Lambda 函数具有写入 S3 和从 cloudwatch 读取的相关权限。
限制 IAM User/Role 只读访问 S3 存储桶。
我需要向某人提供对我们的 CloudWatch 计费指标的只读 AWS CLI 访问权限。我不确定如何执行此操作,因为 CloudWatch 没有任何可以控制访问的特定资源。这意味着在 IAM 策略中没有要指定的 ARN,因此,策略中的任何资源指定都是“*”。有关 CloudWatch ARN 限制的更多信息,请参见 here. I looked into using namespaces,但我相信 "aws-portal" 命名空间适用于控制台。非常感谢任何方向或想法。
在当前的 CloudWatch ARN 限制下,IAM 策略看起来像这样。
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"cloudwatch:DescribeMetricData",
"cloudwatch:GetMetricData"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
如您所说,您将无法在 CloudWatch 中实现此目的。根据 docs:
CloudWatch doesn't have any specific resources for you to control access to... For example, you can't give a user access to CloudWatch data for only a specific set of EC2 instances or a specific load balancer. Permissions granted using IAM cover all the cloud resources you use or monitor with CloudWatch.
另一种选择可能是:
在 lambda 函数上使用 Scheduled events 定期将相关计费指标从 Cloudwatch 导出到 S3 存储桶。例如,使用 Python SDK,lambda 可能如下所示:
import boto3 from datetime import datetime, timedelta def lambda_handler(event, context): try: bucket_name = "so-billing-metrics" filename = '-'.join(['billing', datetime.now().strftime("%Y-%m-%d-%H")]) region_name = "us-east-1" dimensions = {'Name': 'Currency', 'Value':'USD'} metric_name = 'EstimatedCharges' namespace = 'AWS/Billing' start_time = datetime.now() - timedelta(hours = 1) end_time = datetime.now() # Create CloudWatch client cloudwatch = boto3.client('cloudwatch', region_name=region_name) # Get billing metrics for the last hour metrics = cloudwatch.get_metric_statistics( Dimensions=[dimensions], MetricName=metric_name, Namespace=namespace, StartTime=start_time, EndTime=end_time, Period=60, Statistics=['Sum']) # Save data to temp file with open('/tmp/billingmetrics', 'wb') as f: # Write header and data f.write("Timestamp, Cost") for entry in metrics['Datapoints']: f.write(",".join([entry['Timestamp'].strftime('%Y-%m-%d %H:%M:%S'), str(entry['Sum']), entry['Unit']])) # Upload temp file to S3 s3 = boto3.client('s3') with open('/tmp/billingmetrics', 'rb') as data: s3.upload_fileobj(data, bucket_name, filename) except Exception as e: print str(e) return 0 return 1
注意:您需要确保 Lambda 函数具有写入 S3 和从 cloudwatch 读取的相关权限。
限制 IAM User/Role 只读访问 S3 存储桶。