Install nginx in compute engine through Terraform
Tags: nginx, gcp, terraform
Published: 2023-05-30 06:03:26

## Introduction
hi, i am Akshay Rao
This blog is about the installation of nginx in GCP VM through terraform.

## Pre-requisite 
GCP account (can get 300$ free trial account)
Terraform installed 
VS-code

## Let's start

- create a project in the gcp console.
- click on the tab beside google cloud logo and click **new project**, give name i have given it a terraform-gcp.

![Image 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lskk2jjawnq9gvfl7snr.png)

- create a service account by searching service account in the search bar, click create service account-> give name -> add the editor role under basic.

- create a keys for the service account and download the json file.
- make a directory in which the terraform scripts will be stored and move the above downloaded json to this directory.

```
mv ~/Downloads/<file name> credentials.json
```
create a file named main.tf

1. Provider block
```
provider "google" {
  project = "<your project-id>"
  credentials = "${file("credentials.json")}" 
  region = "us-west1"
  zone = "us-west1-a"
}
```
now execute `terraform init`
this is done so that the terraform can connect to gcp.
`.terraform.lock.hcl
.terraform `
will be created automatically 
provider will be registered.
![Image 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j92lvxhs3lnsf6kmkok8.png)
2. Resources block
create a network , one subnetwork and VM instance in which the nginx will be running.

```
resource "google_compute_network" "vpc_network" {
  name                    = "my-custom-network"
  auto_create_subnetworks = false
  mtu                     = 1460
}

resource "google_compute_subnetwork" "default" {
  name          = "us-west-a"
  ip_cidr_range = "10.0.1.0/24"
  region        = "us-west1"
  network       = google_compute_network.vpc_network.id
}

resource "google_compute_instance" "nginx-instance" {
    name = "nginx-intsance"
    machine_type = "f1-micro"
    tags = ["ssh"]                                              
    zone = "us-west1-a"
    allow_stopping_for_update = true

    boot_disk {
      initialize_params {
        image = "debian-cloud/debian-11"
      }
    }
    metadata_startup_script =  "sudo apt-get update; sudo apt-get install -y nginx; sudo systemctl start nginx"      // renderning script from template file
    network_interface {
      subnetwork = "google_compute_subnetwork.default.id"
      subnetwork_project = "<your project id>"
      access_config {
         // is included so that the vm gets external ip address
      }
    }
}
```

- mtu - maximum trasmiaaion unit.
- added boot as the debian 11 image.
- in the metadata_startup_script i have passed the installation commands for the nginx.

## Deployment and Verify

save it
now run command `terraform plan` and yes
terraform will know the what resources to create with plan command and it will create orderly when applied.

```
[akshay.rao terraform-gcp]$ terraform plan
data.template_file.nginx_installation: Reading...
data.template_file.nginx_installation: Read complete after 0s [id=cfbeb1ad70856f85403aaec9edaed46cdcd3ab215367abd5b1049f5a69a24fc1]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # google_compute_instance.nginx-instance will be created
  + resource "google_compute_instance" "nginx-instance" {
      + allow_stopping_for_update = true
      + can_ip_forward            = false
      + cpu_platform              = (known after apply)
      + current_status            = (known after apply)
      + deletion_protection       = false
      + guest_accelerator         = (known after apply)
      + id                        = (known after apply)
      + instance_id               = (known after apply)
      + label_fingerprint         = (known after apply)
      + machine_type              = "f1-micro"
      + metadata_fingerprint      = (known after apply)
      + metadata_startup_script   = <<-EOT
            #!/bin/bash/
            set -e
            echo "** installing nginx **"
            sudo apt-get update
            sudo apt-get install -y nginx
            sudo systemctl enable nginx
            sudo systemctl restart nginx
            
            echo "**   Installation Complteted!!   **"
            
            echo "Welcome to Nginx which is deployed using Terraform!!!" > /var/www/html
            
            echo "**   Startup script completes!!   **"
        EOT
      + min_cpu_platform          = (known after apply)
      + name                      = "nginx-intsance"
      + project                   = (known after apply)
      + self_link                 = (known after apply)
      + tags                      = [
          + "proxy",
        ]
      + tags_fingerprint          = (known after apply)
      + zone                      = "us-west1-a"

      + boot_disk {
          + auto_delete                = true
          + device_name                = (known after apply)
          + disk_encryption_key_sha256 = (known after apply)
          + kms_key_self_link          = (known after apply)
          + mode                       = "READ_WRITE"
          + source                     = (known after apply)

          + initialize_params {
              + image  = "debian-cloud/debian-11"
              + labels = (known after apply)
              + size   = (known after apply)
              + type   = (known after apply)
            }
        }

      + network_interface {
          + ipv6_access_type   = (known after apply)
          + name               = (known after apply)
          + network            = "default"
          + network_ip         = (known after apply)
          + stack_type         = (known after apply)
          + subnetwork         = (known after apply)
          + subnetwork_project = (known after apply)

          + access_config {
              + nat_ip       = (known after apply)
              + network_tier = (known after apply)
            }
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.
```
now `terraform apply` and yes

