【问题标题】:ValidationException: Before you can proceed, you must enable a service-linked role to give Amazon ES permissions to access your VPCValidationException:在继续之前,您必须启用服务相关角色以授予 Amazon ES 访问您的 VPC 的权限
【发布时间】:2018-04-24 01:32:48
【问题描述】:

我正在尝试在 AWS 上创建 VPC 控制的弹性搜索服务。问题是我在运行以下代码时不断收到错误消息:“ValidationException:在您继续之前,您必须启用服务相关角色以授予 Amazon ES 访问您的 VPC 的权限”。

const AWS = require('aws-sdk');
AWS.config.update({region:'<aws-datacenter>'});
const accessPolicies = {
  Statement: [{
    Effect: "Allow",
    Principal: {
      AWS: "*"
    },
    Action: "es:*",
    Resource: "arn:aws:es:<dc>:<accountid>:domain/<domain-name/*"
  }]
};
const params = {
  DomainName: '<domain>',
  /* required */
  AccessPolicies: JSON.stringify(accessPolicies),
  AdvancedOptions: {
    EBSEnabled: "true",
    VolumeType: "io1",
    VolumeSize: "100",
    Iops: "1000"
  },
  EBSOptions: {
    EBSEnabled: true,
    Iops: 1000,
    VolumeSize: 100,
    VolumeType: "io1"
  },
  ElasticsearchClusterConfig: {
    DedicatedMasterCount: 3,
    DedicatedMasterEnabled: true,
    DedicatedMasterType: "m4.large.elasticsearch",
    InstanceCount: 2,
    InstanceType: 'm4.xlarge.elasticsearch',
    ZoneAwarenessEnabled: true
  },
  ElasticsearchVersion: '5.5',
  SnapshotOptions: {
    AutomatedSnapshotStartHour: 3
  },
  VPCOptions: {
    SubnetIds: [
      '<redacted>',
      '<redacted>'
    ],
    SecurityGroupIds: [
      '<redacted>'
    ]
  }
};

const es = new AWS.ES();
es.createElasticsearchDomain(params, function (err, data) {
  if (err) {
    console.log(err, err.stack); // an error occurred
  } else {
    console.log(JSON.stringify(data, null, 4)); // successful response
  }
});

问题是我收到此错误:ValidationException: 在您继续之前,您必须启用服务相关角色以授予 Amazon ES 访问您的 VPC 的权限。我似乎无法弄清楚如何为弹性搜索服务创建此服务链接角色。在 aws.amazon.com IAM 控制台中,我无法为角色选择该服务。我相信它应该是自动创建的。

有没有人遇到过这个问题或知道如何解决它?

【问题讨论】:

  • 在使用 aws-cloudformation 模板在 VPC 中创建 elasticsearch 域时,我也遇到了同样的错误。看起来没有办法在VPCOptions 中设置服务相关角色。 Amazon ES 需要服务相关角色来访问您的 VPC、创建域终端节点并将网络接口放置在 VPC 的子网中。

标签: amazon-web-services amazon-elasticsearch aws-elasticsearch


【解决方案1】:

目前不支持使用VPCaws-sdk/cloudformation 创建elasticsearch 域。 elasticsearch 服务需要特殊的服务链接角色才能在指定的VPC 中创建网络接口。目前可以使用console / cli(@Oscar Barrett 的回答如下)。

但是,有一种解决方法可以使其正常工作,描述如下:

  • 使用控制台创建具有VPC 访问权限的测试elasticsearch 域。
  • 这将创建一个名为AWSServiceRoleForAmazonElasticsearchService的服务链接角色[注意:您不能手动或通过console创建具有指定名称的角色]
  • 创建此角色后,使用aws-sdkcloudformation 创建elasticsearch 域和VPC
  • 您可以稍后删除测试elasticsearch

更新:@Oscar Barrett 的回答中描述了创建服务角色的更正确方法。我想删除我的答案;但有关实际问题的其他事实仍然更相关,因此将我的答案保留在这里。

【讨论】:

  • 创建服务链接角色的更好方法是使用 CLI:aws iam create-service-linked-role --aws-service-name es.amazonaws.com
  • @OscarBarrett 将您的评论推广为真正的答案
【解决方案2】:

可以使用 AWS CLI 创建服务相关角色。

aws iam create-service-linked-role --aws-service-name es.amazonaws.com

【讨论】:

    【解决方案3】:

    对于遇到此错误的 terraform 用户,您可以使用 aws_iam_service_linked_role 资源为 ES 服务创建服务链接角色:

    resource "aws_iam_service_linked_role" "es" {
        aws_service_name = "es.amazonaws.com"
        description      = "Allows Amazon ES to manage AWS resources for a domain on your behalf."
    }
    

    此资源是在 AWS Provider 的 Release 1.15.0(2018 年 4 月 18 日)中添加的。

    【讨论】:

    • 我这样做了,但现在我无法删除它。我在控制台中收到一条错误消息:“至少一个域正在使用服务相关角色”?我该如何解决?
    【解决方案4】:

    您现在可以在 CloudFormation 模板中创建服务相关角色,类似于 @htaccess 的 Terraform 答案。详情请见the documentation for the CloudFormation syntax for Service-Linked Roles

    YourRoleNameHere:
      Type: 'AWS::IAM::ServiceLinkedRole'
      Properties:
        AWSServiceName: es.amazonaws.com
        Description: 'Role for ES to access resources in my VPC'
    

    【讨论】:

    • 也许我的配置有问题,但即使在服务链接角色和 ES 域之间存在“DependsOn”,我仍然收到相同的错误消息。 确实但是,如果我启动了一个 CF 模板来完成您所描述的操作,随后另一个具有 ES 域的模板,但不幸的是,这对我来说不是很有用.
    • 我在模板中创建了其他东西,所以我使用了额外的DependsOns 让角色先创建,然后创建其他东西,然后尽可能晚地创建 ES 域。猜测是因为 IAM 的最终一致性。
    • 当我在创建弹性搜索域的同一 CF 脚本中使用 ServiceLinkedRole 时,这不起作用。有什么方便的等待方式吗?尝试过取决于,但没有奏效。当我使用 aws cli 独立创建角色时工作,但希望将所有配置都放在 CF 中。
    【解决方案5】:

    在 CDK 中自己做:

    const serviceLinkedRole = new cdk.CfnResource(this, "es-service-linked-role", {
      type: "AWS::IAM::ServiceLinkedRole",
      properties: {
        AWSServiceName: "es.amazonaws.com",
        Description: "Role for ES to access resources in my VPC"
      }
    });
    
    const esDomain = new es.CfnDomain(this, "es", { ... });
    
    esDomain.node.addDependency(serviceLinkedRole);
    

    【讨论】:

      猜你喜欢
      • 2016-01-30
      • 2014-12-28
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 2020-01-31
      • 2011-02-24
      • 2016-06-10
      • 2019-05-16
      相关资源
      最近更新 更多