Skip to content

Latest commit

 

History

History
219 lines (168 loc) · 8.4 KB

File metadata and controls

219 lines (168 loc) · 8.4 KB

Software provisioning

Prerequisites

Having completed labs 00, 01, 02, and 05.

If you did not finish lab 05, you can take *.tf files in the solution folder.

Connect to the Vagrant VM

Connect to the VM using ssh

$ cd <GIT_REPO_NAME>/vagrant
$ vagrant ssh

Move to the right path and create your lab folder

vagrant@terraform-vm$ cd ~/$GIT_REPO_NAME/labs/06-Software_provisioning

Create a new directory for the project to live and create a main.tf file for the Terraform config. The contents of this file describe all of the GCP resources that will be used in the project.

vagrant@terraform-vm$ mkdir mylab
vagrant@terraform-vm$ cd mylab
vagrant@terraform-vm$ cp ../../05-Output_variables/mylab/* ./

If you haven't complete the 05-Output_variables lab, you can take *.tf files from the solution folder.

We will modify the resourse google_compute_instance inside the instance.tf file by adding provisioners in order to perform the following tasks:

  • Install tcpdump (using the remote-exec provisioner)
  • Copy the file 'scripts/my_script.sh' (using the file provisioner)
  • Executing the script my_script.sh on the target VM (using the remote-exec provisioner)
  • Create a local Ansible inventory file containing the ip address of the target machine (using the local-exec provisioner)
  • Install nginx using Ansible and the previously created inventory file (using the local-exec provisioner)

Open the instance.tf and locate the resourse google_compute_instance, you will place code snippets witin, i.e.:

...
resource "google_compute_instance" "default" {
  // You will place code snippets here
...

Add this snippet, it is used to install tcpdump on the target machine:

 // Install software using remote-exec provisioner
 provisioner "remote-exec" {
   inline = [
      "sudo apt-get -y install tcpdump"
   ]

   connection {
    type     = "ssh"
    host     = "${google_compute_instance.default.network_interface.0.access_config.0.nat_ip}"
    user     = "${var.VM_USERNAME}"
    private_key = "${file("~/.ssh/id_rsa")}"
  }
 }

Now add the following snippet, it is used to upload the provided my_script.sh into the target VM

 // Upload a file using file provisioner
 provisioner "file" {
       source      = "../scripts/my_script.sh"
       destination = "/tmp/my_script.sh"

    connection {
      type     = "ssh"
      host     = "${google_compute_instance.default.network_interface.0.access_config.0.nat_ip}"
      user     = "${var.VM_USERNAME}"
      private_key = "${file("~/.ssh/id_rsa")}"
   }
 }

Now add the following snippet, it is used to change the permissions and execute the script on the target VM

 // Execute a script remotely using remote-exec provisioner
 provisioner "remote-exec" {
   inline = [
     "chmod a+x /tmp/my_script.sh",
      "/tmp/my_script.sh"
   ]

   connection {
    type     = "ssh"
    host     = "${google_compute_instance.default.network_interface.0.access_config.0.nat_ip}"
    user     = "${var.VM_USERNAME}"
    private_key = "${file("~/.ssh/id_rsa")}"
  }
 }

Now add the following snippet, it is used to create a file locally named inventory.txt, containing the VMs ip address in a format required by Ansible

 // Create the Ansible inventory locally using the local-exec provisioner 
 provisioner "local-exec" {
    command = "echo '[all]' > inventory.txt && echo ${google_compute_instance.default.network_interface.0.access_config.0.nat_ip} >> inventory.txt"
 }

Finally add the following snippet, it is used to execute the provided Ansible playbook toward the remote VM using the previously created inventory file

 // Provision using Ansible with local-exec provisioner
 provisioner "local-exec" {
    command = "sleep 40; ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u ${var.VM_USERNAME} --private-key ~/.ssh/id_rsa -i inventory.txt ../playbooks/ansible-playbook.yml" 
 }

Now if you save the instance.tf file and execute the terraform commands, the provisioning starts and you should see an output like the one showed here below.


vagrant@terraform-vm$ terraform init
...
vagrant@terraform-vm$ terraform plan
... 
vagrant@terraform-vm$ terraform apply
...
google_compute_instance.default: Provisioning with 'local-exec'...
google_compute_instance.default (local-exec): Executing: ["/bin/sh" "-c" "echo '[all]' > inventory.txt && echo 34.83.56.48 >> inventory.txt"]
google_compute_instance.default: Provisioning with 'local-exec'...
google_compute_instance.default (local-exec): Executing: ["/bin/sh" "-c" "sleep 40; ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u denis_maggiorotto --private-key ~/.ssh/id_rsa -i inventory.txt ../playbooks/ansible-playbook.yml"]
google_compute_instance.default: Still creating... [50s elapsed]
google_compute_instance.default: Still creating... [1m0s elapsed]
google_compute_instance.default: Still creating... [1m10s elapsed]
google_compute_instance.default: Still creating... [1m20s elapsed]

google_compute_instance.default (local-exec): PLAY [Install nginx] ***********************************************************

google_compute_instance.default (local-exec): TASK [setup] *******************************************************************
google_compute_instance.default: Still creating... [1m30s elapsed]
google_compute_instance.default (local-exec): ok: [34.83.56.48]

google_compute_instance.default (local-exec): TASK [Install base packages] ***************************************************
google_compute_instance.default: Still creating... [1m40s elapsed]
google_compute_instance.default (local-exec): changed: [34.83.56.48]

google_compute_instance.default (local-exec): PLAY RECAP *********************************************************************
google_compute_instance.default (local-exec): 34.83.56.48                : ok=2    changed=1    unreachable=0    failed=0

google_compute_instance.default: Creation complete after 1m48s [id=my-vm-0ee9ede014833adc]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

ip = 34.83.56.48

Let's check if everything went fine on the target VM:

vagrant@terraform-vm$ ssh -l denis_maggiorotto 34.83.56.48
denis_maggiorotto@my-vm-0ee9ede014833adc:~$ cat README.md 
I've been here
denis_maggiorotto@my-vm-0ee9ede014833adc:~$ apt list --installed | grep tcpdump
tcpdump/stable,stable,now 4.9.2-1~deb9u1 amd64 [installed]
denis_maggiorotto@my-vm-0ee9ede014833adc:~$ apt list --installed | grep nginx
libnginx-mod-http-auth-pam/stable,stable,now 1.10.3-1+deb9u2 amd64 [installed,automatic]
libnginx-mod-http-dav-ext/stable,stable,now 1.10.3-1+deb9u2 amd64 [installed,automatic]
libnginx-mod-http-echo/stable,stable,now 1.10.3-1+deb9u2 amd64 [installed,automatic]
libnginx-mod-http-geoip/stable,stable,now 1.10.3-1+deb9u2 amd64 [installed,automatic]
libnginx-mod-http-image-filter/stable,stable,now 1.10.3-1+deb9u2 amd64 [installed,automatic]
libnginx-mod-http-subs-filter/stable,stable,now 1.10.3-1+deb9u2 amd64 [installed,automatic]
libnginx-mod-http-upstream-fair/stable,stable,now 1.10.3-1+deb9u2 amd64 [installed,automatic]
libnginx-mod-http-xslt-filter/stable,stable,now 1.10.3-1+deb9u2 amd64 [installed,automatic]
libnginx-mod-mail/stable,stable,now 1.10.3-1+deb9u2 amd64 [installed,automatic]
libnginx-mod-stream/stable,stable,now 1.10.3-1+deb9u2 amd64 [installed,automatic]
nginx/stable,stable,now 1.10.3-1+deb9u2 all [installed]
nginx-common/stable,stable,now 1.10.3-1+deb9u2 all [installed,automatic]
nginx-full/stable,stable,now 1.10.3-1+deb9u2 amd64 [installed,automatic]

Remember to destroy resources (active VM cost)

vagrant@terraform-vm$ terraform destroy
random_id.instance_id: Refreshing state... [id=VPapVgriyvw]
google_compute_instance.default: Refreshing state... [id=my-vm-54f6a9560ae2cafc]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # google_compute_instance.default will be destroyed
  - resource "google_compute_instance" "default" {
      - can_ip_forward       = false -> null
      - cpu_platform         = "Intel Broadwell" -> null
      - deletion_protection  = false -> null
      - guest_accelerator    = [] -> null
      - id                   = "my-vm-54f6a9560ae2cafc" -> null
      - instance_id          = "942803623566960790" -> null
      - label_fingerprint    = "42WmSpB8rSM=" -> null
      - labels               = {} -> null
      - machine_type         = "f1-micro" -> null
...

Type yes when prompted