main.tf 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. /*
  2. * 1) Create Public Subnet with a /24 size (HA: create one in at least 3 different availability zones)
  3. * 2) Create a NAT Gateway in one of the Public Subnets
  4. * 3) Create a Route with the Internet Gateway as default route, associate it with the Public Subnet(s)
  5. * 4) Create a Route with the NAT Gateway as default route, *that should be associated to all Private Subnets when they are created*
  6. * 5) Create a Security Group for Bastion Hosts that accepts SSH from anywhere
  7. * 6) Create a Security Group for ELBs that accepts HTTP and HTTPS from anywhere
  8. * 7) Create a Bastion Host with bastion host SG associated to ti, install NTP and Userify on it
  9. */
  10. #-------------------
  11. # VARIABLES
  12. #-------------------
  13. variable "stack_name" {
  14. default = "Name for this stack like customer-Name or project-name"
  15. }
  16. variable "aws_region" {}
  17. variable "vpc_id" {}
  18. // Variables for providers used in this module
  19. variable "aws_access_key" {}
  20. variable "aws_secret_key" {}
  21. // Deployer SSH Pub SSH keys
  22. variable "public_key_path" {}
  23. variable "public_subnets" {
  24. description = "A list of public subnets inside the VPC."
  25. default = ["10.0.10.0/24"]
  26. }
  27. variable "private_subnets" {
  28. description = "A list of private subnets inside the VPC."
  29. default = ["10.0.11.0/24"]
  30. }
  31. variable "private_db_subnets" {
  32. description = "A list of private subnets inside the VPC for the RDS Postgres"
  33. default = ["10.0.100.0/24","10.0.101.0/24"]
  34. }
  35. variable "azs" {
  36. description = "A list of Availability zones in the region"
  37. default = ["a","b","c"]
  38. }
  39. variable "enable_nat_gateway" {
  40. description = "should be true if you want to provision NAT Gateways for each of your private networks"
  41. default = false
  42. }
  43. variable "private_propagating_vgws" {
  44. description = "A list of VGWs the private route table should propagate."
  45. default = []
  46. }
  47. variable "public_propagating_vgws" {
  48. description = "A list of VGWs the public route table should propagate."
  49. default = []
  50. }
  51. variable "ssl_certificate_id" {
  52. description = "SSL Certificate ID on AWS for nuxeocloud.com"
  53. default = "ASCAI627UM4G2NSLWDTMM"
  54. }
  55. // RDS Instance Variables
  56. variable "rds_instance_name" {
  57. default = "nuxeo"
  58. }
  59. variable "rds_is_multi_az" {
  60. default = "false"
  61. }
  62. variable "rds_storage_type" {
  63. default = "standard"
  64. }
  65. variable "rds_allocated_storage" {
  66. description = "The allocated storage in GBs"
  67. // You just give it the number, e.g. 10
  68. }
  69. variable "rds_engine_version" {
  70. // For valid engine versions, see:
  71. // See http://docs.aws.amazon.com/cli/latest/reference/rds/create-db-instance.html
  72. // --engine-version
  73. }
  74. variable "rds_instance_class" {
  75. default = "db.t2.micro"
  76. }
  77. variable "database_name" {
  78. description = "The name of the database to create"
  79. }
  80. variable "database_user" {}
  81. variable "database_password" {}
  82. variable "db_parameter_group" {
  83. default = "default.mysql5.6"
  84. }
  85. // RDS Subnet Group Variables
  86. #variable "subnet_az1" {}
  87. #variable "subnet_az2" {}
  88. #-------------
  89. # AWS Provider
  90. #-------------
  91. provider "aws" {
  92. access_key = "${var.aws_access_key}"
  93. secret_key = "${var.aws_secret_key}"
  94. region = "${var.aws_region}"
  95. }
  96. data "aws_availability_zones" "all" {}
  97. ///////////////////////////////////////////////////////////////////////
  98. // RESOURCES
  99. ///////////////////////////////////////////////////////////////////////
  100. #-------------
  101. # DNS Entry for Cloud Customer
  102. #-------------
  103. #resource "aws_route53_record" "dns" {
  104. # zone_id = "Z1EFT3O5K9NMCJ" // Zone ID for nuxeocloud.com
  105. # name = "${name}"
  106. # type = "CNAME"
  107. # ttl = "300"
  108. # weighted_routing_policy {
  109. # weight = 90
  110. # }
  111. # set_identifier = "${var.stack_name}"
  112. # records = ["${var.stack_name}.nuxeocloud.com"]
  113. #}
  114. #-------------
  115. # S3 Bucket
  116. #-------------
  117. resource "random_id" "customer" {
  118. byte_length = 8
  119. }
  120. resource "aws_s3_bucket" "bucket" {
  121. bucket = "nuxeo-${random_id.customer.hex}"
  122. acl = "private"
  123. tags {
  124. Name = "cloud-${random_id.customer.b64}"
  125. billing-category = "customers"
  126. billing-subcategory = "${var.stack_name}"
  127. role = "nuxeo.aws-s3"
  128. }
  129. }
  130. #-------------
  131. # CREATE SUBNETS
  132. #-------------
  133. resource "aws_subnet" "public" {
  134. vpc_id = "${var.vpc_id}"
  135. cidr_block = "${var.public_subnets[count.index]}"
  136. availability_zone = "${var.aws_region}${var.azs[count.index]}"
  137. count = "${length(var.public_subnets)}"
  138. tags {
  139. Name = "${var.stack_name}-subnet-public-${var.aws_region}${element(var.azs, count.index)}"
  140. billing-category = "customers"
  141. billing-subcategory = "${var.stack_name}"
  142. role = "nuxeo.aws-subnet"
  143. }
  144. map_public_ip_on_launch = "true"
  145. }
  146. resource "aws_subnet" "private" {
  147. vpc_id = "${var.vpc_id}"
  148. cidr_block = "${var.private_subnets[count.index]}"
  149. availability_zone = "${var.aws_region}${var.azs[count.index]}"
  150. count = "${length(var.private_subnets)}"
  151. tags {
  152. Name = "${var.stack_name}-subnet-private-${var.aws_region}${element(var.azs, count.index)}"
  153. billing-category = "customers"
  154. billing-subcategory = "${var.stack_name}"
  155. role = "nuxeo.aws-subnet"
  156. }
  157. }
  158. resource "aws_subnet" "db_private" {
  159. vpc_id = "${var.vpc_id}"
  160. cidr_block = "${var.private_db_subnets[count.index]}"
  161. availability_zone = "${var.aws_region}${var.azs[count.index]}"
  162. count = "${length(var.private_db_subnets)}"
  163. tags {
  164. Name = "${var.stack_name}-db-subnet-private-${var.aws_region}${element(var.azs, count.index)}"
  165. billing-category = "customers"
  166. billing-subcategory = "${var.stack_name}"
  167. role = "nuxeo.aws-subnet"
  168. }
  169. }
  170. #-------------
  171. # CREATE NAT GATEWAY
  172. #-------------
  173. # > Create EIP to associate to NAT GW
  174. resource "aws_eip" "nateip" {
  175. vpc = true
  176. count = "${length(var.private_subnets) * lookup(map(var.enable_nat_gateway, 1), "true", 0)}"
  177. tags {
  178. Name = "${var.vpc_id}-nat-eip"
  179. billing-category = "customers"
  180. role = "nuxeo.aws-nat_eip"
  181. }
  182. }
  183. # > Create NAT GW
  184. resource "aws_nat_gateway" "natgw" {
  185. allocation_id = "${element(aws_eip.nateip.*.id, count.index)}"
  186. subnet_id = "${element(aws_subnet.public.*.id, count.index)}"
  187. count = "${length(var.private_subnets) * lookup(map(var.enable_nat_gateway, 1), "true", 0)}"
  188. tags {
  189. Name = "${var.stack_name}-natgw"
  190. billing-category = "customers"
  191. billing-subcategory = "${var.stack_name}"
  192. role = "nuxeo.aws-natgw"
  193. }
  194. depends_on = ["aws_internet_gateway.igw"]
  195. }
  196. # > Create IGW
  197. resource "aws_internet_gateway" "igw" {
  198. vpc_id = "${var.vpc_id}"
  199. }
  200. #-------------
  201. # CREATE ROUTES
  202. #-------------
  203. # > Route Tables
  204. # >> Route Table for Public Subnets
  205. resource "aws_route_table" "public" {
  206. vpc_id = "${var.vpc_id}"
  207. propagating_vgws = ["${var.public_propagating_vgws}"]
  208. tags {
  209. Name = "${var.stack_name}-rt-public"
  210. billing-category = "customers"
  211. billing-subcategory = "${var.stack_name}"
  212. role = "nuxeo.aws-rtb"
  213. }
  214. }
  215. # >> Route Table for Private Subnets
  216. resource "aws_route_table" "private" {
  217. vpc_id = "${var.vpc_id}"
  218. propagating_vgws = ["${var.private_propagating_vgws}"]
  219. count = "${length(var.private_subnets)}"
  220. tags {
  221. Name = "${var.stack_name}-rt-private-${element(var.azs, count.index)}"
  222. billing-category = "customers"
  223. billing-subcategory = "${var.stack_name}"
  224. role = "nuxeo.aws-rtb"
  225. }
  226. }
  227. # > Associations
  228. # >> for Private Subnets
  229. resource "aws_route_table_association" "private" {
  230. count = "${length(var.private_subnets)}"
  231. subnet_id = "${element(aws_subnet.private.*.id, count.index)}"
  232. route_table_id = "${element(aws_route_table.private.*.id, count.index)}"
  233. }
  234. # >> for Public Subnets
  235. resource "aws_route_table_association" "public" {
  236. count = "${length(var.public_subnets)}"
  237. subnet_id = "${element(aws_subnet.public.*.id, count.index)}"
  238. route_table_id = "${aws_route_table.public.id}"
  239. }
  240. # > Routes
  241. # >> Route for IGW
  242. resource "aws_route" "public_internet_gateway" {
  243. route_table_id = "${aws_route_table.public.id}"
  244. destination_cidr_block = "0.0.0.0/0"
  245. gateway_id = "${aws_internet_gateway.igw.id}"
  246. }
  247. # Route for NAT GW
  248. resource "aws_route" "private_nat_gateway" {
  249. route_table_id = "${element(aws_route_table.private.*.id, count.index)}"
  250. destination_cidr_block = "0.0.0.0/0"
  251. nat_gateway_id = "${element(aws_nat_gateway.natgw.*.id, count.index)}"
  252. count = "${length(var.private_subnets) * lookup(map(var.enable_nat_gateway, 1), "true", 0)}"
  253. }
  254. #-------------------
  255. # Security Groups
  256. #-------------------
  257. resource "aws_security_group" "sg_external_elb" {
  258. name = "${format("%s-sg-external-elb", var.stack_name)}"
  259. vpc_id = "${var.vpc_id}"
  260. description = "Allows external ELB traffic"
  261. ingress {
  262. from_port = 80
  263. to_port = 80
  264. protocol = "tcp"
  265. cidr_blocks = ["0.0.0.0/0"]
  266. }
  267. ingress {
  268. from_port = 443
  269. to_port = 443
  270. protocol = "tcp"
  271. cidr_blocks = ["0.0.0.0/0"]
  272. }
  273. egress {
  274. from_port = 0
  275. to_port = 0
  276. protocol = -1
  277. cidr_blocks = ["0.0.0.0/0"]
  278. }
  279. lifecycle {
  280. create_before_destroy = true
  281. }
  282. tags {
  283. Name = "${format("%s external elb", var.stack_name)}"
  284. billing-category = "customers"
  285. billing-subcategory = "${var.stack_name}"
  286. role = "nuxeo.aws-sg.external"
  287. }
  288. }
  289. resource "aws_security_group" "sg_internal" {
  290. name = "${format("%s-sg-internal-elb", var.stack_name)}"
  291. vpc_id = "${var.vpc_id}"
  292. description = "Allows external ELB traffic"
  293. ingress {
  294. from_port = 80
  295. to_port = 80
  296. protocol = "tcp"
  297. security_groups = ["${aws_security_group.sg_external_elb.id}"]
  298. }
  299. ingress {
  300. from_port = 8080
  301. to_port = 8080
  302. protocol = "tcp"
  303. security_groups = ["${aws_security_group.sg_external_elb.id}"]
  304. }
  305. ingress {
  306. from_port = 22
  307. to_port = 22
  308. protocol = "tcp"
  309. # TOFIX to replace by bastion host
  310. cidr_blocks = ["0.0.0.0/0"]
  311. }
  312. egress {
  313. from_port = 0
  314. to_port = 0
  315. protocol = -1
  316. cidr_blocks = ["0.0.0.0/0"]
  317. }
  318. lifecycle {
  319. create_before_destroy = true
  320. }
  321. tags {
  322. Name = "${format("%s internal elb", var.stack_name)}"
  323. billing-category = "customers"
  324. billing-subcategory = "${var.stack_name}"
  325. role = "nuxeo.aws-sg.internal"
  326. }
  327. }
  328. resource "aws_security_group" "external_ssh" {
  329. name = "${format("%s-sg-external-ssh", var.stack_name)}"
  330. description = "Allows ssh from the world"
  331. vpc_id = "${var.vpc_id}"
  332. ingress {
  333. from_port = 22
  334. to_port = 22
  335. protocol = "tcp"
  336. cidr_blocks = ["0.0.0.0/0"]
  337. }
  338. egress {
  339. from_port = 0
  340. to_port = 0
  341. protocol = "-1"
  342. cidr_blocks = ["0.0.0.0/0"]
  343. }
  344. lifecycle {
  345. create_before_destroy = true
  346. }
  347. tags {
  348. Name = "${format("%s external ssh", var.stack_name)}"
  349. billing-category = "customers"
  350. billing-subcategory = "${var.stack_name}"
  351. role= "nuxeo.aws-sg-ssh"
  352. }
  353. tags {
  354. }
  355. }
  356. #-------------------
  357. # ELB
  358. #-------------------
  359. resource "aws_elb" "elb" {
  360. name = "elb-${var.stack_name}"
  361. internal = true
  362. cross_zone_load_balancing = true
  363. subnets = ["${aws_subnet.public.id}"]
  364. security_groups = ["${aws_security_group.sg_external_elb.id}"]
  365. idle_timeout = 30
  366. connection_draining = true
  367. connection_draining_timeout = 15
  368. listener {
  369. lb_port = 80
  370. lb_protocol = "http"
  371. instance_port = 80
  372. instance_protocol = "http"
  373. }
  374. # listener {
  375. # lb_port = 443
  376. # lb_protocol = "https"
  377. # instance_port = 80
  378. # instance_protocol = "http"
  379. # #ssl_certificate_id = "${var.ssl_certificate_id}"
  380. # }
  381. health_check {
  382. healthy_threshold = 2
  383. unhealthy_threshold = 2
  384. timeout = 5
  385. target = "TCP:8080"
  386. interval = 30
  387. }
  388. # access_logs {
  389. # bucket = "${var.log_bucket}"
  390. # }
  391. tags {
  392. Name = "elb-${var.stack_name}"
  393. billing-category = "customers"
  394. billing-subcategory = "${var.stack_name}"
  395. role= "nuxeo.elb"
  396. }
  397. tags {
  398. }
  399. }
  400. #-------------------
  401. # RDS Postgresql Database
  402. #-------------------
  403. resource "aws_db_instance" "main_rds_instance" {
  404. identifier = "db-${var.stack_name}"
  405. allocated_storage = "${var.rds_allocated_storage}"
  406. engine = "postgres"
  407. engine_version = "${var.rds_engine_version}"
  408. instance_class = "${var.rds_instance_class}"
  409. name = "${var.stack_name}"
  410. username = "${var.database_user}"
  411. password = "${var.database_password}"
  412. // Because we're assuming a VPC, we use this option, but only one SG id
  413. vpc_security_group_ids = ["${aws_security_group.sg_internal.id}"]
  414. // We're creating a subnet group in the module and passing in the name
  415. db_subnet_group_name = "${var.stack_name}-db-subnet-group"
  416. parameter_group_name = "default.postgres9.4"
  417. // We want the multi-az setting to be toggleable, but off by default
  418. multi_az = "${var.rds_is_multi_az}"
  419. storage_type = "${var.rds_storage_type}"
  420. tags {
  421. Name = "${var.stack_name} - Nuxeo Postgres Database"
  422. billing-category = "customers"
  423. billing-subcategory = "${var.stack_name}"
  424. role= "nuxeo.db"
  425. }
  426. }
  427. resource "aws_db_subnet_group" "main_db_subnet_group" {
  428. name = "${var.stack_name}-db-subnet-group"
  429. description = "RDS private subnet group"
  430. subnet_ids = ["${aws_subnet.db_private.0.id}", "${aws_subnet.db_private.1.id}"]
  431. }
  432. #-------------------
  433. # Elastic Cache Redis
  434. #-------------------
  435. resource "aws_elasticache_cluster" "redis" {
  436. cluster_id = "${var.stack_name}"
  437. engine = "redis"
  438. engine_version = "3.2.4"
  439. node_type = "cache.t2.micro"
  440. port = "6379"
  441. num_cache_nodes = 1
  442. parameter_group_name = "default.redis3.2"
  443. subnet_group_name = "${aws_elasticache_subnet_group.redis.name}"
  444. security_group_ids = ["${aws_security_group.sg_internal.id}"]
  445. tags {
  446. Name = "Redis ElasticCache"
  447. billing-category = "customers"
  448. billing-subcategory = "${var.stack_name}"
  449. role= "nuxeo.redis"
  450. }
  451. }
  452. resource "aws_elasticache_subnet_group" "redis" {
  453. name = "${var.stack_name}-redis-subnet-group"
  454. description = "Private subnets for the ElastiCache instances"
  455. subnet_ids = ["${aws_subnet.db_private.0.id}", "${aws_subnet.db_private.1.id}"]
  456. }
  457. #-------------------
  458. # Create Nuxeo Ubuntu Instance
  459. #-------------------
  460. # Create a new instance of the latest Ubuntu on an
  461. # t2.micro node with an AWS Tag naming it "Nuxeo"
  462. data "aws_ami" "ubuntu" {
  463. most_recent = true
  464. filter {
  465. name = "name"
  466. values = ["ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-*"]
  467. }
  468. filter {
  469. name = "virtualization-type"
  470. values = ["hvm"]
  471. }
  472. owners = ["099720109477"] # Canonical
  473. }
  474. resource "aws_instance" "nuxeo" {
  475. ami = "${data.aws_ami.ubuntu.id}"
  476. instance_type = "t2.micro"
  477. key_name = "${aws_key_pair.deployer.id}"
  478. subnet_id = "${aws_subnet.private.id}"
  479. tags {
  480. Name = "Nuxeo"
  481. billing-category = "customers"
  482. billing-subcategory = "${var.stack_name}"
  483. role= "nuxeo.instance"
  484. }
  485. }
  486. #---------------------
  487. # Deployer SSH keys
  488. #--------------------
  489. resource "aws_key_pair" "deployer" {
  490. key_name = "deployer-key"
  491. public_key = "${file(var.public_key_path)}"
  492. }