```
[akshay.rao terraform-gcp ]$ terraform apply
data.template_file.nginx_installation: Reading...
data.template_file.nginx_installation: Read complete after 0s [id=cfbeb1ad70856f85403aaec9edaed46cdcd3ab215367abd5b1049f5a69a24fc1]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # google_compute_instance.nginx-instance will be created
  + resource "google_compute_instance" "nginx-instance" {
      + allow_stopping_for_update = true
      + can_ip_forward            = false
      + cpu_platform              = (known after apply)
      + current_status            = (known after apply)
      + deletion_protection       = false
      + guest_accelerator         = (known after apply)
      + id                        = (known after apply)
      + instance_id               = (known after apply)
      + label_fingerprint         = (known after apply)
      + machine_type              = "f1-micro"
      + metadata_fingerprint      = (known after apply)
      + metadata_startup_script   = <<-EOT
            #!/bin/bash/
            set -e
            echo "** installing nginx **"
            sudo apt-get update
            sudo apt-get install -y nginx
            sudo systemctl enable nginx
            sudo systemctl restart nginx
            
            echo "**   Installation Complteted!!   **"
            
            echo "Welcome to Nginx which is deployed using Terraform!!!" > /var/www/html
            
            echo "**   Startup script completes!!   **"
        EOT
      + min_cpu_platform          = (known after apply)
      + name                      = "nginx-intsance"
      + project                   = (known after apply)
      + self_link                 = (known after apply)
      + tags                      = [
          + "proxy",
        ]
      + tags_fingerprint          = (known after apply)
      + zone                      = "us-west1-a"

      + boot_disk {
          + auto_delete                = true
          + device_name                = (known after apply)
          + disk_encryption_key_sha256 = (known after apply)
          + kms_key_self_link          = (known after apply)
          + mode                       = "READ_WRITE"
          + source                     = (known after apply)

          + initialize_params {
              + image  = "debian-cloud/debian-11"
              + labels = (known after apply)
              + size   = (known after apply)
              + type   = (known after apply)
            }
        }

      + network_interface {
          + ipv6_access_type   = (known after apply)
          + name               = (known after apply)
          + network            = "default"
          + network_ip         = (known after apply)
          + stack_type         = (known after apply)
          + subnetwork         = (known after apply)
          + subnetwork_project = (known after apply)

          + access_config {
              + nat_ip       = (known after apply)
              + network_tier = (known after apply)
            }
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

google_compute_instance.nginx-instance: Creating...
google_compute_instance.nginx-instance: Still creating... [10s elapsed]
google_compute_instance.nginx-instance: Still creating... [20s elapsed]
google_compute_instance.nginx-instance: Creation complete after 22s [id=projects/terraform-gcp-388209/zones/us-west1-a/instances/nginx-intsance]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```
now go to console and search for vm instances you will be able to see the vm running

![Image 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z1yv42u561ae0hjyg3g8.png)
click on ssh with open with browser window

![Image 4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3i0gh3xl96v930oennvd.png)
the terminal will open 
run command `systemctl status nginx`
you will get:-
![Image 5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmj0vi1arm6f45ek07a2.png)
we have insatlled nginx through terraform.
Thank you