Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating aws_elasticsearch_domain can't be done due to absence of AWSServiceRoleForAmazonElasticsearchService role #5218

Closed
sarunask opened this issue Jul 17, 2018 · 18 comments
Assignees
Labels
documentation Introduces or discusses updates to documentation. service/elasticsearch Issues and PRs that pertain to the elasticsearch service.
Milestone

Comments

@sarunask
Copy link

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform Version

Terraform v0.11.7

  • provider.archive v1.0.3
  • provider.aws v1.27.0
  • provider.null v1.0.0
  • provider.random v1.3.1

Affected Resource(s)

  • aws_elasticsearch_domain

Terraform Configuration Files

resource "aws_elasticsearch_domain" "es" {
  domain_name           = "${substr(random_pet.random_pet_name.id,0,28)}"
  elasticsearch_version = "6.2"

  # Anyone in
  access_policies = "${data.aws_iam_policy_document.es_policy.json}"

  cluster_config {
    instance_type  = "${var.es_instance_size}"
    instance_count = "${var.es_instance_count}"
  }

  ebs_options {
    ebs_enabled = true
    volume_type = "gp2"
    volume_size = "${var.es_eb_disk_size}"
  }

  vpc_options {
    subnet_ids         = ["${element(aws_db_subnet_group.elasticsearch_sb.subnet_ids, 0)}"]
    security_group_ids = ["${aws_security_group.allow_all.id}"]
  }

  snapshot_options {
    automated_snapshot_start_hour = 23
  }

  tags {
    Name        = "${random_pet.random_pet_name.id}"
    component   = "${var.component}"
    description = "${var.es_description}"
  }
}

Debug Output

https://gist.github.com/sarunask/69b7e612d92ee992d7a70f506623f35f

Panic Output

No panic

Expected Behavior

ES Cluster created

Actual Behavior

Terraform gave error:

  • aws_elasticsearch_domain.es: Error reading IAM Role AWSServiceRoleForAmazonElasticsearchService: NoSuchEntity: The user with name AWSServiceRoleForAmazonElasticsearchService cannot be found.
    status code: 404, request id: 2fe1c895-89d7-11e8-8212-c38ddc7e67d2

Steps to Reproduce

  1. terraform apply

Important Factoids

In current AWS account there are no previous ElasticSearch clusters.

References

  • #0000
@bflad bflad added bug Addresses a defect in current functionality. service/elasticsearch Issues and PRs that pertain to the elasticsearch service. labels Jul 17, 2018
@FransUrbo
Copy link

Not even creating a microcluster from the AWS Console seemed to help.

@FransUrbo
Copy link

Looking at https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/slr-es.html, I get the impression that this error ONLY (?) occurs if/when a VPC is specified for ES.

@FransUrbo
Copy link

Yes, indeed when I create my micro-cluster and instead choose "VPC access", then I get the IAM Role AWSServiceRoleForAmazonElasticsearchService line.

@FransUrbo
Copy link

FransUrbo commented Jul 20, 2018

The IAM role was then created, and while the one I created in the AWS console is building (will take ten, fifteen minutes), I'm running Terraform to create my "real" cluster with Terraform.

Looking at the IAM role, it have the AmazonElasticsearchServiceRolePolicy policy attached and it looks like this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1480452973134",
            "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:DeleteNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:ModifyNetworkInterfaceAttribute",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

... with the trust entity es.amazonaws.com:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "es.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

... in the path /aws-service-role/es.amazonaws.com/.

@thibaudio
Copy link

You can just add this ressource before creating your domain:

resource "aws_iam_service_linked_role" "es" {
  aws_service_name = "es.amazonaws.com"
}

This will create the needed role for ES

@yruss972
Copy link

yruss972 commented Sep 4, 2018

Seems that aws_iam_service_linked_role resource fails if the role has already been created outside the current terraform state which makes this hard to couple with the creation of an es cluster.

lawliet89 added a commit to dsaidgovsg/terraform-modules that referenced this issue Sep 18, 2018
lawliet89 added a commit to dsaidgovsg/terraform-modules that referenced this issue Sep 18, 2018
* Fix issue related to ES Service linked role

See hashicorp/terraform-provider-aws#5218

* Fix repetition
@mvn-bachhuynh-dn
Copy link

@SylH You save my day! Thank you!

@eunomie
Copy link

eunomie commented Oct 25, 2018

You can just add this ressource before creating your domain:

resource "aws_iam_service_linked_role" "es" {
  aws_service_name = "es.amazonaws.com"
}

It may also need to add a dependency on this role from ES domains like

resource "aws_elasticsearch_domain" "es" {
  depends_on = ["aws_iam_service_linked_role.es"]
  ...
}

It will prevent issues on destroy:

Error: Error applying plan:

1 error(s) occurred:

* aws_iam_service_linked_role.es (destroy): 1 error(s) occurred:

* aws_iam_service_linked_role.es: Error waiting for role (arn:aws:iam::<...>:role/aws-service-role/es.amazonaws.com/AWSServiceRoleForAmazonElasticsearchService) to be deleted: unexpected state 'FAILED', wanted target 'SUCCEEDED'. last error: %!s(<nil>)

The error on destroy is raised because the role cannot be destroyed if there's one ES domain in the VPC. ES domain must be destroyed before the role.

