NOTICE - This is now supported natively by AWS as seen here. Thanks to contributors and friends! Always nice when AWS catches up to us :)
This still works, but you are better off using native support.
AWS CloudFormation does not support AWS Elasticsearch Service. This is a Lambda-backed custom resource to add support for AWS Elasticsearch Service to CloudFormation.
This package on NPM
This package on GitHub
This Lambda makes use of the Lambda-Backed CloudFormation Custom Resource flow module, cfn-lambda (GitHub / NPM).
See ./example.template.json for a sample CloudFormation template. The example uses Condition statements, Parameters, and dynamic ServiceToken generation fully.
"ResourceLogicalIdInResourcesObject": {
  "Type": "Type": "Custom::ElasticsearchDomain",
  "Properties": {
    "ServiceToken": "arn:aws:lambda:<cfn-region-id>:<your-account-id>:function:<this-deployed-lambda-name>",
    "DomainName": "STRING_VALUE", // REQUIRED - only required value from SDK
    "AccessPolicies": "STRING_VALUE", // JSON-stringified Access Policy
    "AdvancedOptions": {
      "someKey': "STRING_VALUE", // See latest SDK docs for supported vals,
      /* anotherKey: ... */    //   as this is optional and I pass them thru
    },
    "EBSOptions": {
      "EBSEnabled": true || false,
      "Iops": 0,
      "VolumeSize": 0,
      "VolumeType": 'standard | gp2 | io1'
    },
    "ElasticsearchClusterConfig": {
      "DedicatedMasterCount": 0,
      "DedicatedMasterEnabled": true || false,
      "DedicatedMasterType": <see ./schema.json for enum values>,
      "InstanceCount": 0,
      "InstanceType": <see ./schema.json for enum values>,
      "ZoneAwarenessEnabled": true || false
    },
    "SnapshotOptions": {
      "AutomatedSnapshotStartHour": 0
    }
  }
}
The way that takes 10 seconds...
# Have aws CLI installed + permissions for IAM and Lamdba
$ npm run cfn-lambda-deploy
You will have this resource installed in every supported Region globally!
... And the way more difficult way.
IMPORTANT: With this method, you must install this custom service Lambda in each AWS Region in which you want CloudFormation to be able to access the ElasticsearchDomain custom resource!
- Go to the AWS Lambda Console Create Function view:
- 
Zip this repository into /tmp/ElasticsearchDomain.zip$ cd $REPO_ROOT && zip -r /tmp/ElasticsearchDomain.zip;
- 
Enter a name in the Name blank. I suggest: CfnLambdaResouce-ElasticsearchDomain
- 
Enter a Description (optional). 
- 
Toggle Code Entry Type to "Upload a .ZIP file" 
- 
Click "Upload", navigate to and select /tmp/ElasticsearchDomain.zip
- 
Set the Timeout under Advanced Settings to 10 sec 
- 
Click the Role dropdown then click "Basic Execution Role". This will pop out a new window. 
- 
Select IAM Role, then select option "Create a new IAM Role" 
- 
Name the role lambda_cfn_elasticsearch_domain(or something descriptive)
- 
Click "View Policy Document", click "Edit" on the right, then hit "OK" 
- 
Copy and paste the ./execution-policy.jsondocument.
- 
Hit "Allow". The window will close. Go back to the first window if you are not already there. 
- 
Click "Create Function". Finally, done! Now go to Usage or see the example template. Next time, stick to the instant deploy script. 
Submit pull requests or Tweet @ayetempleton if you want to get involved with roadmap as well, or if you want to do this for a living :)
Work is (extremely) active, published here:
Andrew's NPM Account