diff --git a/modules/azure_vm/README.md b/modules/azure_vm/README.md new file mode 100644 index 0000000..725e6b5 --- /dev/null +++ b/modules/azure_vm/README.md @@ -0,0 +1,134 @@ +# Azure VM Standalone Deployment + +## Requirements + +- VPC with desired subnets + +## Usage + +1. Directly use our module in your existing Terraform configuration and provide the required variables + - If you want to use an external Postgres instance (Flexible Server), set external_psql to true. This is recommended for production deployments. + +``` +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.74" + } + } +} + +provider "azurerm" { + features {} +} + + +module "retool" { + source = "git@github.com:tryretool/retool-terraform.git//modules/azure_vm" + external_psql = "true" | "false" + psql_password = "" + resource_group_name = "" + subnet_name = "" + version_number = "" + virtual_network_name = "" +} + +output "vm_public_ip" { + value = module.retool.vm_public_ip + description = "Public IP of VM Instance" +} +``` +2. Copy `vm_script.sh` to your local Terraform directory. + +3. Run `terraform plan` to confirm that the changes look good + +4. Run `terraform apply` to apply the configuration changes + +5. After a few minutes, SSH into your newly created EC2 instance using the Key Pair passed into `ssh_key_path`, defaults to `~/.ssh/id_rsa.pub` + +6. Verify that the GitHub repository exists + +``` +sudo su - +cd /retool/retool-onpremise +``` + +7. Verify that the Dockerfile contains the correct Retool version number + +``` +# you should see the X.Y.Z version number specified +vim Dockerfile +``` + +8. Verify that all of the Docker containers are up and running. If one of them is not running or restarting, try re-creating the containers with (`docker-compose up -d`) + +``` +docker-ps +``` + +9. Modify your environment variables in `docker.env`. If you have an external RDS database (strongly recommended), replace the `POSTGRES_` environment variables with the new ones. + +- If testing out your instance for the first time without SSL/HTTPS, you should uncomment `# COOKIE_INSECURE = true` +- Replace your `LICENSE_KEY` with your provided Retool license key +- If using Postgres Flexible server, add `POSTGRES_SSL_ENABLED=true` + +10. Add any additional configuration needed to the `docker.env` file. You can refer to our documentation for [all additional environment variables](https://docs.retool.com/docs/environment-variables). + +11. Access your Retool instance on the public IP that is given via the resource creation outputs. If no SSL certificate has been configured you need to access the instance on port 3000 (append :3000 to the end of the URL) and via http. + +### Security Rules + +You can configure the security group ingress and egress rules using input variables: + +For example, to create a Retool instance accessible from anywhere, you can use the following value for `security_rules` which enables inbound traffic on ports (`30`, `443`, `22`, and `3000`) and all outbound traffic. Note that this is also the default behavior of this module. + +``` + security_rules = [ + { + name = "GlobalHTTP" + priority = 300 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "80" + source_address_prefix = "*" + destination_address_prefix = "*" + }, + { + name = "GlobalHTTPS" + priority = 310 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "443" + source_address_prefix = "*" + destination_address_prefix = "*" + }, + { + name = "SSH" + priority = 320 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "22" + source_address_prefix = "*" + destination_address_prefix = "*" + }, + { + name = "ApplicationPort" + priority = 330 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "3000" + source_address_prefix = "*" + destination_address_prefix = "*" + } + ] +``` + diff --git a/modules/azure_vm/main.tf b/modules/azure_vm/main.tf new file mode 100644 index 0000000..bbaf594 --- /dev/null +++ b/modules/azure_vm/main.tf @@ -0,0 +1,193 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.74" + } + } +} + +locals { + flat_security_rules = { + for rule in var.security_rules : + rule.name => rule + } +} + +data "azurerm_resource_group" "selected" { + name = var.resource_group_name +} + +data "azurerm_virtual_network" "selected" { + name = var.virtual_network_name + resource_group_name = data.azurerm_resource_group.selected.name +} + +data "azurerm_subnet" "selected" { + name = var.subnet_name + resource_group_name = data.azurerm_resource_group.selected.name + virtual_network_name = data.azurerm_virtual_network.selected.name +} + +resource "azurerm_public_ip" "this" { + name = "retool_public_ip" + resource_group_name = data.azurerm_resource_group.selected.name + location = data.azurerm_resource_group.selected.location + allocation_method = "Static" + lifecycle { + create_before_destroy = true + } +} + +resource "azurerm_network_interface" "this" { + name = "retoolni" + location = data.azurerm_resource_group.selected.location + resource_group_name = data.azurerm_resource_group.selected.name + + ip_configuration { + name = "retool-ni-config" + subnet_id = data.azurerm_subnet.selected.id + private_ip_address_allocation = "Dynamic" + public_ip_address_id = azurerm_public_ip.this.id + } +} + +resource "azurerm_network_security_group" "this" { + name = "retool-sg" + location = data.azurerm_resource_group.selected.location + resource_group_name = data.azurerm_resource_group.selected.name +} + +resource "azurerm_network_security_rule" "this" { + for_each = local.flat_security_rules + name = each.value.name + priority = each.value.priority + direction = each.value.direction + access = each.value.access + protocol = each.value.protocol + source_port_range = each.value.source_port_range + destination_port_range = each.value.destination_port_range + source_address_prefix = each.value.source_address_prefix + destination_address_prefix = each.value.destination_address_prefix + resource_group_name = data.azurerm_resource_group.selected.name + network_security_group_name = azurerm_network_security_group.this.name + + +} + +resource "azurerm_network_interface_security_group_association" "this" { + network_interface_id = azurerm_network_interface.this.id + network_security_group_id = azurerm_network_security_group.this.id +} + +resource "azurerm_linux_virtual_machine" "this" { + name = "retool" + resource_group_name = data.azurerm_resource_group.selected.name + location = data.azurerm_resource_group.selected.location + size = var.instance_size + admin_username = "retooladmin" + network_interface_ids = [ + azurerm_network_interface.this.id, + ] + + admin_ssh_key { + username = "retooladmin" + public_key = file(var.ssh_key_path) + } + + os_disk { + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + disk_size_gb = "160" + } + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts-gen2" + version = "latest" + } +} + + +resource "azurerm_virtual_machine_extension" "this" { + name = "retool" + virtual_machine_id = azurerm_linux_virtual_machine.this.id + publisher = "Microsoft.Azure.Extensions" + type = "CustomScript" + type_handler_version = "2.0" + + settings = < Dockerfile +echo CMD ./docker_scripts/start_api.sh >> Dockerfile + +# Initialize Docker and Retool Installation +./install.sh + +# Run services +docker-compose up -d + +# exit code for success in terraform +exit 0 \ No newline at end of file