2.6. 为 Athena 启用帐户访问
要在 Web 界面和 API 中提供数据,请为要使用的 hybrid committed spend 创建一个 IAM 策略和角色。此配置提供对存储的信息以及任何其他信息的访问。
流程
在 AWS Identity and Access Management (IAM)控制台中,为您要配置的 Athena Lambda 功能创建一个 IAM 策略。
选择 JSON 选项卡并在 JSON 策略文本框中粘贴以下内容:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "athena:*" ], "Resource": [ "*" ] }, { "Effect": "Allow", "Action": [ "glue:CreateDatabase", "glue:DeleteDatabase", "glue:GetDatabase", "glue:GetDatabases", "glue:UpdateDatabase", "glue:CreateTable", "glue:DeleteTable", "glue:BatchDeleteTable", "glue:UpdateTable", "glue:GetTable", "glue:GetTables", "glue:BatchCreatePartition", "glue:CreatePartition", "glue:DeletePartition", "glue:BatchDeletePartition", "glue:UpdatePartition", "glue:GetPartition", "glue:GetPartitions", "glue:BatchGetPartition" ], "Resource": [ "*" ] }, { "Effect": "Allow", "Action": [ "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket", "s3:ListBucketMultipartUploads", "s3:ListMultipartUploadParts", "s3:AbortMultipartUpload", "s3:CreateBucket", "s3:PutObject", "s3:PutBucketPublicAccessBlock" ], "Resource": [ "arn:aws:s3:::CHANGE-ME*"1 ] }, { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::CHANGE-ME*"2 ] }, { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation", "s3:ListAllMyBuckets" ], "Resource": [ "*" ] }, { "Effect": "Allow", "Action": [ "sns:ListTopics", "sns:GetTopicAttributes" ], "Resource": [ "*" ] }, { "Effect": "Allow", "Action": [ "cloudwatch:PutMetricAlarm", "cloudwatch:DescribeAlarms", "cloudwatch:DeleteAlarms", "cloudwatch:GetMetricData" ], "Resource": [ "*" ] }, { "Effect": "Allow", "Action": [ "lakeformation:GetDataAccess" ], "Resource": [ "*" ] }, { "Effect": "Allow", "Action": [ "logs:*" ], "Resource": "*" } ] }
- 为策略提供名称并完成策略的创建。保持 AWS IAM 控制台打开,因为您需要它才能继续下一步。
在 AWS IAM 控制台中,创建一个新的 IAM 角色:
- 对于可信实体的类型,选择 AWS 服务。
- 选择 Lambda。
- 附加您刚才配置的 IAM 策略。
- 输入角色名称和描述,并完成角色创建。
2.6.1. 为报告生成配置 Athena
配置 Athena 为混合提交成本提供经过过滤的成本和使用情况报告。配置 Athena 为成本管理提供经过过滤的成本和使用情况报告。
以下配置仅提供对额外存储信息的访问。它不提供对任何其他操作的访问:
流程
-
在 AWS S3 控制台中,导航到您创建的过滤存储桶并下载
crawler-cfn.yml
文件。 - 从 AWS 控制台中的 Cloudformation 中,创建一个新堆栈。
- 将 Template 选择为 Ready。
-
上传您之前下载的
crawler-cfn.yml
文件。这应该会立即加载。 - 点击 Next。
- 输入名称并点 Next。
- 点 I 确认 AWS Cloudformation 可能会创建 IAM 资源,然后点 Submit。
2.6.2. 为 Athena 创建 Lambda 功能
您必须创建一个 Lambda 功能来查询成本和使用情况报告。此 Lambda 功能查询红帽相关费用的成本和使用情况报告,并产生您过滤的费用报告。
流程
- 在 AWS 控制台中进入到 Lambda,然后点 Create function。
- 点 Author from scratch。
- 输入您的功能的名称。
- 在 Runtime 下拉菜单中选择 python 3.7。
- 选择 x86_64 作为 Architecture。
- 在 Permissions 下,选择您创建的 Athena 角色。
- 点 Create function。
将以下代码粘贴到功能中:
import boto3 import uuid import json from datetime import datetime now = datetime.now() year = now.strftime("%Y") month = now.strftime("%m") day = now.strftime("%d") # Vars to Change! integration_uuid = <your_integration_uuid> # integration_uuid bucket = <your_S3_Bucket_Name> # Bucket created for query results database = 'athenacurcfn_athena_cost_and_usage' # Database to execute athena queries output=f's3://{bucket}/{year}/{month}/{day}/{uuid.uuid4()}' # Output location for query results # Athena query query = f"SELECT * FROM {database}.koku_athena WHERE ((bill_billing_entity = 'AWS Marketplace' AND line_item_legal_entity like '%Red Hat%') OR (line_item_legal_entity like '%Amazon Web Services%' AND line_item_line_item_description like '%Red Hat%') OR (line_item_legal_entity like '%Amazon Web Services%' AND line_item_line_item_description like '%RHEL%') OR (line_item_legal_entity like '%AWS%' AND line_item_line_item_description like '%Red Hat%') OR (line_item_legal_entity like '%AWS%' AND line_item_line_item_description like '%RHEL%') OR (line_item_legal_entity like '%AWS%' AND product_product_name like '%Red Hat%') OR (line_item_legal_entity like '%Amazon Web Services%' AND product_product_name like '%Red Hat%')) AND year = '{year}' AND month = '{month}'" def lambda_handler(event, context): # Initiate Boto3 athena Client athena_client = boto3.client('athena') # Trigger athena query response = athena_client.start_query_execution( QueryString=query, QueryExecutionContext={ 'Database': database }, ResultConfiguration={ 'OutputLocation': output } ) # Save query execution to s3 object s3 = boto3.client('s3') json_object = {"integration_uuid": integration_uuid, "bill_year": year, "bill_month": month, "query_execution_id": response.get("QueryExecutionId"), "result_prefix": output} s3.put_object( Body=json.dumps(json_object), Bucket=bucket, Key='query-data.json' ) return json_object
将
<your_integration_uuid
> 替换为您在 console.redhat.com 上创建的集成中的 UUID。将<your_S3_Bucket_Name>
替换为您为存储报告创建的 S3 存储桶的名称。- 点 Deploy 来测试该功能。
2.6.3. 创建 Lambda 功能来发布报告文件
您必须创建一个 Lambda 功能,将报告文件发布到您创建的 S3 存储桶。
流程
- 在 AWS 控制台中进入到 Lambda,然后点 Create function。
- 点 Author from scratch
- 输入您的功能的名称
- 在 Runtime 下拉菜单中选择 python 3.7。
- 选择 x86_64 作为 Architecture。
- 在 Permissions 下,选择您创建的 Athena 角色。
- 点 Create function。
将以下代码粘贴到功能中:
import boto3 import json import requests from botocore.exceptions import ClientError def get_credentials(secret_name, region_name): session = boto3.session.Session() client = session.client( service_name='secretsmanager', region_name=region_name ) try: get_secret_value_response = client.get_secret_value( SecretId=secret_name ) except ClientError as e: raise e secret = get_secret_value_response['SecretString'] return secret secret_name = "CHANGEME" region_name = "us-east-1" secret = get_credentials(secret_name, region_name) json_creds = json.loads(secret) USER = json_creds.get("<your_username>") # console.redhat.com Username PASS = json_creds.get("<your_password>") # console.redhat.com Password bucket = "<your_S3_Bucket_Name>" # Bucket for athena query results def lambda_handler(event, context): # Initiate Boto3 s3 and fetch query file s3_resource = boto3.resource('s3') json_content = json.loads(s3_resource.Object(bucket, 'query-data.json').get()['Body'].read().decode('utf-8')) # Initiate Boto3 athena Client and attempt to fetch athena results athena_client = boto3.client('athena') try: athena_results = athena_client.get_query_execution(QueryExecutionId=json_content["query_execution_id"]) except Exception as e: return f"Error fetching athena query results: {e} \n Consider increasing the time between running and fetching results" reports_list = [] prefix = json_content["result_prefix"].split(f'{bucket}/')[-1] # Initiate Boto3 s3 client s3_client = boto3.client('s3') result_data = s3_client.list_objects(Bucket=bucket, Prefix=prefix) for item in result_data.get("Contents"): if item.get("Key").endswith(".csv"): reports_list.append(item.get("Key")) # Post results to console.redhat.com API url = "https://console.redhat.com/api/cost-management/v1/ingress/reports/" json_data = {"source": json_content["integration_uuid"], "reports_list": reports_list, "bill_year": json_content["bill_year"], "bill_month": json_content["bill_month"]} resp = requests.post(url, json=json_data, auth=(USER, PASS)) return resp
将
<your_username>
替换为您的 console.redhat.com 的用户名。将<your_password>
替换为您的 console.redhat.com 的密码。将<your_S3_Bucket_Name
> 替换为您为存储报告的 S3 存储桶的名称。- 点 Deploy 来测试该功能。