0

I'm trying to create a cloudformation template that will have, among other things, an ec2 instance with and EIP and an elasticsearch domain. The issue is that I'm creating a circular dependancy that I'm unable to figure out how to uncouple. Here it is.

The ec2 instance needs the address of the elasticsearch domain, so I'm adding it to a file in the UserData.

The elasticsearch AccessPolicies need the public IP of the EC2 instance to allow access from that server.

So there it is. Elasticsearch depends on the EIP of an ec2 instance, and the ec2 instance depends on the address of the elasticsearch domain. So what I'm trying to do is use the EIPAssociation to delay the need to create the EC2Instance until after the ElasticSearch domain has been created. But still no luck.

Does anyone have a good solution to this issue? I know I can have an AccessPolicy that is IAM based, but I'd much rather use the IP.

Thanks in advance.

Here is the code:

"MyEIP" : {
  "Type" : "AWS::EC2::EIP"
},
"ElasticsearchDomain": {
  "Type": "AWS::Elasticsearch::Domain",
  "Properties": {
    "ElasticsearchClusterConfig": {
      "DedicatedMasterEnabled": "false",
      "InstanceCount": "1",
      "ZoneAwarenessEnabled": "false",
      "InstanceType": "t2.micro.elasticsearch"
    },
    "EBSOptions": {
      "EBSEnabled": true,
      "Iops": 0,
      "VolumeSize": 10,
      "VolumeType": "gp2"
    },
    "SnapshotOptions": {
      "AutomatedSnapshotStartHour": "0"
    },
    "AccessPolicies":{
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "",
          "Effect": "Allow",
          "Principal": {
            "AWS": "*"
          },
          "Action": "es:*",
          "Resource": { "Fn::Join" : [ "", [
            "arn:aws:es:us-east-1:00000000000:domain/",
            { "Ref" : "ElasticsearchDomain" },
            "/*"
          ]]},
          "Condition": {
            "IpAddress": {
              "aws:SourceIp": { "Ref" : "MyEIP" }
            }
          }
        }
      ]
    },
    "AdvancedOptions": {
      "rest.action.multi.allow_explicit_index": "true"
    }
  }
},
"Ec2Instance" : {
  "Type" : "AWS::EC2::Instance",
  "Properties" : {
    "ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "64"]},
    "KeyName" : { "Ref" : "KeyName" },
    "InstanceType" : { "Ref": "ServerInstanceType" },
    "SecurityGroups" : [ { "Ref" : "InstanceSecurityGroup" } ],
    "Tags": [{
      "Key" : "Name",
      "Value" : {
        "Fn::Join" : [ "", [
          { "Ref" : "AWS::StackName" }
        ]]
      }
    }],
      "UserData" : { "Fn::Base64" : { "Fn::Join" : [ "", [
      "#!/bin/bash -ex\n",
      "echo \"",
      "STACK_NAME=", { "Ref" : "AWS::StackName"}, "\n",
      "ELASTICSEARCH_CLIENT=https://", { "Fn::GetAtt": [ "ElasticsearchDomain", "DomainEndpoint" ] }, "/\n",
  "\n",
      "\" > /etc/uni_creds\n"
    ]]}}
  }
},
"EIPAssociation" : {
   "Type": "AWS::EC2::EIPAssociation",
   "Properties": {
      "EIP": { "Ref" : "MyEIP" },
      "InstanceId": { "Ref" : "Ec2Instance" }
   }
}
randy
  • 9
  • 3
  • Have you logged this with AWS? You get free support from them for this, always worth going to the source if you have the option. – Chopper3 Jan 26 '17 at 17:33

1 Answers1

1

I think I've solved my issue. Although I was getting an error that was saying there was a circular dependancy between the EC2 instance, elasticsearch domain, and the EIP or EIPAssociation, the actual error was that I was referencing my elasticsearch domain in my elasticsearch domain.

"ElasticsearchDomain": {
  "Type": "AWS::Elasticsearch::Domain"
  ...
  { "Ref" : "ElasticsearchDomain" },
}

Which would obviously cause an issue. The error message was what got me running up he wrong tree. Anyway, dumb mistake. Hopefully no one else runs into this.

randy
  • 9
  • 3
  • 2
    I'm running into a similar issue, in that I want to let the ElasticsearchDomain's DomainName to be automatically created, but then I need to access that generated domain name from within the AccessPolicies Resource setting... Since doing a Ref to the object creates a circular dependency, how did you end up solving it? Did you assign a name statically, or did you find a way to keep it automatic? – Ken Simon Mar 17 '17 at 16:14
  • With the EIP, I could actually separate it because there is an EIPAssociation. So I could create the EIP and add it to the ElasticSearchPolicy. Then associate it after the EC2 instance has been created. I'm not sure if there is a work around for your situation. – randy Mar 19 '17 at 03:47