New user sign up using AWS Builder ID
New user sign up using AWS Builder ID is currently unavailable on re:Post. To sign up, please use the AWS Management Console instead.
如何解決當我嘗試將慢速日誌發佈到 CloudWatch Logs 時在 CloudFormation 中收到的錯誤?
我想要解決當我嘗試將慢速日誌發佈到 Amazon CloudWatch Logs 時在 AWS CloudFormation 中收到的錯誤。錯誤是: 「為 CloudWatch Logs 日誌群組 /aws/aes/domains/search/search-logs 指定的資源存取政策未授予 Amazon Elasticsearch Service 建立日誌串流的足夠權限。」
簡短描述
若要解決此錯誤,請在日誌群組層級使用單獨的政策,以允許 Amazon Elasticsearch Service (Amazon ES) 將日誌推送到 CloudWatch Logs。然後,使用 AWS::Elasticsearch::Domain 中的 AccessPolicies 為 Amazon ES 網域設定權限。
下列步驟說明如何使用以 Python 3.6 建立的 AWS Lambda 支援的自訂資源,將慢速日誌發佈到使用 CloudFormation 的 CloudWatch。自訂資源會觸發 Lambda 函數,然後該函數會觸發 PutResourcePolicy API 以發佈慢速日誌。
**注意:**當 CloudFormation 啟用日誌發佈到 CloudWatch 時,AWS::Logs::LogGroup 資源沒有可指派資源存取政策的屬性。為 CloudWatch Logs 日誌群組指定的資源存取政策應授予足夠的權限,讓 Amazon ES 發佈日誌串流。您無法直接使用 CloudFormation 資源建立存取政策權限。這是因為 AWS::Logs::LogGroup 資源的 PutResourcePolicy API 呼叫不受 CloudFormation 支援。
解決方法
**注意:**如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤訊息,請確認您使用的是最新的 AWS CLI 版本。
下列 CloudFormation 範本使用自訂資源來取得日誌群組的名稱。然後,範本會套用允許 Amazon ES 服務對日誌群組進行 API 呼叫的政策。
1. 建立一個名為 ESlogsPermission.yaml 的 CloudFormation 範本:
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. AWSTemplateFormatVersion: 2010-09-09 Description: AWS cloudFormation template to publish slow logs to Amazon CloudWatch Logs. Parameters: LogGroupName: Type: String Description: Please don't change the log group name while updating ESDomainName: Description: A name for the Amazon Elastic Search domain Type: String LambdaFunctionName: Description: Lambda Function Name Type: String Resources: AwsLogGroup: Type: 'AWS::Logs::LogGroup' Properties: LogGroupName: !Ref LogGroupName LambdaLogGroup: Type: 'AWS::Logs::LogGroup' Properties: LogGroupName: !Sub '/aws/lambda/${LambdaFunctionName}' LambdaExecutionRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - 'sts:AssumeRole' Path: / Policies: - PolicyName: root1 PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: !Sub >- arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${LambdaFunctionName}:log-stream:* - PolicyName: root2 PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - 'logs:CreateLogGroup' Resource: - !Sub >- arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${LambdaFunctionName} - !Sub >- arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/${LogGroupName} - Effect: Allow Action: - 'logs:PutResourcePolicy' - 'logs:DeleteResourcePolicy' Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*' logGroupPolicyFunction: DependsOn: LambdaLogGroup Type: 'AWS::Lambda::Function' Properties: FunctionName: !Ref LambdaFunctionName Code: ZipFile: > import urllib3 import json import boto3 http = urllib3.PoolManager() SUCCESS = "SUCCESS" FAILED = "FAILED" def send(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False): responseUrl = event['ResponseURL'] print(responseUrl) responseBody = {} responseBody['Status'] = responseStatus responseBody['Reason'] = 'See the details in CloudWatch Log Stream: ' + context.log_stream_name responseBody['PhysicalResourceId'] = physicalResourceId or context.log_stream_name responseBody['StackId'] = event['StackId'] responseBody['RequestId'] = event['RequestId'] responseBody['LogicalResourceId'] = event['LogicalResourceId'] responseBody['NoEcho'] = noEcho responseBody['Data'] = responseData json_responseBody = json.dumps(responseBody) print("Response body:\n" + json_responseBody) headers = { 'content-type' : '', 'content-length' : str(len(json_responseBody)) } try: response = http.request('PUT',responseUrl,body=json_responseBody.encode('utf-8'),headers=headers) print("Status code: " + response.reason) except Exception as e: print("send(..) failed executing requests.put(..): " + str(e)) def handler(event, context): logsgroup_policy_name=event['ResourceProperties']['CWLOGS_NAME'] cw_log_group_arn=event['ResourceProperties']['CWLOG_ARN'] cwlogs = boto3.client('logs') loggroup_policy={ "Version": "2012-10-17", "Statement": [{ "Sid": "", "Effect": "Allow", "Principal": { "Service": "es.amazonaws.com"}, "Action":[ "logs:PutLogEvents", " logs:PutLogEventsBatch", "logs:CreateLogStream" ], 'Resource': f'{cw_log_group_arn}' }] } loggroup_policy = json.dumps(loggroup_policy) if(event['RequestType'] == 'Delete'): print("Request Type:",event['RequestType']) cwlogs.delete_resource_policy( policyName=logsgroup_policy_name ) responseData={} send(event, context, SUCCESS, responseData) elif(event['RequestType'] == 'Create'): try: cwlogs.put_resource_policy( policyName = logsgroup_policy_name, policyDocument = loggroup_policy ) responseData={} print("Sending response to custom resource") send(event, context, SUCCESS, responseData) except Exception as e: print('Failed to process:', e) send(event, context, FAILED, responseData) elif(event['RequestType'] == 'Update'): try: responseData={} print("Update is not supported on this resource") send(event, context, SUCCESS, responseData) except Exception as e: print('Failed to process:', e) send(event, context, FAILED, responseData) Handler: index.handler Role: !GetAtt - LambdaExecutionRole - Arn Runtime: python3.6 logGroupPolicycustomresource: Type: 'Custom::LogGroupPolicy' Properties: ServiceToken: !GetAtt - logGroupPolicyFunction - Arn CWLOGS_NAME: !Ref LogGroupName CWLOG_ARN: !GetAtt - AwsLogGroup - Arn ElasticsearchDomain: Type: 'AWS::Elasticsearch::Domain' DependsOn: logGroupPolicycustomresource Properties: DomainName: !Ref ESDomainName ElasticsearchVersion: '6.2' EBSOptions: EBSEnabled: true VolumeSize: 10 VolumeType: gp2 LogPublishingOptions: SEARCH_SLOW_LOGS: CloudWatchLogsLogGroupArn: !GetAtt - AwsLogGroup - Arn Enabled: true
2. 若要啟動具有 ESlogsPermission.yaml 檔案的 CloudFormation 堆疊,請使用 CloudFormation 主控台或下列 AWS CLI 命令:
aws cloudformation create-stack --stack-name yourStackName --template-body file://yourTemplateName --parameters ParameterKey=LogGroupName,ParameterValue=Your-LogGroup-Name, ParameterKey=ESDomainName,ParameterValue=Your-ES-Name --capabilities CAPABILITY_NAMED_IAM --region yourRegion
**注意:**使用您的值取代 yourStackName、yourTemplateName、Your-LogGroup-Name、Your-ES-Name 及 yourRegion。
CloudFormation 範本會為您執行下列作業:
1. 建立日誌群組。
2. 建立 Lambda 函數。Lambda 函數會使用自訂資源,從 CloudFormation 範本的參數區段取得日誌群組名稱。Lambda 函數會為日誌群組名稱呼叫 PutResourcePolicy API。日誌群組必須具有允許 Amazon ES 網域放置日誌的政策。
3. 建立 Lambda 支援的自訂資源,以叫用在步驟 2 中建立的 Lambda 函數。自訂資源可協助在日誌群組 Amazon Resource Name (ARN) 上套用 PutResourcePolicy,以便 Amazon ES 可以串流日誌。在範本中,CloudFormation 使用自訂資源建立具有 LogPublishingOption 的 Amazon ES 網域。

相關內容
- 已提問 1 年前lg...
- 已提問 4 個月前lg...
- AWS 官方已更新 1 年前
- AWS 官方已更新 8 個月前
- AWS 官方已更新 8 個月前