# Deploy A Sample Web Application on DigitalOcean Using Terraform This tutorial teaches you how to use Terraform to deploy [a sample web application](https://github.com/do-community/terraform-sample-digitalocean-architectures/tree/master/01-minimal-web-db-stack) to your DigitalOcean account. The architecture includes three Droplets attached to a database and a load balancer in a VPC network: ``` flowchart RL SSH[CLI icon SSH Traffic] HTTPS[load-balancers icon HTTPS Traffic] subgraph VPC["virtual-private-cloud icon VPC 192.168.22.0/24"] direction LR DB[( managed-db icon Database )] subgraph WEB["general-purpose-droplet icon Droplets (Web Servers)"] direction TB W1[standard-droplet icon Web Server] W2[standard-droplet icon Web Server] W3[standard-droplet icon Web Server] end Bastion[CLI icon Bastion Host] LB[load-balancers icon Load Balancer] Bastion --> LB LB --> W1 LB --> W2 LB --> W3 W1 --> DB W2 --> DB W3 --> DB end SSH --> Bastion HTTPS --> LB ``` At the end of this tutorial, you can visit a small website being hosted by your Droplets in your web browser. ## Prerequisites Before starting this tutorial, you need four things: - You need to create an [API token in your DigitalOcean account](https://docs.digitalocean.com/reference/api/create-personal-access-token/index.html.md). This allows Terraform to access the DigitalOcean API and programmatically deploy resources into your account. - You need to own a domain name and [have its DNS records hosted by DigitalOcean](https://docs.digitalocean.com/products/networking/dns/how-to/add-domains/index.html.md). The domain name allows you to access the newly deployed Droplets via a hostname. - You need to [have an SSH key](https://docs.digitalocean.com/products/droplets/how-to/add-ssh-keys/index.html.md) and [upload your public key to your DigitalOcean team](https://docs.digitalocean.com/platform/teams/how-to/upload-ssh-keys/index.html.md). This is the SSH key that Terraform applies to the Droplets being deployed. - You need to [install Terraform](https://docs.digitalocean.com/reference/terraform/getting-started/index.html.md#install-terraform) on the machine you are deploying from. Terraform is available for MacOS, Windows, Linux, and FreeBSD. **Note**: This tutorial deploys real resources into your account. These resources incur charges for as long as you keep them running. To avoid unwanted charges, the [last step of this tutorial](#step-6-destroy-resources-optional) destroys all of this tutorial’s resources. ## Step 1: Download the DigitalOcean Sample Terraform Repo We created a [GitHub repository with several Terraform configuration files](https://github.com/do-community/terraform-sample-digitalocean-architectures) that compose the web architecture. You need to download this repository to your machine to deploy the resources. This does not require a [GitHub](https://github.com/) account. First, download the repository to your system: ```shell git clone https://github.com/do-community/terraform-sample-digitalocean-architectures ``` Once you download the repository, move to the `01-minimal-web-db-stack` directory: ```shell cd terraform-sample-digitalocean-architectures/01-minimal-web-db-stack ``` This directory is where you execute Terraform commands from. ## Step 2: Configure Terraform Environment Variables Before running Terraform commands, you need to assign your API token as an environment variable. This allows Terraform to access your DigitalOcean account via the API. Environment variables are stored on your operating system outside of your working directory. This can be useful for storing variable values that are consistent across your DigitalOcean Terraform deployments, such as your API token or datacenter regions. To assign your API token as an environment variable, run the following command, entering your API token and the path to your private SSH when prompted: ``` echo Enter your DigitalOcean API token?; read token; export TF_VAR_do_token=$token ``` The command returns a blank prompt when successful. To verify the variable was created, print the value of the variable to the command line: ``` echo $TF_VAR_do_token ``` The variable is set correctly if the command prints your key. ## Step 3: Assign Values to Input Variables Next, you need to customize the architecture to match your needs, like setting your domain name and SSH key. To do this, you assign values to certain Terraform variables in its configuration files. ## Click here for an overview of Terraform variables. The `.tf` files in the working directory contain your DigitalOcean resource configurations. During deployment, Terraform loads all files with a `.tf` extension and creates a manifest of resources to deploy called a *plan*. You can divide resource configurations between as many or as few `.tf` files as you want. Here’s an example of a basic resource configuration in a `.tf` file: `example.tf` ```text resource "digitalocean_droplet" "web" { image = "ubuntu-18-04-x64" name = "web-server" region = "sfo2" size = "s-1vcpu-1gb" count = "2" } ``` This resource defines two DigitalOcean Droplets named `web-server` that run an Ubuntu 18.04 image in the SFO2 datacenter region. While you can define all of your resources by hand in `.tf` files, Terraform becomes more powerful when you begin using input variables. Input variables give you the ability to dynamically define values for resource attributes before and during deployment. In the `variables.tf` file of the sample architecture, we have defined input variables for many resource attributes, including the `region` attribute. `variables.tf` ```text variable "region" { type = string default = "nyc3" } ``` In this variable, we have defined that the value of the `region` attribute should be a string, and that if no other value is provided during the deployment, the default `"nyc3"` value is assigned to any `region` attribute with this variable assigned to it. Then, in the Droplet resource configuration `example.tf`, we assigned the region variable (`var.region`) to the region attribute: `example.tf` ```text resource "digitalocean_droplet" "web" { image = "ubuntu-18-04-x64" name = "web-1" region = var.region size = "s-1vcpu-1gb" count = "2" } ``` This means that Terraform assigns the resource’s `region` attribute value during deployment through one of four methods and in the following order: 1. Command-line flags 2. Values stored in a `.tfvars` file 3. Values set in the Terraform environment variables 4. User input on the command line during the deployment If Terraform does not receive a value from any of these methods, it assigns the default value. In the example above, if you didn’t assign a value to the region variable through any of the aforementioned methods, Terraform would assign the `nyc3` value to all resources with a `region` attribute that have this input variable assigned to it. In the sample architecture, we assigned values for several required variables in the `nyc3.tfvars` file which you need to customize before deployment. To edit the input variables, open the `nyc3.tfvars` file in a text editor: ```shell nano nyc3.tfvars ``` Then change the values of the `ssh_key` and `domain_name` fields. - For the `ssh_key` field, enter the file name of an SSH key you have [previously uploaded to your team](https://docs.digitalocean.com/platform/teams/how-to/upload-ssh-keys/index.html.md). - In the `domain` field, enter a [domain name hosted on DigitalOcean](https://docs.digitalocean.com/products/networking/dns/how-to/add-domains/index.html.md). You can also customize the values of other variables, like the region. The result should look similar to this: `nyc3.tfvars` ```text region = "nyc3" droplet_count = 3 ssh_key = "id_rsa.pub" subdomain = "minimal-vpc" domain_name = "example.com" ``` Save the changes to the file and then close it. ## Step 4: Deploy the Infrastructure Terraform requires three steps for deployment: 1. **Initializing the directory**. `terraform init` prepares the working directory for use by accounting for any changes in Terraform’s backend configuration. 2. **Reviewing an execution plan**. `terraform plan` provides a detailed manifest of the resources for you to review before execution. 3. **Applying (executing) the Terraform plan**. `terraform apply` executes the deployment of the resources into your account. To initialize the working directory, run the following command from the `01-minimal-web-db-stack` directory: ```shell terraform init ``` Next, create the Terraform plan: ```shell terraform plan -var-file=nyc3.tfvars -out=infra.out ``` Terraform saves the plan to an `infra.out` inside the working directory. Open the file in a text editor to review your Terraform plan. Finally, apply the plan and begin the deployment: ```shell terraform apply "infra.out" ``` Terraform creates the resources outlined in the Terraform plan in your DigitalOcean account. ## Step 5: View Your Infrastructure You can view the resources being created in the [control panel](https://cloud.digitalocean.com), like the [Droplets](https://cloud.digitalocean.com/droplets), [database](https://cloud.digitalocean.com/databases), and [load balancer](https://cloud.digitalocean.com/networking/load_balancers). Once the deployment is complete, you have deployed the infrastructure. To view the website being hosted by the Droplets, open a web browser and enter `minimal-vpc.example.com`, replacing `example.com` with the domain you used in the deployment. Click your browser’s **Reload** or **Refresh** button to see how the load balancer is distributing traffic across the Droplets using a round-robin algorithm. ## Step 6: Destroy Resources (Optional) You can delete resources from your account using Terraform with one command. You can destroy specific resources or all the resources deployed using your `.tfvars` file. To destroy all of the resources you created during this tutorial, run: ```shell terraform destroy -var-file=nyc3.tfvars ``` Terraform asks you to confirm the deletion. ## Summary Once you’ve deployed resources into your account, you can use this same workflow to deploy similar architectures for other web applications into your account. You only need to complete these steps once: - Create an API token. - Download Terraform. - Set up environmental variables. To deploy additional architectures using the same configuration, run the following commands from the Terraform directory: 1. Run `terraform init` to initialize the directory. 2. Run `terraform plan -var-file=nyc3.tfvars -out=infra.out` to create and review your Terraform plan. 3. Review your Terraform plan by opening `infra.out` file in a text editor. 4. Run `terraform apply "infra.out"` to deploy resources. ## What’s Next? After deploying the web application infrastructure, you can use your new Droplets and network to [host your websites](https://www.digitalocean.com/community/tutorials/how-to-host-a-website-using-cloudflare-and-nginx-on-ubuntu-20-04) and applications. You can also edit the Terraform files to experiment and make changes to the infrastructure. Use our reference documentation to learn about more options: [DigitalOcean Terraform Provider Reference](https://docs.digitalocean.com/reference/terraform/reference/index.html.md): A complete reference for the DigitalOcean Terraform provider. After you make changes, you can redeploy the new infrastructure by using the instructions in [step 4](#step-4-initialize-review-plan-and-execute-terraform).