ValidationException: Before you can proceed, you must enable a service-linked role to give Amazon ES permissions to access your VPC

Viewed 20542

I am trying to create a VPC controlled Elastic Search Service on AWS. The problem is I keep getting the error when I run the following code: 'ValidationException: Before you can proceed, you must enable a service-linked role to give Amazon ES permissions to access your 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
  }
});

The problem is I get this error: ValidationException: Before you can proceed, you must enable a service-linked role to give Amazon ES permissions to access your VPC. I cannot seem to figure out how to create this service linked role for the elastic search service. In the aws.amazon.com IAM console I cannot select that service for a role. I believe it is supposed to be created automatically.

Has anybody ran into this or know the way to fix it?

5 Answers

You can now create a service-linked role in a CloudFormation template, similar to the Terraform answer by @htaccess. See the documentation for the CloudFormation syntax for Service-Linked Roles for more details

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

For terraform users who hit this error, you can use the aws_iam_service_linked_role resource to create a service linked role for the ES service:

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."
}

This resource was added in Release 1.15.0 (April 18, 2018) of the AWS Provider.

Do it yourself in 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);
Related