@ernesto-miranda
Copy link

I had the same issue and I got over it by creating (through the GUI) a test ES domain first, that created the AWSServiceRoleForAmazonElasticsearchService and after that I was able to apply my terraform code successfully. It is kind of the obvious workaround but I'm commenting this anyway in case someone else got stuck.

@tomelliff
Copy link
Contributor

We just ran into this now and it looks like the createAwsElasticsearchIAMServiceRoleIfMissing is wrong because it's checking the error message for "Role not found" while the error message appears to contain "cannot be found" instead.

This is an easy fix, however I'm not sure of the benefit of doing so as we don't really automatically create service linked roles on the first run anywhere else and it's going to be an absolute pain to test that this works nicely in an automated way.

I'd recommend that we pull this out entirely and straight up recommend that users create the service linked role themselves either in a separate location (as this is an account wide thing and you may have multiple ES clusters in an AWS account) or use depends_on to set the dependency order as mentioned further up in the issue.

This approach then keeps us consistent with other resources with service linked roles available and doesn't add awkward, unexpected things (creating IAM things implicitly is a bit unusual, even if it is a service linked role) and means we don't have an untested block of code in the code base.

@bflad thoughts?

@bflad
Copy link
Contributor

bflad commented Jan 9, 2019

@tomelliff that's a great write up and I'd agree with you -- recommend we remove that code as you suggested (merging in 2.0 of the AWS provider just to be safe) and in its place we should certainly add information on the aws_elasticsearch_domain resource page about the aws_iam_service_linked_role resource, mentioning depends_on, and calling out it needs to happen only once per AWS account to close out this issue. Two separate pull requests (one for the code removal and one for the documentation) would be fantastic.

@bflad bflad self-assigned this Jan 9, 2019
@bflad bflad added documentation Introduces or discusses updates to documentation. and removed bug Addresses a defect in current functionality. labels Jan 9, 2019
@bflad
Copy link
Contributor

bflad commented Jan 9, 2019

(I've assigned to myself for tracking, but anyone can feel free to make the above PRs)

tomelliff added a commit to tomelliff/terraform-provider-aws that referenced this issue Jan 17, 2019
It's necessary to have already created the elasticsearch.amazonaws.com service linked role before attempting to create a VPC based ES cluster.

This can either be done separately from the ES cluster creation (useful if you have multiple ES clusters in an AWS account because the service linked role can only be created once) or the aws_elastcisearch_domain resource needs to wait for it to be created by using depends_on.

See the discussion on hashicorp#5218 for more information.
tomelliff added a commit to tomelliff/terraform-provider-aws that referenced this issue Jan 17, 2019
This is not currently working due to the error message being different than expected ('cannot be found' instead of the expected 'Role not found').

Instead of fixing the bug it was decided that a better approach would be to force users to explicitly create the IAM service linked role instead of doing it for them if it didn't exist.
This more closely matches what we do elsewhere and also means we aren't implicitly creating an IAM role despite the user not trying to do that which is particularly dangerous with IAM even if it is just a service linked role.

This is also reasonably necessary because it's going to be an absolute pain to catch this in acceptance tests as it's something that gets implicitly created once per account and then not managed by Terraform after that.

See the discussion on hashicorp#5218 for more information.
@tomelliff
Copy link
Contributor

@bflad sorry for the delay, made these changes a few days back while on the train but didn't push them until now. Let me know on each of the PRs if there's any issues with them.

@stantonk
Copy link

stantonk commented Jan 26, 2019

@eunomie i still get the same error:

aws_iam_service_linked_role.es: Error waiting for role (arn:aws:iam::REDACTED:role/aws-service-role/es.amazonaws.com/AWSServiceRoleForAmazonElasticsearchService) to be deleted: unexpected state 'FAILED', wanted target 'SUCCEEDED'. last error: %!s(<nil>)

despite having:

resource "aws_elasticsearch_domain" "es" {
  ...
  depends_on = [
    "aws_iam_service_linked_role.es",
  ]
}

@jgutierrez-adl
Copy link

jgutierrez-adl commented Jan 28, 2019

Please fix the example:

resource "aws_iam_service_linked_role" "es" {
  aws_service_name = "**elasticsearch**.amazonaws.com"
}

...

@bflad bflad added this to the v2.0.0 milestone Feb 23, 2019
@bflad
Copy link
Contributor

bflad commented Feb 23, 2019

The aws_elasticsearch_domain resource documentation page now includes information and an example of using the aws_iam_service_linked_role resource in this case. 👍

@bflad bflad closed this as completed Feb 23, 2019
@jeckhart
Copy link

Please fix the example:

resource "aws_iam_service_linked_role" "es" {
  aws_service_name = "**elasticsearch**.amazonaws.com"
}

...

@jgutierrez-adl As per the docs the proper aws_service_name is es.amazonaws.com. Thus, the proper terraform stanza is:

resource "aws_iam_service_linked_role" "es" {
  aws_service_name = "es.amazonaws.com"
}

@ghost
Copy link

ghost commented Mar 31, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

@ghost ghost locked and limited conversation to collaborators Mar 31, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
documentation Introduces or discusses updates to documentation. service/elasticsearch Issues and PRs that pertain to the elasticsearch service.
Projects
None yet
Development

No branches or pull requests