Deploy Terraform + Ansible Playbook with UpCloud infrastructure


Example deployment with Terraform + Ansible : “Loadbalancer and 2 X Webservers connected throught SDN using Debian template”


/ deployment.tf

terraform {
  required_providers {
    upcloud = {
      source = "UpCloudLtd/upcloud"
      version = "~> 2.0"
    }
  }
}

resource "upcloud_network" "sdn_network" {
  name = var.hostname_SDN
  zone = var.upcloud_zone

  ip_network {
    address = "10.0.0.0/24"
    dhcp    = true
    family  = "IPv4"
  }
}



#loadbalancer Server

 resource "upcloud_server" "server1" {
     hostname = var.hostname-loadbalancer
     zone = var.upcloud_zone
     plan = "1xCPU-1GB"
     
template {
     
     size = 25
     #template Debian 10
     storage = "01000000-0000-4000-8000-000020050100"
       }

network_interface {
     type = "public"
  }

network_interface {
     type = "utility"
  }

network_interface {
     type = "private"
     ip_address = "10.0.0.2"
     network = upcloud_network.sdn_network.id
  }


login {
    user = "root"
    keys = [ chomp(file(var.ssh_private_key_path))]
    create_password = true
    password_delivery = "email"
  }
}

How to generate Ansible inventory: “for automation”

resource "local_file" "AnsibleInventory" {
  content =  templatefile("hosts.tmpl", {
  
  loadbalance-ip = upcloud_server.server1.network_interface[0].ip_address,
  
  webserver001-ip = upcloud_server.server2.network_interface[0].ip_address,
  
  webserver002-ip = upcloud_server.server3.network_interface[0].ip_address
})
  filename = "hosts"
}

Ansible hosts.tmpl file “for automation”

[loadbalancer]
${loadbalance-ip}

[webserver001]
${webserver001-ip}

[webserver002]
${webserver002-ip}

Terraform variables.tf file:

variable "ssh_private_key_path" {
  default     = "/home/$USER/.ssh/id_rsa.pub"
  type        = string
}

variable "hostname-loadbalancer" {
  default     = "loadbalancer.mytest.com"
  type        = string
}

variable "hostname-webserver001" {
  default     = "webserver001.mytest.com"
  type        = string
}

variable "hostname-webserver002" {
  default     = "webserver002.mytest.com"
  type        = string
}

variable "upcloud_zone" {
  default     = "uk-lon1"
  type        = string
}

variable "hostname_SDN" {
  default     = "mytest.com Private Network"
  type        = string
}

Terraform commands: ./instal.sh

terraform init -input=false
terraform plan -out=tfplan
terraform apply "tfplan" 

##Ansible Playbook . webserver001.yml

---
- name: Webserver installation
  hosts: webserver001
  become: true

  tasks:
    - name: Update and upgrade apt packages
      apt:
       update_cache: yes
       upgrade: "yes" 

    - name: Install UFW
      apt:
       name: ufw
       state: present
    - name: Setup rules
      command: ""
      with_items:
        - ufw default deny incoming
        - ufw allow ssh
        - ufw allow http
        - ufw allow https
        - ufw --force enable

    - name: nginx
      apt: 
       name: nginx
       state: present

    - name: Delete content & directory
      file:
       state: absent
       path: "/var/www/html/index.nginx-debian.html"

    - name: "copying the web pages"
      template:
       src: "index.html"
       dest: "/var/www/html/index.html"

    - name: "start nginx"
      service:
       name: "nginx"
       state: started

Ansible hosts file:

[loadbalancer]
 
[webserver001]
 
[webserver002]
 

Ansible Commands: ./instal.sh

ansible-playbook webserver001.yml -i hosts
ansible-playbook webserver002.yml -i hosts
ansible-playbook haproxy-install.yml -i hosts