-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7741533
Showing
6 changed files
with
321 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
*.tfstate | ||
*.tfstate.backup | ||
*.tfvars |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Dead simple Terraform configuration for creating RabbitMQ cluster on AWS. | ||
|
||
|
||
## Requirements | ||
1. AWS account | ||
2. Route53 Zone (internal preferably) | ||
|
||
## How to use it ? | ||
|
||
Create `terraform.tfvars` file with content: | ||
``` | ||
region = "<REGION-HERE>" | ||
access_key = "<YOUR-KEY-HERE>" | ||
secret_key = "<YOUR-SECRET-HERE>" | ||
ssh_key_name = "<SSH-KEY-NAME>" | ||
vpc_id = "<VPC-ID>" | ||
subnet_ids = ["<SUBNET-1-ID>", "<SUBNET-2-ID>"] | ||
route53_zone_id = "<ROUTE53-ZONE-ID>" | ||
``` | ||
|
||
then run `terraform plan` and `terraform apply` | ||
|
||
## What it does ? | ||
|
||
1. Creates `${var.count}` nodes in `${var.subnet_ids}` subnets | ||
1. Adds Route53 A record for each node in `${var.route53_zone_id}` zone (like `rabbit-0.local`, `rabbit-1.local`, ...) | ||
1. Makes sure they can talk to each other and create cluster | ||
1. Configures `/` vhost queues in High Available (Mirrored) mode with automatic synchronization (`"ha-mode":"all", "ha-sync-mode":"automatic"`) | ||
1. Creates ELB to load balance nodes and Route53 record for it (like `rabbit.local`) | ||
|
||
|
||
<p align="center"> | ||
<img src=".github/chart.png" width="600"> | ||
</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#cloud-config | ||
hostname: ${hostname} | ||
|
||
write_files: | ||
- path: /root/docker-compose.yaml | ||
content: | | ||
version: "2" | ||
services: | ||
node: | ||
hostname: ${hostname} | ||
environment: | ||
- RABBITMQ_ERLANG_COOKIE=${secret_cookie} | ||
- RABBITMQ_USE_LONGNAME=true | ||
- RABBITMQ_NODENAME=rabbit@${hostname} | ||
image: "rabbitmq:3-management" | ||
ports: | ||
- '4369:4369' | ||
- "5672:5672" | ||
- "15672:15672" | ||
- '25672:25672' | ||
volumes: | ||
- ./data:/var/lib/rabbitmq | ||
- ./conf:/etc/rabbitmq | ||
- path: /root/conf/enabled_plugins | ||
content: | | ||
[rabbitmq_management]. | ||
- path: /root/conf/rabbitmq.config | ||
content: | | ||
[ { rabbit, [ | ||
{cluster_nodes, {[${nodes}], disc}}, | ||
{ loopback_users, [ ] } ] } | ||
]. | ||
runcmd: | ||
# wait until DNS records are created | ||
- sleep 10 | ||
- yum update -y | ||
- yum install -y docker | ||
- service docker start | ||
- chkconfig docker on | ||
- usermod -a -G docker ec2-user | ||
- pip install docker-compose | ||
- /usr/local/bin/docker-compose -f /root/docker-compose.yaml up -d | ||
- sleep 2 | ||
- /usr/local/bin/docker-compose -f /root/docker-compose.yaml exec -T node rabbitmqctl -n rabbit@${hostname} add_user admin ${admin_password} || true | ||
- /usr/local/bin/docker-compose -f /root/docker-compose.yaml exec -T node rabbitmqctl -n rabbit@${hostname} set_user_tags admin administrator || true | ||
- /usr/local/bin/docker-compose -f /root/docker-compose.yaml exec -T node rabbitmqctl -n rabbit@${hostname} add_user rabbit ${rabbit_password} || true | ||
|
||
- /usr/local/bin/docker-compose -f /root/docker-compose.yaml exec -T node rabbitmqctl -n rabbit@${hostname} add_vhost / || true | ||
- /usr/local/bin/docker-compose -f /root/docker-compose.yaml exec -T node rabbitmqctl -n rabbit@${hostname} set_policy -p / ha-all_ttl_expiry "^" '{"ha-mode":"exactly", "ha-params":${majority}, "ha-sync-mode":"automatic", "message-ttl":${message_timeout}, "expires":${message_timeout}}' || true | ||
|
||
- /usr/local/bin/docker-compose -f /root/docker-compose.yaml exec -T node rabbitmqctl -n rabbit@${hostname} set_permissions -p / admin ".*" ".*" ".*" || true | ||
- /usr/local/bin/docker-compose -f /root/docker-compose.yaml exec -T node rabbitmqctl -n rabbit@${hostname} set_permissions -p / rabbit ".*" ".*" ".*" || true | ||
|
||
- /usr/local/bin/docker-compose -f /root/docker-compose.yaml exec -T node rabbitmqctl -n rabbit@${hostname} delete_user guest || true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
provider "aws" { | ||
region = "${var.region}" | ||
access_key = "${var.access_key}" | ||
secret_key = "${var.secret_key}" | ||
} | ||
|
||
data "aws_vpc" "vpc" { | ||
id = "${var.vpc_id}" | ||
} | ||
|
||
data "aws_route53_zone" "selected" { | ||
zone_id = "${var.route53_zone_id}" | ||
} | ||
|
||
data "aws_ami_ids" "ami" { | ||
owners = ["amazon"] | ||
|
||
filter { | ||
name = "name" | ||
values = ["amzn-ami-hvm-2017*-gp2"] | ||
} | ||
} | ||
|
||
data "null_data_source" "nodes" { | ||
count = "${var.count}" | ||
inputs = { | ||
name = "rabbit-${count.index}" | ||
domain = "rabbit-${count.index}.${substr(data.aws_route53_zone.selected.name, 0, length(data.aws_route53_zone.selected.name) - 1)}" | ||
node_name = "rabbit@rabbit-${count.index}.${substr(data.aws_route53_zone.selected.name, 0, length(data.aws_route53_zone.selected.name) - 1)}" | ||
} | ||
} | ||
|
||
resource "aws_security_group" "rabbitmq_elb" { | ||
name = "rabbitmq_elb" | ||
vpc_id = "${var.vpc_id}" | ||
description = "Security Group for the rabbitmq elb" | ||
|
||
ingress { | ||
protocol = "tcp" | ||
from_port = 5672 | ||
to_port = 5672 | ||
security_groups = ["${var.security_group_ids}"] | ||
} | ||
|
||
ingress { | ||
protocol = "tcp" | ||
from_port = 80 | ||
to_port = 80 | ||
security_groups = ["${var.security_group_ids}"] | ||
} | ||
|
||
egress { | ||
protocol = "-1" | ||
from_port = 0 | ||
to_port = 0 | ||
cidr_blocks = [ | ||
"0.0.0.0/0" | ||
] | ||
} | ||
|
||
tags { | ||
Name = "rabbitmq elb" | ||
} | ||
} | ||
|
||
resource "aws_security_group" "rabbitmq_nodes" { | ||
name = "rabbitmq-nodes" | ||
vpc_id = "${var.vpc_id}" | ||
description = "Security Group for the rabbitmq nodes" | ||
|
||
ingress { | ||
protocol = -1 | ||
from_port = 0 | ||
to_port = 0 | ||
self = true | ||
} | ||
|
||
ingress { | ||
protocol = "tcp" | ||
from_port = 5672 | ||
to_port = 5672 | ||
security_groups = ["${aws_security_group.rabbitmq_elb.id}"] | ||
} | ||
|
||
ingress { | ||
protocol = "tcp" | ||
from_port = 15672 | ||
to_port = 15672 | ||
security_groups = ["${aws_security_group.rabbitmq_elb.id}"] | ||
} | ||
|
||
ingress { | ||
protocol = "tcp" | ||
from_port = 22 | ||
to_port = 22 | ||
security_groups = ["${var.security_group_ids}"] | ||
} | ||
|
||
egress { | ||
protocol = "-1" | ||
from_port = 0 | ||
to_port = 0 | ||
cidr_blocks = [ | ||
"0.0.0.0/0" | ||
] | ||
} | ||
|
||
tags { | ||
Name = "rabbitmq nodes" | ||
} | ||
} | ||
|
||
data "template_file" "cloud-init" { | ||
count = "${var.count}" | ||
template = "${file("${path.module}/cloud-init.yaml")}" | ||
|
||
vars { | ||
majority = "${floor(var.count / 2) + 1}" | ||
nodes = "${join(", ", formatlist("'%s'", data.null_data_source.nodes.*.inputs.node_name))}" | ||
hostname = "${element(data.null_data_source.nodes.*.inputs.domain, count.index)}" | ||
secret_cookie = "${var.rabbitmq_secret_cookie}" | ||
admin_password = "${var.admin_password}" | ||
rabbit_password = "${var.rabbit_password}" | ||
message_timeout = "${3 * 24 * 60 * 60 * 1000}" # 3 days | ||
} | ||
} | ||
|
||
resource "aws_instance" "rabbitmq" { | ||
count = "${var.count}" | ||
subnet_id = "${element(var.subnet_ids, count.index)}" | ||
ami = "${data.aws_ami_ids.ami.ids[0]}" | ||
instance_type = "${var.instance_type}" | ||
key_name = "${var.ssh_key_name}" | ||
vpc_security_group_ids = ["${aws_security_group.rabbitmq_nodes.id}"] | ||
associate_public_ip_address = false | ||
user_data = "${element(data.template_file.cloud-init.*.rendered, count.index)}" | ||
tags { | ||
Name = "rabbitmq-${count.index}" | ||
} | ||
} | ||
|
||
resource "aws_route53_record" "rabbit" { | ||
count = "${var.count}" | ||
zone_id = "${var.route53_zone_id}" | ||
name = "rabbit-${count.index}" | ||
type = "A" | ||
ttl = "300" | ||
records = ["${element(aws_instance.rabbitmq.*.private_ip, count.index)}"] | ||
} | ||
|
||
resource "aws_elb" "elb" { | ||
name = "rabbit-elb" | ||
|
||
listener { | ||
instance_port = 5672 | ||
instance_protocol = "tcp" | ||
lb_port = 5672 | ||
lb_protocol = "tcp" | ||
} | ||
|
||
listener { | ||
instance_port = 15672 | ||
instance_protocol = "http" | ||
lb_port = 80 | ||
lb_protocol = "http" | ||
} | ||
|
||
health_check { | ||
healthy_threshold = 2 | ||
unhealthy_threshold = 2 | ||
timeout = 3 | ||
target = "TCP:5672" | ||
interval = 30 | ||
} | ||
|
||
instances = ["${aws_instance.rabbitmq.*.id}"] | ||
subnets = ["${var.subnet_ids}"] | ||
idle_timeout = 3600 | ||
internal = true | ||
security_groups = ["${aws_security_group.rabbitmq_elb.id}"] | ||
|
||
tags { | ||
Name = "rabbitmq" | ||
} | ||
} | ||
|
||
resource "aws_route53_record" "elb" { | ||
zone_id = "${var.route53_zone_id}" | ||
name = "rabbit" | ||
type = "CNAME" | ||
ttl = "300" | ||
records = ["${aws_elb.elb.dns_name}"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
variable "access_key" {} | ||
variable "secret_key" {} | ||
variable "region" {} | ||
variable "vpc_id" {} | ||
variable "ssh_key_name" {} | ||
variable "count" { | ||
description = "Number of RabbitMQ nodes" | ||
default = 2 | ||
} | ||
variable "subnet_ids" { | ||
description = "Subnets for RabbitMQ nodes" | ||
type = "list" | ||
} | ||
variable "security_group_ids" { | ||
description = "Security groups which should have access to ELB (amqp + http ports) and nodes (ssh port)" | ||
type = "list" | ||
} | ||
variable "route53_zone_id" { | ||
description = "Route53 internal zone" | ||
} | ||
variable "admin_password" { | ||
description = "Password for 'admin' user" | ||
default = "password" | ||
} | ||
variable "rabbit_password" { | ||
description = "Password for 'rabbit' user" | ||
default = "password" | ||
} | ||
variable "rabbitmq_secret_cookie" { | ||
default = "supersecretcookie" | ||
} | ||
variable "instance_type" { | ||
default = "t2.small" | ||
} |