This folder contains a Terraform module to deploy a
Couchbase cluster in AWS on top of an Auto Scaling Group.
This module can be used to deploy any or all of the Couchbase services (data, search, index, query) or Sync
Gateway. The idea is to create an Amazon Machine Image (AMI)
that has Couchbase and/or Sync Gateway installed using the
install-couchbase-server and/or
install-sync-gateway
modules.
How do you use this module?
This folder defines a Terraform module, which you can use in your
code by adding a module configuration and setting its source parameter to URL of this folder:
module"couchbase_cluster" {
# TODO: replace <VERSION> with the latest version from the releases page: https://github.com/gruntwork-io/terraform-aws-couchbase/releases
source = "github.com/gruntwork-io/terraform-aws-couchbase//modules/couchbase-cluster?ref=<VERSION>"# Specify the ID of the Couchbase AMI. You should build this using the scripts in the install-couchbase-server and/or # install-sync-gateway modules.
ami_id = "ami-abcd1234"# Configure and start Couchbase during boot.
user_data = <<-EOF
#!/bin/bash
/opt/couchbase/bin/run-couchbase-server --username admin --password password
EOF
# ... See variables.tf for the other parameters you must define for the couchbase-cluster module
}
Note the following parameters:
source: Use this parameter to specify the URL of the couchbase-cluster module. The double slash (//) is
intentional and required. Terraform uses it to specify subfolders within a Git repo (see module
sources). The ref parameter specifies a specific Git tag in
this repo. That way, instead of using the latest version of this module from the master branch, which
will change every time you run Terraform, you're using a fixed version of the repo.
user_data: Use this parameter to specify a User
Data script that each
server will run during boot. This is where you can use the
run-couchbase-server and/or
run-sync-gateway
scripts to configure and run Couchbase and/or Sync Gateway.
You can find the other parameters in variables.tf.
Check out the examples folder for
fully-working sample code.
How do you connect to the Couchbase cluster?
Connecting to Sync Gateway
We recommend deploying a load balancer in front of Sync Gateway using the load-balancer
module. If you do that, the module will
output the DNS name of the load balancer, and you can connect to that URL to connect to the Sync Gateway.
For replication with Couchbase Lite and other external clients, you should connect to the REST
API (default
port 4984). For unrestricted access to the database and administrative tasks, you should connect to the admin
UI (default port 4985, though it's typically only accessible
from localhost, as it provides admin access to everything in the DB!).
Connecting to the Couchbase Server Web Console
We recommend deploying a load balancer in front of your Couchbase Servers using the load-balancer
module. If you do that, the module will
output the DNS name of the load balancer, and you can connect to that URL to connect to access the Couchbase
Web Console at the /ui path.
Connecting to Couchbase Server via the SDK
Using a Load Balancer to talk to Couchbase APIs (e.g., via an SDK) is NOT recommended (see the Couchbase
FAQ for more info), so you will need to get the IPs of the
individual servers and connect to them directly. Since those servers run in an Auto Scaling Group (ASG) where servers
can be added/replaced/removed at any time, you can't get their IP addresses from Terraform. Instead, you'll need to look up
the IPs using the AWS APIs.
The easiest way to do that is to use the AWS SDK to look up the servers using EC2 Tags. Each server deployed by
the couchbase-cluster module has its Name and aws:autoscaling:groupName tag set to the value you pass in via the
cluster_name parameter. You can also specify custom tags via the tags parameter. You can use the AWS SDK to find
the IPs of all servers with those tags.
For example, using the AWS CLI, you can get the IPs for servers in us-east-1 with
the tag Name=couchbase-example as follows:
This will return a bunch of JSON that contains the IPs of the servers. You can then use the Couchbase
SDK for your programming language to connect
to these IPs. See the Network Configuration
documentation to see what
ports different Couchbase services use.
This module runs Couchbase on top of an Auto Scaling Group (ASG). Typically, you
should run the ASG with multiple Instances spread across multiple Availability
Zones. Each of the EC2
Instances should be running an AMI that has Couchbase and/or Sync Gateway installed via the
install-couchbase-server and/or
install-sync-gateway
modules. You pass in the ID of the AMI to run using the ami_id input parameter.
EBS Volumes
This module can optionally create an EBS volume for each EC2 Instance in the ASG. You
can use these volume to store Couchbase data. As explained in the
documentation,
we recommend using two EBS Volumes, one for the Couchbase data dir and one for the index dir.
Security Group
Each EC2 Instance in the ASG has a Security Group that allows minimal connectivity:
All outbound requests
Inbound SSH access from the CIDR blocks and security groups you specify
Each EC2 Instance in the ASG has an IAM Role attached.
The IAM Role ARN and ID are exported as output variables if you need to add additional permissions.
How do you roll out updates?
If you want to deploy a new version of Couchbase across the cluster, the best way to do that is to:
Rolling deploy:
Build a new AMI.
Set the ami_id parameter to the ID of the new AMI.
Run terraform apply.
This updates the Launch Configuration of the ASG, so any new Instances in the ASG will have your new AMI, but it
does NOT actually deploy those new instances. You'll have to force the ASG to update the instances as follows.
Remove one of the old nodes from the cluster
(docs).
Terminate the corresponding EC2 Instance.
The ASG will automatically launch a replacement EC2 Instance after a minute with the new code.
Wait for the replacement node to join the cluster and catch up on replication.
Repeat steps 5-7 for the remaining nodes.
New cluster:
Build a new AMI.
Create a totally new ASG using the couchbase-cluster module with the ami_id set to the new AMI, but all
other parameters the same as the old cluster.
Wait for all the nodes in the new ASG to join the cluster and catch up on replication.
Remove each of the nodes from the old cluster
(docs).
Remove the old ASG by removing that couchbase-cluster module from your code.
We may add a script in the future to automate this process (PRs are welcome!).
Security
Here are some of the main security considerations to keep in mind when using this module:
Couchbase can encrypt all of its network traffic. For instructions on enabling network encryption, have a look at the
encryption on the wire documentation.
Encryption at rest
The EC2 Instances in the cluster can store their data in one of two locations:
An EBS Volume, if you enable it with this module. Set the ebs_volume_encrypted parameter to true to enable
encryption for the EBS volume.
The root volume. To encrypt the root volume, you must encrypt your AMI. If you're creating the AMI using Packer
(e.g. as shown in the couchbase-ami example),
you need to set the encrypt_boot parameter to
true.
Dedicated instances
If you wish to use dedicated instances, you can set the tenancy parameter to "dedicated" in this module.
Security groups
This module attaches a security group to each EC2 Instance that allows inbound requests as follows:
SSH: For the SSH port (default: 22), you can use the allowed_ssh_cidr_blocks parameter to control the list of CIDR blocks that will be allowed access. You can use
the allowed_inbound_ssh_security_group_ids parameter to control the list of source Security Groups that will be
allowed access.
You can associate an EC2 Key Pair with each
of the EC2 Instances in this cluster by specifying the Key Pair's name in the ssh_key_name variable. If you don't
want to associate a Key Pair with these servers, set ssh_key_name to an empty string.
Questions? Ask away.
We're here to talk about our services, answer any questions, give advice, or just to chat.
{"treedata":{"name":"root","toggled":true,"children":[{"name":".circleci","children":[{"name":"config.yml","path":".circleci/config.yml","sha":"193cb67012263437903101c15897eb82471f70fc"},{"name":"publish-amis.sh","path":".circleci/publish-amis.sh","sha":"abb6cf0e36e53f65074d47170f147d06036f5797"}]},{"name":".gitignore","path":".gitignore","sha":"85435101db88fb540a38f4b6dfa03ffd79d97633"},{"name":".pre-commit-config.yaml","path":".pre-commit-config.yaml","sha":"1142c08a1fb176570e5470375e110838234ebfa4"},{"name":".pre-commit-hooks.yaml","path":".pre-commit-hooks.yaml","sha":"92462242c5c4a3aa0f5d5f5b19a81811c71e4b49"},{"name":"CODEOWNERS","path":"CODEOWNERS","sha":"28333bea0519ace338740140eff651c08cbf27d7"},{"name":"CONTRIBUTING.md","path":"CONTRIBUTING.md","sha":"de3aa54eede67b6eddf1776e08f8441973f57fc1"},{"name":"LICENSE","path":"LICENSE","sha":"7a4a3ea2424c09fbe48d455aed1eaa94d9124835"},{"name":"NOTICE","path":"NOTICE","sha":"77030eb8f10190ffd42c28bb41922f8c91b089a1"},{"name":"README.md","path":"README.md","sha":"ddbfff5345200723a3881695f9e8fd3cd6d4bb77"},{"name":"_docs","children":[{"name":"couchbase-multi-cluster-architecture.png","path":"_docs/couchbase-multi-cluster-architecture.png","sha":"60ec0e7cca94e2400662b7ed8565833b84f142be"},{"name":"couchbase-multi-datacenter-replication-architecture.png","path":"_docs/couchbase-multi-datacenter-replication-architecture.png","sha":"d19384e42f436e9a96ae112853e679208d8cc513"},{"name":"couchbase-multi-datacenter-replication-architecture.psd","path":"_docs/couchbase-multi-datacenter-replication-architecture.psd","sha":"9750878217d877c6fed0d70c57d4e4f1ed732a4a"},{"name":"couchbase-single-cluster-architecture.png","path":"_docs/couchbase-single-cluster-architecture.png","sha":"448144c58bddc5bf46c096289344d66733bc7592"}]},{"name":"examples","children":[{"name":"couchbase-ami","children":[{"name":"README.md","path":"examples/couchbase-ami/README.md","sha":"db19908786e1f925f14a63e9f74e12be68ecea41"},{"name":"couchbase.json","path":"examples/couchbase-ami/couchbase.json","sha":"2071002cbd823dbdca82d0fa2df41d5edabd993d"},{"name":"sync_gateway.json","path":"examples/couchbase-ami/sync_gateway.json","sha":"067df37d31d51feae93105d11ed8d1539f7c6e3a"}]},{"name":"couchbase-cluster-mds","children":[{"name":"README.md","path":"examples/couchbase-cluster-mds/README.md","sha":"ad316fdc85a5687e6310614d1d48f6fa9dcc33bc"},{"name":"local-test","children":[{"name":".env","path":"examples/couchbase-cluster-mds/local-test/.env","sha":"fb429afef6ea74aa33abe5e4319b3538a2bd7263"},{"name":"docker-compose.yml","path":"examples/couchbase-cluster-mds/local-test/docker-compose.yml","sha":"791983d4ac39cc4ff6f7f613e1d78976287f6dbf"}]},{"name":"main.tf","path":"examples/couchbase-cluster-mds/main.tf","sha":"cd89e4c4b2139134ceefcc709a00543e843adf54"},{"name":"outputs.tf","path":"examples/couchbase-cluster-mds/outputs.tf","sha":"4a60475339777bdbf95b6045d7d2e956c2dbe927"},{"name":"user-data","children":[{"name":"user-data-couchbase-data-nodes.sh","path":"examples/couchbase-cluster-mds/user-data/user-data-couchbase-data-nodes.sh","sha":"feb4ae958397c19ded82e21fb60578fbb1ac19e3"},{"name":"user-data-couchbase-index-query-search-nodes.sh","path":"examples/couchbase-cluster-mds/user-data/user-data-couchbase-index-query-search-nodes.sh","sha":"c13d780c95601b1bfa157d65329312866a18f3ff"},{"name":"user-data-sync-gateway.sh","path":"examples/couchbase-cluster-mds/user-data/user-data-sync-gateway.sh","sha":"99aa5e77cfff2774bd0020d51ea6ba77a49a3674"}]},{"name":"variables.tf","path":"examples/couchbase-cluster-mds/variables.tf","sha":"779b652d4ae2bee64e852131b9ca85f39f0bdfd8"}]},{"name":"couchbase-cluster-simple-dns-tls","children":[{"name":"README.md","path":"examples/couchbase-cluster-simple-dns-tls/README.md","sha":"d2e537222684a472713c29292f4160f811b3ed62"},{"name":"local-test","children":[{"name":".env","path":"examples/couchbase-cluster-simple-dns-tls/local-test/.env","sha":"fb429afef6ea74aa33abe5e4319b3538a2bd7263"},{"name":"docker-compose.yml","path":"examples/couchbase-cluster-simple-dns-tls/local-test/docker-compose.yml","sha":"e8980454ea06f365ee92df93aaf6b007c20437cf"}]},{"name":"main.tf","path":"examples/couchbase-cluster-simple-dns-tls/main.tf","sha":"21623b967fa4e0f2224d89cec5ea8d4a9a67d028"},{"name":"outputs.tf","path":"examples/couchbase-cluster-simple-dns-tls/outputs.tf","sha":"bf8c18b332125a2e0e68e210b26fa48dd6594039"},{"name":"user-data","children":[{"name":"user-data.sh","path":"examples/couchbase-cluster-simple-dns-tls/user-data/user-data.sh","sha":"bf62d443d7e8226ee7630d5807b3e4be533151f8"}]},{"name":"variables.tf","path":"examples/couchbase-cluster-simple-dns-tls/variables.tf","sha":"c4b4418dc839693bd8dbde269a82ac31ef03ce7c"}]},{"name":"couchbase-cluster-simple","children":[{"name":"README.md","path":"examples/couchbase-cluster-simple/README.md","sha":"e4126f146380b68bca8e2075b3579c32d564a2f5"},{"name":"local-test","children":[{"name":".env","path":"examples/couchbase-cluster-simple/local-test/.env","sha":"fb429afef6ea74aa33abe5e4319b3538a2bd7263"},{"name":"docker-compose.yml","path":"examples/couchbase-cluster-simple/local-test/docker-compose.yml","sha":"e8980454ea06f365ee92df93aaf6b007c20437cf"}]},{"name":"user-data","children":[{"name":"user-data.sh","path":"examples/couchbase-cluster-simple/user-data/user-data.sh","sha":"f5107d31dd228a3268a894f86978fa30abc29d20"}]}]},{"name":"couchbase-multi-datacenter-replication","children":[{"name":"README.md","path":"examples/couchbase-multi-datacenter-replication/README.md","sha":"e7b299a03d14f1ff713fc57363d6c9e250bbc1ed"},{"name":"local-test","children":[{"name":".env","path":"examples/couchbase-multi-datacenter-replication/local-test/.env","sha":"6112e2bcb38259397b81257ebbf422ebaccec068"},{"name":"docker-compose.yml","path":"examples/couchbase-multi-datacenter-replication/local-test/docker-compose.yml","sha":"12db84e3008f3498f58fe6bb64afcf4d69448410"}]},{"name":"main.tf","path":"examples/couchbase-multi-datacenter-replication/main.tf","sha":"5773fad2e489d3cefd5a2e03de92c83a886c1263"},{"name":"outputs.tf","path":"examples/couchbase-multi-datacenter-replication/outputs.tf","sha":"b176beecefad8213f0c8d953cb1451deb827dba8"},{"name":"user-data","children":[{"name":"user-data-primary.sh","path":"examples/couchbase-multi-datacenter-replication/user-data/user-data-primary.sh","sha":"71a34464aaee5f324190f9fa60f620769a9923a8"},{"name":"user-data-replica.sh","path":"examples/couchbase-multi-datacenter-replication/user-data/user-data-replica.sh","sha":"aa410fd045f04a9788a7b09fa5fb2c03970a5f0e"}]},{"name":"variables.tf","path":"examples/couchbase-multi-datacenter-replication/variables.tf","sha":"99c18d0b5dcda11b3999a3cae808f80944be9255"}]},{"name":"local-mocks","children":[{"name":"README.md","path":"examples/local-mocks/README.md","sha":"4c6d80b3998e1027f5c2a4c71715772b81830b31"},{"name":"aws.sh","path":"examples/local-mocks/aws.sh","sha":"20408cfe23eb7a3cf2451fbb7d8214a0b746b1cc"},{"name":"entrypoint.sh","path":"examples/local-mocks/entrypoint.sh","sha":"51c897ba4b159e58381eb23b760c84696dc9b681"},{"name":"mount-volume.sh","path":"examples/local-mocks/mount-volume.sh","sha":"c9fa0b283e7ce1a0b1652dc4565bfe2740dcc820"}]}]},{"name":"main.tf","path":"main.tf","sha":"1868c0ad8ffa0ce7ebbe695d733820e3ea188426"},{"name":"modules","children":[{"name":"couchbase-cluster","children":[{"name":"README.md","path":"modules/couchbase-cluster/README.md","sha":"bb1edabb679a103375a61ed16fa0ad6f63991a50","toggled":true},{"name":"main.tf","path":"modules/couchbase-cluster/main.tf","sha":"ed88c06cd25e6926b9b228a1eb66a35b52880070"},{"name":"outputs.tf","path":"modules/couchbase-cluster/outputs.tf","sha":"43f4b8d33b580deface276e3f49680e26daf7b7c"},{"name":"variables.tf","path":"modules/couchbase-cluster/variables.tf","sha":"188c2383e0211961663d26d98216ac3dd0a76418"}],"toggled":true},{"name":"couchbase-commons","children":[{"name":"README.md","path":"modules/couchbase-commons/README.md","sha":"f1367ace90480981e5dceba2c7cb84f6878a1fb8"},{"name":"couchbase-common.sh","path":"modules/couchbase-commons/couchbase-common.sh","sha":"6ef25a60dabe4182d0805d115a6fed1cba5422a0"},{"name":"couchbase-rally-point","path":"modules/couchbase-commons/couchbase-rally-point","sha":"103bc2dbc4b2a7d51b56f08eb186ce2f00b323c7"},{"name":"mount-volume.sh","path":"modules/couchbase-commons/mount-volume.sh","sha":"3767b9a3ea78e4fa1f48f29866dcef430a5fa9fe"}]},{"name":"couchbase-iam-policies","children":[{"name":"README.md","path":"modules/couchbase-iam-policies/README.md","sha":"922154296ebbb41e9343b0ead8fb469007944048"},{"name":"main.tf","path":"modules/couchbase-iam-policies/main.tf","sha":"e29f3ca8e36f743680465589e7a154d986a28367"},{"name":"variables.tf","path":"modules/couchbase-iam-policies/variables.tf","sha":"26ac224bac34cf635bff250be92515b7b6f97070"}]},{"name":"couchbase-server-security-group-rules","children":[{"name":"README.md","path":"modules/couchbase-server-security-group-rules/README.md","sha":"208e46d7c9647c61941dd77b212009fab3d16fd5"},{"name":"main.tf","path":"modules/couchbase-server-security-group-rules/main.tf","sha":"5d0f320b8f97d6f9855e748495c8e27315d47522"},{"name":"outputs.tf","path":"modules/couchbase-server-security-group-rules/outputs.tf","sha":"4c5c8af8a2fb065200fdc7090a9c1b5cd226d5d6"},{"name":"variables.tf","path":"modules/couchbase-server-security-group-rules/variables.tf","sha":"1f00f38fc9e89210f0ca8bc2189d6615a9e4481b"}]},{"name":"install-couchbase-server","children":[{"name":"README.md","path":"modules/install-couchbase-server/README.md","sha":"c61cfa9d91a6fdaf8b269dbe9e00018addb74786"},{"name":"disable-thp","path":"modules/install-couchbase-server/disable-thp","sha":"2ead9b6e580a16712375f207ba4261884157f88e"},{"name":"install-couchbase-server","path":"modules/install-couchbase-server/install-couchbase-server","sha":"ebee490745cf82f243b3521a6f723a50c76ac57d"}]},{"name":"install-sync-gateway","children":[{"name":"README.md","path":"modules/install-sync-gateway/README.md","sha":"abf0948beecb4ab06a9d55c402d8c1b444d95c6d"},{"name":"install-sync-gateway","path":"modules/install-sync-gateway/install-sync-gateway","sha":"4b1d60c9e73bc5d10801bb80949708efe8f0b311"}]},{"name":"load-balancer-target-group","children":[{"name":"README.md","path":"modules/load-balancer-target-group/README.md","sha":"b71f21e4aa7c506b9a4df23919e2e844609c6b73"},{"name":"main.tf","path":"modules/load-balancer-target-group/main.tf","sha":"e466de27ac669e03b3e6074a3e5d3c7ca5beb2e8"},{"name":"outputs.tf","path":"modules/load-balancer-target-group/outputs.tf","sha":"c66bcfb9097a75d942502aa134cdc1809e108e28"},{"name":"variables.tf","path":"modules/load-balancer-target-group/variables.tf","sha":"d0bbba3368e012a21a9254b54606dab54f44a20f"}]},{"name":"load-balancer","children":[{"name":"README.md","path":"modules/load-balancer/README.md","sha":"c3e457f41ef1b3797e96bd395931b4b86d8763f7"},{"name":"main.tf","path":"modules/load-balancer/main.tf","sha":"b2125b3f14f65a38814e1babddca7ca321701064"},{"name":"outputs.tf","path":"modules/load-balancer/outputs.tf","sha":"74124a4d0972376f7756ba927604637536b4a7b6"},{"name":"variables.tf","path":"modules/load-balancer/variables.tf","sha":"990d99f7ef2bc15d0656b66c8640e01393f9d10b"}]},{"name":"run-couchbase-server","children":[{"name":"README.md","path":"modules/run-couchbase-server/README.md","sha":"e76309c1cec9658a928bc868a21efac02312e72f"},{"name":"run-couchbase-server","path":"modules/run-couchbase-server/run-couchbase-server","sha":"625f642186f6d10e1e2e7870da264a462bc18554"}]},{"name":"run-replication","children":[{"name":"README.md","path":"modules/run-replication/README.md","sha":"70b7aa50e06d1c390b2f7921e8293c4e45de4fae"},{"name":"run-replication","path":"modules/run-replication/run-replication","sha":"419c2f1cca183fd2f1fd9a94a11ba587609edded"}]},{"name":"run-sync-gateway","children":[{"name":"README.md","path":"modules/run-sync-gateway/README.md","sha":"0a0d2c6391c30545d5e80fb1f34b568c6231cee4"},{"name":"run-sync-gateway","path":"modules/run-sync-gateway/run-sync-gateway","sha":"8f827839afe57bd36a4a6c35ef2a169fa6992054"}]},{"name":"sync-gateway-security-group-rules","children":[{"name":"README.md","path":"modules/sync-gateway-security-group-rules/README.md","sha":"f5e50b67844506d15a277e3578105dc3a1225c95"},{"name":"main.tf","path":"modules/sync-gateway-security-group-rules/main.tf","sha":"87028ff2de4562224ec2d20986acbe1eb4faaeee"},{"name":"outputs.tf","path":"modules/sync-gateway-security-group-rules/outputs.tf","sha":"20655ee9c7729f093241ec28e31b197e7d4fbdca"},{"name":"variables.tf","path":"modules/sync-gateway-security-group-rules/variables.tf","sha":"cf39a81712ec01fc36b9f83dd7e62226b1d08a60"}]}],"toggled":true},{"name":"outputs.tf","path":"outputs.tf","sha":"4138cc3c41b0d5ebf4ce088431332550eb503e10"},{"name":"test","children":[{"name":"Gopkg.lock","path":"test/Gopkg.lock","sha":"42577e372ee9d685a77d83537a631f1d6c18fdf5"},{"name":"Gopkg.toml","path":"test/Gopkg.toml","sha":"4925cde6b22bd6697a2f5fb81a86ba60628786a5"},{"name":"README.md","path":"test/README.md","sha":"36e97d94c441e302871e22126004113f3ffb84d1"},{"name":"couchbase_helpers.go","path":"test/couchbase_helpers.go","sha":"43bddbac0885037fcadcdcf81ccafdeeabe16a37"},{"name":"couchbase_multi_cluster_test.go","path":"test/couchbase_multi_cluster_test.go","sha":"3f4ce22c64179b7c04710e7903dc616722215131"},{"name":"couchbase_multi_datacenter_replication_test.go","path":"test/couchbase_multi_datacenter_replication_test.go","sha":"cdb6df8391670b38cb7185d97f3522eabba7cee4"},{"name":"couchbase_single_cluster_dns_tls_test.go","path":"test/couchbase_single_cluster_dns_tls_test.go","sha":"0fd10dc7be5d802ad648fec8d486f81d681ebfc0"},{"name":"couchbase_single_cluster_test.go","path":"test/couchbase_single_cluster_test.go","sha":"4defb9cda7c5b2d0077849b4869d6c72c0876456"},{"name":"docker_compose_test.go","path":"test/docker_compose_test.go","sha":"29c79d54d53f5858a9ad3713ff80d1799d63a9f3"},{"name":"terratest_helpers.go","path":"test/terratest_helpers.go","sha":"29cc6e09e083f421dbfc153990b3d3fe9cc8cf76"}]},{"name":"variables.tf","path":"variables.tf","sha":"e463cef71c94336b5f14de9f3ddc1cdf7d4edaec"}]},"detailsContent":"<h1 class=\"preview__body--title\" id=\"couchbase-cluster\">Couchbase Cluster</h1><div class=\"preview__body--border\"></div><p>This folder contains a <a href=\"https://www.terraform.io/\" class=\"preview__body--description--blue\" target=\"_blank\">Terraform</a> module to deploy a\n<a href=\"https://www.couchbase.com/\" class=\"preview__body--description--blue\" target=\"_blank\">Couchbase</a> cluster in <a href=\"https://aws.amazon.com/\" class=\"preview__body--description--blue\" target=\"_blank\">AWS</a> on top of an Auto Scaling Group.\nThis module can be used to deploy any or all of the Couchbase services (data, search, index, query) or Sync\nGateway. The idea is to create an <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html\" class=\"preview__body--description--blue\" target=\"_blank\">Amazon Machine Image (AMI)</a>\nthat has Couchbase and/or Sync Gateway installed using the\n<a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/install-couchbase-server\" class=\"preview__body--description--blue\">install-couchbase-server</a> and/or\n<a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/install-sync-gateway\" class=\"preview__body--description--blue\">install-sync-gateway</a>\nmodules.</p>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-you-use-this-module\">How do you use this module?</h2>\n<p>This folder defines a <a href=\"https://www.terraform.io/docs/modules/usage.html\" class=\"preview__body--description--blue\" target=\"_blank\">Terraform module</a>, which you can use in your\ncode by adding a <code>module</code> configuration and setting its <code>source</code> parameter to URL of this folder:</p>\n<pre><span class=\"hljs-keyword\">module</span> <span class=\"hljs-string\">\"couchbase_cluster\"</span> {\n <span class=\"hljs-comment\"># <span class=\"hljs-doctag\">TODO:</span> replace <VERSION> with the latest version from the releases page: https://github.com/gruntwork-io/terraform-aws-couchbase/releases</span>\n source = <span class=\"hljs-string\">\"github.com/gruntwork-io/terraform-aws-couchbase//modules/couchbase-cluster?ref=<VERSION>\"</span>\n\n <span class=\"hljs-comment\"># Specify the ID of the Couchbase AMI. You should build this using the scripts in the install-couchbase-server and/or </span>\n <span class=\"hljs-comment\"># install-sync-gateway modules.</span>\n ami_id = <span class=\"hljs-string\">\"ami-abcd1234\"</span>\n \n <span class=\"hljs-comment\"># Configure and start Couchbase during boot. </span>\n user_data = <<-EOF\n <span class=\"hljs-comment\">#!/bin/bash</span>\n /opt/couchbase/bin/run-couchbase-server --username admin --password password\n EOF\n \n <span class=\"hljs-comment\"># ... See variables.tf for the other parameters you must define for the couchbase-cluster module</span>\n}\n</pre>\n<p>Note the following parameters:</p>\n<ul>\n<li>\n<p><code>source</code>: Use this parameter to specify the URL of the couchbase-cluster module. The double slash (<code>//</code>) is\nintentional and required. Terraform uses it to specify subfolders within a Git repo (see <a href=\"https://www.terraform.io/docs/modules/sources.html\" class=\"preview__body--description--blue\" target=\"_blank\">module\nsources</a>). The <code>ref</code> parameter specifies a specific Git tag in\nthis repo. That way, instead of using the latest version of this module from the <code>master</code> branch, which\nwill change every time you run Terraform, you're using a fixed version of the repo.</p>\n</li>\n<li>\n<p><code>ami_id</code>: Use this parameter to specify the ID of a Couchbase <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html\" class=\"preview__body--description--blue\" target=\"_blank\">Amazon Machine Image\n(AMI)</a> to deploy on each server in the cluster. You\nshould install Couchbase and/or Sync Gateway in this AMI using the scripts in the\n<a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/install-couchbase-server\" class=\"preview__body--description--blue\">install-couchbase-server</a> and/or\n<a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/install-sync-gateway\" class=\"preview__body--description--blue\">install-sync-gateway</a>\nmodules.</p>\n</li>\n<li>\n<p><code>user_data</code>: Use this parameter to specify a <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html#user-data-shell-scripts\" class=\"preview__body--description--blue\" target=\"_blank\">User\nData</a> script that each\nserver will run during boot. This is where you can use the\n<a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/run-couchbase-server\" class=\"preview__body--description--blue\">run-couchbase-server</a> and/or\n<a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/run-sync-gateway\" class=\"preview__body--description--blue\">run-sync-gateway</a>\nscripts to configure and run Couchbase and/or Sync Gateway.</p>\n</li>\n</ul>\n<p>You can find the other parameters in <a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/couchbase-cluster/variables.tf\" class=\"preview__body--description--blue\">variables.tf</a>.</p>\n<p>Check out the <a href=\"/repos/v0.2.2/terraform-aws-couchbase/examples\" class=\"preview__body--description--blue\">examples folder</a> for\nfully-working sample code.</p>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-you-connect-to-the-couchbase-cluster\">How do you connect to the Couchbase cluster?</h2>\n<h3 class=\"preview__body--subtitle\" id=\"connecting-to-sync-gateway\">Connecting to Sync Gateway</h3>\n<p>We recommend deploying a load balancer in front of Sync Gateway using the <a href=\"/repos/v0.2.2/terraform-aws-couchbase/examples\" class=\"preview__body--description--blue\">load-balancer\nmodule</a>. If you do that, the module will\noutput the DNS name of the load balancer, and you can connect to that URL to connect to the Sync Gateway.</p>\n<p>For replication with Couchbase Lite and other external clients, you should connect to the <a href=\"https://developer.couchbase.com/documentation/mobile/1.5/guides/sync-gateway/rest-api-client/index.html\" class=\"preview__body--description--blue\" target=\"_blank\">REST\nAPI</a> (default\nport 4984). For unrestricted access to the database and administrative tasks, you should connect to the <a href=\"https://github.com/couchbaselabs/sync_gateway_admin_ui\" class=\"preview__body--description--blue\" target=\"_blank\">admin\nUI</a> (default port 4985, though it's typically only accessible\nfrom localhost, as it provides admin access to everything in the DB!).</p>\n<h3 class=\"preview__body--subtitle\" id=\"connecting-to-the-couchbase-server-web-console\">Connecting to the Couchbase Server Web Console</h3>\n<p>We recommend deploying a load balancer in front of your Couchbase Servers using the <a href=\"/repos/v0.2.2/terraform-aws-couchbase/examples\" class=\"preview__body--description--blue\">load-balancer\nmodule</a>. If you do that, the module will\noutput the DNS name of the load balancer, and you can connect to that URL to connect to access the <a href=\"https://developer.couchbase.com/documentation/server/current/admin/ui-intro.html\" class=\"preview__body--description--blue\" target=\"_blank\">Couchbase\nWeb Console</a> at the <code>/ui</code> path.</p>\n<h3 class=\"preview__body--subtitle\" id=\"connecting-to-couchbase-server-via-the-sdk\">Connecting to Couchbase Server via the SDK</h3>\n<p>Using a Load Balancer to talk to Couchbase APIs (e.g., via an SDK) is NOT recommended (see <a href=\"https://blog.couchbase.com/couchbase-101-q-and-a/\" class=\"preview__body--description--blue\" target=\"_blank\">the Couchbase\nFAQ</a> for more info), so you will need to get the IPs of the\nindividual servers and connect to them directly. Since those servers run in an Auto Scaling Group (ASG) where servers\ncan be added/replaced/removed at any time, you can't get their IP addresses from Terraform. Instead, you'll need to look up\nthe IPs using the AWS APIs.</p>\n<p>The easiest way to do that is to use the AWS SDK to look up the servers using EC2 Tags. Each server deployed by\nthe <code>couchbase-cluster</code> module has its <code>Name</code> and <code>aws:autoscaling:groupName</code> tag set to the value you pass in via the\n<code>cluster_name</code> parameter. You can also specify custom tags via the <code>tags</code> parameter. You can use the AWS SDK to find\nthe IPs of all servers with those tags.</p>\n<p>For example, using the <a href=\"https://aws.amazon.com/cli/\" class=\"preview__body--description--blue\" target=\"_blank\">AWS CLI</a>, you can get the IPs for servers in <code>us-east-1</code> with\nthe tag <code>Name=couchbase-example</code> as follows:</p>\n<pre>aws ec2 describe-instances <span class=\"hljs-string\">\\</span>\n --region <span class=\"hljs-string\">\"us-east-1\"</span> <span class=\"hljs-string\">\\</span>\n --filter <span class=\"hljs-string\">\\</span>\n <span class=\"hljs-string\">\"Name=tag:Name,Values=couchbase-example\"</span> <span class=\"hljs-string\">\\</span>\n <span class=\"hljs-string\">\"Name=instance-state-name,Values=running\"</span>\n</pre>\n<p>This will return a bunch of JSON that contains the IPs of the servers. You can then use the <a href=\"https://developer.couchbase.com/documentation/server/4.0/sdks/intro.html\" class=\"preview__body--description--blue\" target=\"_blank\">Couchbase\nSDK</a> for your programming language to connect\nto these IPs. See the <a href=\"https://developer.couchbase.com/documentation/server/current/install/install-ports.html\" class=\"preview__body--description--blue\" target=\"_blank\">Network Configuration\ndocumentation</a> to see what\nports different Couchbase services use.</p>\n<h2 class=\"preview__body--subtitle\" id=\"whats-included-in-this-module\">What's included in this module?</h2>\n<p>This module creates the following:</p>\n<ul>\n<li><a href=\"#auto-scaling-group\" class=\"preview__body--description--blue\">Auto Scaling Group</a></li>\n<li><a href=\"#ebs-volumes\" class=\"preview__body--description--blue\">EBS Volumes</a></li>\n<li><a href=\"#security-group\" class=\"preview__body--description--blue\">Security Group</a></li>\n<li><a href=\"#iam-role-and-permissions\" class=\"preview__body--description--blue\">IAM Role and Permissions</a></li>\n</ul>\n<h3 class=\"preview__body--subtitle\" id=\"auto-scaling-group\">Auto Scaling Group</h3>\n<p>This module runs Couchbase on top of an <a href=\"https://aws.amazon.com/autoscaling/\" class=\"preview__body--description--blue\" target=\"_blank\">Auto Scaling Group (ASG)</a>. Typically, you\nshould run the ASG with multiple Instances spread across multiple <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html\" class=\"preview__body--description--blue\" target=\"_blank\">Availability\nZones</a>. Each of the EC2\nInstances should be running an AMI that has Couchbase and/or Sync Gateway installed via the\n<a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/install-couchbase-server\" class=\"preview__body--description--blue\">install-couchbase-server</a> and/or\n<a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/install-sync-gateway\" class=\"preview__body--description--blue\">install-sync-gateway</a>\nmodules. You pass in the ID of the AMI to run using the <code>ami_id</code> input parameter.</p>\n<h3 class=\"preview__body--subtitle\" id=\"ebs-volumes\">EBS Volumes</h3>\n<p>This module can optionally create an <a href=\"https://aws.amazon.com/ebs/\" class=\"preview__body--description--blue\" target=\"_blank\">EBS volume</a> for each EC2 Instance in the ASG. You\ncan use these volume to store Couchbase data. As explained in <a href=\"https://developer.couchbase.com/documentation/server/current/cloud/couchbase-aws-best-practices.html#topic_ghd_55f_nbb__aws-storage\" class=\"preview__body--description--blue\" target=\"_blank\">the\ndocumentation</a>,\nwe recommend using two EBS Volumes, one for the Couchbase data dir and one for the index dir.</p>\n<h3 class=\"preview__body--subtitle\" id=\"security-group\">Security Group</h3>\n<p>Each EC2 Instance in the ASG has a Security Group that allows minimal connectivity:</p>\n<ul>\n<li>All outbound requests</li>\n<li>Inbound SSH access from the CIDR blocks and security groups you specify</li>\n</ul>\n<p>The Security Group ID is exported as an output variable which you can use with the\n<a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/couchbase-server-security-group-rules\" class=\"preview__body--description--blue\">couchbase-server-security-group-rules</a> and\n<a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/sync-gateway-security-group-rules\" class=\"preview__body--description--blue\">sync-gateway-security-group-rules</a>\nmodules to open up all the ports necessary for Couchbase and Sync Gateway.</p>\n<p>Check out the <a href=\"#security\" class=\"preview__body--description--blue\">Security section</a> for more details.</p>\n<h3 class=\"preview__body--subtitle\" id=\"iam-role-and-permissions\">IAM Role and Permissions</h3>\n<p>Each EC2 Instance in the ASG has an <a href=\"http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html\" class=\"preview__body--description--blue\" target=\"_blank\">IAM Role</a> attached.\nThe IAM Role ARN and ID are exported as output variables if you need to add additional permissions.</p>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-you-roll-out-updates\">How do you roll out updates?</h2>\n<p>If you want to deploy a new version of Couchbase across the cluster, the best way to do that is to:</p>\n<ol>\n<li>\n<p>Rolling deploy:</p>\n<ol>\n<li>Build a new AMI.</li>\n<li>Set the <code>ami_id</code> parameter to the ID of the new AMI.</li>\n<li>Run <code>terraform apply</code>.</li>\n<li>This updates the Launch Configuration of the ASG, so any new Instances in the ASG will have your new AMI, but it\ndoes NOT actually deploy those new instances. You'll have to force the ASG to update the instances as follows.</li>\n<li>Remove one of the old nodes from the cluster\n(<a href=\"https://developer.couchbase.com/documentation/server/3.x/admin/Tasks/rebalance-remove-node.html\" class=\"preview__body--description--blue\" target=\"_blank\">docs</a>).</li>\n<li>Terminate the corresponding EC2 Instance.</li>\n<li>The ASG will automatically launch a replacement EC2 Instance after a minute with the new code.</li>\n<li>Wait for the replacement node to join the cluster and catch up on replication.</li>\n<li>Repeat steps 5-7 for the remaining nodes.</li>\n</ol>\n</li>\n<li>\n<p>New cluster:</p>\n<ol>\n<li>Build a new AMI.</li>\n<li>Create a totally new ASG using the <code>couchbase-cluster</code> module with the <code>ami_id</code> set to the new AMI, but all\nother parameters the same as the old cluster.</li>\n<li>Wait for all the nodes in the new ASG to join the cluster and catch up on replication.</li>\n<li>Remove each of the nodes from the old cluster\n(<a href=\"https://developer.couchbase.com/documentation/server/3.x/admin/Tasks/rebalance-remove-node.html\" class=\"preview__body--description--blue\" target=\"_blank\">docs</a>).</li>\n<li>Remove the old ASG by removing that <code>couchbase-cluster</code> module from your code.</li>\n</ol>\n</li>\n</ol>\n<p>We may add a script in the future to automate this process (PRs are welcome!).</p>\n<h2 class=\"preview__body--subtitle\" id=\"security\">Security</h2>\n<p>Here are some of the main security considerations to keep in mind when using this module:</p>\n<ol>\n<li><a href=\"#encryption-in-transit\" class=\"preview__body--description--blue\">Encryption in transit</a></li>\n<li><a href=\"#encryption-at-rest\" class=\"preview__body--description--blue\">Encryption at rest</a></li>\n<li><a href=\"#dedicated-instances\" class=\"preview__body--description--blue\">Dedicated instances</a></li>\n<li><a href=\"#security-groups\" class=\"preview__body--description--blue\">Security groups</a></li>\n<li><a href=\"#ssh-access\" class=\"preview__body--description--blue\">SSH access</a></li>\n</ol>\n<h3 class=\"preview__body--subtitle\" id=\"encryption-in-transit\">Encryption in transit</h3>\n<p>Couchbase can encrypt all of its network traffic. For instructions on enabling network encryption, have a look at the\n<a href=\"https://developer.couchbase.com/documentation/server/current/security/security-comm-encryption.html\" class=\"preview__body--description--blue\" target=\"_blank\">encryption on the wire documentation</a>.</p>\n<h3 class=\"preview__body--subtitle\" id=\"encryption-at-rest\">Encryption at rest</h3>\n<p>The EC2 Instances in the cluster can store their data in one of two locations:</p>\n<ul>\n<li>\n<p>An EBS Volume, if you enable it with this module. Set the <code>ebs_volume_encrypted</code> parameter to <code>true</code> to enable\nencryption for the EBS volume.</p>\n</li>\n<li>\n<p>The root volume. To encrypt the root volume, you must encrypt your AMI. If you're creating the AMI using Packer\n(e.g. as shown in the <a href=\"/repos/v0.2.2/terraform-aws-couchbase/examples/couchbase-ami\" class=\"preview__body--description--blue\">couchbase-ami example</a>),\nyou need to set the <a href=\"https://www.packer.io/docs/builders/amazon-ebs.html#encrypt_boot\" class=\"preview__body--description--blue\" target=\"_blank\">encrypt_boot parameter</a> to\n<code>true</code>.</p>\n</li>\n</ul>\n<h3 class=\"preview__body--subtitle\" id=\"dedicated-instances\">Dedicated instances</h3>\n<p>If you wish to use dedicated instances, you can set the <code>tenancy</code> parameter to <code>"dedicated"</code> in this module.</p>\n<h3 class=\"preview__body--subtitle\" id=\"security-groups\">Security groups</h3>\n<p>This module attaches a security group to each EC2 Instance that allows inbound requests as follows:</p>\n<ul>\n<li><strong>SSH</strong>: For the SSH port (default: 22), you can use the <code>allowed_ssh_cidr_blocks</code> parameter to control the list of<br>\n<a href=\"https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing\" class=\"preview__body--description--blue\" target=\"_blank\">CIDR blocks</a> that will be allowed access. You can use\nthe <code>allowed_inbound_ssh_security_group_ids</code> parameter to control the list of source Security Groups that will be\nallowed access.</li>\n</ul>\n<p>The ID of the security group is exported as an output variable, which you can use with the\n<a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/couchbase-server-security-group-rules\" class=\"preview__body--description--blue\">couchbase-server-security-group-rules</a> and\n<a href=\"/repos/v0.2.2/terraform-aws-couchbase/modules/sync-gateway-security-group-rules\" class=\"preview__body--description--blue\">sync-gateway-security-group-rules</a>\nmodules to open up all the ports necessary for Couchbase and Sync Gateway.</p>\n<h3 class=\"preview__body--subtitle\" id=\"ssh-access\">SSH access</h3>\n<p>You can associate an <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html\" class=\"preview__body--description--blue\" target=\"_blank\">EC2 Key Pair</a> with each\nof the EC2 Instances in this cluster by specifying the Key Pair's name in the <code>ssh_key_name</code> variable. If you don't\nwant to associate a Key Pair with these servers, set <code>ssh_key_name</code> to an empty string.</p>\n","repoName":"terraform-aws-couchbase","repoRef":"v0.2.2","serviceDescriptor":{"serviceName":"Couchbase","serviceRepoName":"terraform-aws-couchbase","serviceRepoOrg":"gruntwork-io","cloudProviders":["aws"],"description":"Deploy a Couchbase cluster. Supports automatic bootstrapping, Sync Gateway, Web Console UI, cross-region replication, and auto healing.","imageUrl":"couchbase.png","licenseType":"open-source","technologies":["Terraform","Bash"],"compliance":[],"tags":[""]},"serviceCategoryName":"NoSQL","fileName":"README.md","filePath":"/modules/couchbase-cluster","title":"Repo Browser: Couchbase","description":"Browse the repos in the Gruntwork Infrastructure as Code Library."}