diff --git a/terraform/firewall.tf b/terraform/firewall.tf new file mode 100644 index 0000000..33c3b06 --- /dev/null +++ b/terraform/firewall.tf @@ -0,0 +1,63 @@ +resource "linode_firewall_device" "site-firewall-vms" { + count = length(var.app_servers) + firewall_id = linode_firewall.site-firewall.id + entity_id = "${element(linode_instance.site-vm.*.id, count.index)}" +} + +resource "linode_firewall" "site-firewall" { + label = "site-firewall" + tags = [ + "${var.site}-firewall" + ] + + inbound_policy = "DROP" + outbound_policy = "ACCEPT" + + inbound { + label = "inbound-http" + protocol = "TCP" + action = "ACCEPT" + ports = "80" + ipv4 = ["0.0.0.0/0"] + } + + outbound { + label = "outbound-http" + protocol = "TCP" + action = "ACCEPT" + ports = "80" + ipv4 = ["0.0.0.0/0"] + } + + inbound { + label = "inbound-https" + protocol = "TCP" + action = "ACCEPT" + ports = "443" + ipv4 = ["0.0.0.0/0"] + } + + outbound { + label = "outbound-https" + protocol = "TCP" + action = "ACCEPT" + ports = "443" + ipv4 = ["0.0.0.0/0"] + } + + inbound { + label = "inbound-ssh-22" + protocol = "TCP" + action = "ACCEPT" + ports = "22" + ipv4 = ["0.0.0.0/0"] + } + + inbound { + label = "inbound-ssh-8822" + protocol = "TCP" + action = "ACCEPT" + ports = "8822" + ipv4 = ["0.0.0.0/0"] + } +} diff --git a/terraform/node-balancer.tf b/terraform/node-balancer.tf new file mode 100644 index 0000000..29ea286 --- /dev/null +++ b/terraform/node-balancer.tf @@ -0,0 +1,55 @@ +resource "linode_nodebalancer" "site-nodebalancer" { + label = "site-nodebalancer" + region = var.region + tags = [ + "${var.site}-nodebalancer" + ] +} + +resource "linode_nodebalancer_config" "site-nodebalancer-config-http" { + nodebalancer_id = linode_nodebalancer.site-nodebalancer.id + port = 80 + protocol = "tcp" + check = "connection" + check_path = "/" + check_attempts = 3 + check_timeout = 25 + check_interval = 30 + stickiness = "none" + algorithm = "leastconn" +} + +resource "linode_nodebalancer_config" "site-nodebalancer-config-https" { + nodebalancer_id = linode_nodebalancer.site-nodebalancer.id + port = 443 + protocol = "tcp" + check = "connection" + check_path = "/" + check_attempts = 3 + check_timeout = 25 + check_interval = 30 + stickiness = "none" + algorithm = "leastconn" +} + +resource "linode_nodebalancer_node" "site-nodebalancer-nodes-http" { + count = length(var.app_servers) + nodebalancer_id = linode_nodebalancer.site-nodebalancer.id + config_id = linode_nodebalancer_config.site-nodebalancer-config-http.id + label = "app${count.index}" + address = "${element(linode_instance.site-vm.*.private_ip_address, count.index)}:80" + mode = "accept" +} + +resource "linode_nodebalancer_node" "site-nodebalancer-nodes-https" { + count = length(var.app_servers) + nodebalancer_id = linode_nodebalancer.site-nodebalancer.id + config_id = linode_nodebalancer_config.site-nodebalancer-config-https.id + label = "app${count.index}" + address = "${element(linode_instance.site-vm.*.private_ip_address, count.index)}:443" + mode = "accept" +} + +output "nodebalancer_ip_address" { + value = linode_nodebalancer.site-nodebalancer.ipv4 +} \ No newline at end of file diff --git a/terraform/provider.tf b/terraform/provider.tf new file mode 100644 index 0000000..e93a7e0 --- /dev/null +++ b/terraform/provider.tf @@ -0,0 +1,17 @@ +terraform { + required_providers { + linode = { + source = "linode/linode" + version = "1.25.2" + } + } +} + +provider "linode" { + token = var.token +} + +resource "linode_sshkey" "main_key" { + label = "ssh_key" + ssh_key = chomp(file(var.ssh_key)) +} \ No newline at end of file diff --git a/terraform/site-vm.tf b/terraform/site-vm.tf new file mode 100644 index 0000000..4abbd08 --- /dev/null +++ b/terraform/site-vm.tf @@ -0,0 +1,18 @@ +resource "linode_instance" "site-vm" { + count = length(var.app_servers) + label = "${var.site}-app${count.index}" + tags = [ + "${var.site}-app${count.index}" + ] + region = var.region + private_ip = true + type = var.app_servers[count.index].type + image = var.app_servers[count.index].image + authorized_keys = [ + linode_sshkey.main_key.ssh_key + ] +} + +output "linode_instance_ip_address" { + value = linode_instance.site-vm.*.ipv4 +} \ No newline at end of file diff --git a/terraform/site.auto.tfvars b/terraform/site.auto.tfvars new file mode 100644 index 0000000..cd0edfa --- /dev/null +++ b/terraform/site.auto.tfvars @@ -0,0 +1,18 @@ +site = "example.com" +region = "us-southeast" +environment = "production" +app_servers = [ + { + type = "g6-nanode-1" + image = "linode/ubuntu20.04" + }, + { + type = "g6-nanode-1" + image = "linode/ubuntu20.04" + } +] +bastion_server = { + type = "g6-nanode-1" + image = "linode/ubuntu20.04" +} +ssh_key = "~/.ssh/id_rsa.pub" \ No newline at end of file diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000..1b10b68 --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,39 @@ +variable "token" { + description = "API token of the Linode Account" + type = string +} +variable "site" { + description = "FQDN of the static site" + type = string +} + +variable "environment" { + description = "Environment of the infrastructure (staging/production/dev/etc..)" + type = string +} + +variable "region" { + description = "Region to host the infrastructure" + type = string +} + +variable "root_pass" { + description = "The root password for the bastion instance." + default = "default-root-password" + type = string + sensitive = true +} + +variable "ssh_key" { + description = "Filepath of id_rsa.pub for root access to VMs." +} + +variable "app_servers" { + description = "Details describing the vm instances for the app" + type = list +} + +variable "bastion_server" { + description = "Details describing the bastion instance." + type = map +} \ No newline at end of file