![](/img/trans.png)
[英]Cloud formation error in creating the Role with managed policy and inline policy
[英]CloudWatch resource access policy error while creating Amazon Elasticsearch Service via Cloud Formation
我正在嘗試創建一個啟用LogPublishingOptions
的彈性搜索域。 雖然啟用 LogPublishingOptions ES 表示它沒有足夠的權限在 Cloudwatch 上創建 LogStream。
我嘗試創建一個具有角色的策略並將該策略附加到 ES 引用的 LogGroup 但它不起作用。 以下是我的彈性搜索雲形成模板,
AWSTemplateFormatVersion: 2010-09-09
Resources:
MYLOGGROUP:
Type: 'AWS::Logs::LogGroup'
Properties:
LogGroupName: index_slow
MYESROLE:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: es.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AmazonESFullAccess'
- 'arn:aws:iam::aws:policy/CloudWatchFullAccess'
RoleName: !Join
- '-'
- - es
- !Ref 'AWS::Region'
PolicyDocESIndexSlow :
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:PutLogEvents
- logs:CreateLogStream
Resource: 'arn:aws:logs:*'
PolicyName: !Ref MYLOGGROUP
Roles:
- !Ref MYESROLE
MYESDOMAIN:
Type: AWS::Elasticsearch::Domain
Properties:
DomainName: 'es-domain'
ElasticsearchVersion: '7.4'
ElasticsearchClusterConfig:
DedicatedMasterCount: 3
DedicatedMasterEnabled: True
DedicatedMasterType: 'r5.large.elasticsearch'
InstanceCount: '2'
InstanceType: 'r5.large.elasticsearch'
EBSOptions:
EBSEnabled: True
VolumeSize: 10
VolumeType: 'gp2'
AccessPolicies:
Version: 2012-10-17
Statement:
- Effect: Deny
Principal:
AWS: '*'
Action: 'es:*'
Resource: '*'
AdvancedOptions:
rest.action.multi.allow_explicit_index: True
LogPublishingOptions:
INDEX_SLOW_LOGS:
CloudWatchLogsLogGroupArn: !GetAtt
- MYLOGGROUP
- Arn
Enabled: True
VPCOptions:
SubnetIds:
- !Ref MYSUBNET
SecurityGroupIds:
- !Ref MYSECURITYGROUP
MYVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
MYSUBNET:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MYVPC
CidrBlock: 10.0.0.0/16
MYSECURITYGROUP:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: security group for elastic search domain
VpcId: !Ref MYVPC
GroupName: 'SG for ES'
SecurityGroupIngress:
- FromPort: '443'
IpProtocol: tcp
ToPort: '443'
CidrIp: 0.0.0.0/0
執行時,它會創建除 MYESDOMAIN 之外的所有資源。 它說
為 CloudWatch Logs 日志組 index_slow 指定的資源訪問策略未授予 Amazon Elasticsearch 服務創建日志 stream 的足夠權限。 請檢查資源訪問策略。 (服務:AWSElasticsearch;狀態代碼:400;錯誤代碼:ValidationException)
知道這里缺少什么嗎?
我相信這里有一些關於應該更新/設置哪些策略以啟用 ES 寫入日志組的混淆。
我認為您應該將PolicyDocESIndexSlow
策略應用於CloudWatch Logs 。
根據我的記憶,這不能在 CloudFormation 中完成。 您必須使用put-resource-policy 、相應的 API 調用或控制台,如下所示:
最終的代碼將是這樣的,
部署ES lambda_function.py
import logging
import time
import boto3
import json
from crhelper import CfnResource
logger = logging.getLogger(__name__)
helper = CfnResource(json_logging=False, log_level='DEBUG', boto_level='CRITICAL', sleep_on_delete=120)
try:
# Init code goes here
pass
except Exception as e:
helper.init_failure(e)
@helper.create
@helper.update
def create(event, _):
logger.info("Got Create/Update")
my_log_group_arn = event['ResourceProperties']['MYLOGGROUPArn']
client = boto3.client('logs')
policy_document = dict()
policy_document['Version'] = '2012-10-17'
policy_document['Statement'] = [{
'Sid': 'ESLogsToCloudWatchLogs',
'Effect': 'Allow',
'Principal': {
'Service': [
'es.amazonaws.com'
]
},
'Action': 'logs:*',
}]
policy_document['Statement'][0]['Resource'] = my_log_group_arn
client.put_resource_policy(policyName='ESIndexSlowPolicy', policyDocument=json.dumps(policy_document))
helper.Data['success'] = True
helper.Data['message'] = 'ES policy deployment successful'
# To return an error to Cloud Formation you raise an exception:
if not helper.Data["success"]:
raise Exception('Error message to cloud formation')
return "MYESIDDEFAULT"
@helper.delete
def delete(event, _):
logger.info("Got Delete")
# Delete never returns anything. Should not fail if the underlying resources are already deleted.
# Desired state.
try:
client = boto3.client('logs')
client.delete_resource_policy(policyName='ESIndexSlowPolicy')
except Exception as ex:
logger.critical(f'ES policy delete failed with error [{repr(ex)}]')
def lambda_handler(event, context):
helper(event, context)
以及 CF 模板中的一些附加組件
MYLAMBDAROLE:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AWSLambdaFullAccess'
- 'arn:aws:iam::aws:policy/AmazonS3FullAccess'
- 'arn:aws:iam::aws:policy/AmazonESFullAccess'
- 'arn:aws:iam::aws:policy/CloudWatchFullAccess'
RoleName: !Join
- '-'
- - lambda-role
- !Ref 'AWS::Region'
MYLAMBDADEPLOY:
Type: 'AWS::Lambda::Function'
Properties:
Code:
S3Bucket: es-bucket-for-lambda-ta86asdf596
S3Key: es.zip
FunctionName: deploy_es
Handler: lambda_function.lambda_handler
MemorySize: 128
Role: !GetAtt
- MYLAMBDAROLE
- Arn
Runtime: python3.8
Timeout: 60
MYESSETUP:
Type: 'Custom::MYESSETUP'
Properties:
ServiceToken: !GetAtt
- MYLAMBDADEPLOY
- Arn
MYLOGGROUPArn: !GetAtt
- MYLOGGROUP
- Arn
DependsOn:
- MYLAMBDADEPLOY
- MYLOGGROUP
只需在DependsOn
下面添加到 MYESDOMAIN
DependsOn:
- MYESSETUP
有一個名為AWS::Logs::ResourcePolicy
的 CloudFormation 資源,它允許在 CF 中為 CloudWatch Logs 定義策略。 我發現的主要問題是它只接受一個真正的字符串作為值。 嘗試使用 Ref、Join 等組合字符串一直被拒絕。 如果有人能完成這項工作,那就太棒了。
將其寫入 YAML 更容易,因為 JSON 需要 escaping 所有"
字符。
OSLogGroupPolicy:
Type: AWS::Logs::ResourcePolicy
Properties:
PolicyName: AllowES
PolicyDocument: '{"Version": "2012-10-17","Statement":[{"Effect":"Allow","Principal": {"Service": ["es.amazonaws.com"]},"Action":["logs:PutLogEvents","logs:CreateLogStream"],"Resource":"*"}]}'
在AWS::Logs::ResourcePolicy
的AWS::Elasticsearch::Domain
資源中添加DependsOn
為我解決了這個問題。
示例代碼:
ESLogGroup:
Type: 'AWS::Logs::LogGroup'
Properties:
LogGroupName: !Sub '/aws/OpenSearchService/domains/${NamePrefix}-es/application-logs'
RetentionInDays: 30
ESLogGroupPolicy:
Type: AWS::Logs::ResourcePolicy
DependsOn: ESLogGroup
Properties:
PolicyName: !Sub "es-logs-access-policy"
PolicyDocument: '{"Version": "2012-10-17","Statement":[{"Effect":"Allow","Principal": {"Service": ["es.amazonaws.com"]},"Action":["logs:PutLogEvents","logs:CreateLogStream"],"Resource":"*"}]}'
ESDomain:
Type: AWS::Elasticsearch::Domain
DependsOn: [ESLogGroupPolicy]
Properties:
DomainName: !Sub "${NamePrefix}-es"
...
LogPublishingOptions:
ES_APPLICATION_LOGS:
CloudWatchLogsLogGroupArn: !GetAtt ESLogGroup.Arn
Enabled: true
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.