Manage cloud infrastructure using Terraform

Started by sbglobal, Oct 06, 2022, 09:21 AM

Previous topic - Next topic

sbglobalTopic starter

In this topic, we will look at what Terraform consists of, and also gradually launch our own infrastructure in the cloud with VMware — we will prepare three VMs for different purposes: proxy, file storage and CMS.

Terraform — description, advantages and components
Terraform is an IaC (Infrastructure-as-Code) tool for building and managing virtual infrastructure using code.
In working with the tool, we noted several advantages:

    The speed of deployment of new tenants (custom virtual environments). Usually, the more new customers there are, the more "clicks" technical support staff need to make to publish new resources. With Terraform, users can change the parameters of virtual machines (for example, automatically shut down the OS and increase the partition of the virtual disk) without the participation of technical support and shutdown of the machine itself.

    Instant verification of the activation plan of the new tennant. Using the description of the infrastructure code, we can immediately check what will be added and in what order, as well as in what final state this or that virtual machine or virtual network with connections to virtual machines will be.

    The ability to describe most popular cloud platforms. You can use the tool from Amazon and Google Cloud, to private platforms based on VMware vCloud Director, offering services within IaaS, SaaS and PaaS solutions.

    Manage multiple cloud providers and distribute infrastructure between them to increase fault tolerance, using a single configuration to create, diagnose and manage cloud resources.

    Convenient use for creating demo stands for testing and debugging software. You can create and transfer stands for the testing department, check software in different environments in parallel, and instantly change and delete resources by creating just one resource building plan.

Terraform "Terrarium"

We briefly talked about the advantages of the tool, now we will analyze it into its components

Providers (providers).

In Terraform, almost any type of infrastructure can be represented as a resource. The connection between resources and the API platform is provided by providers modules that allow you to create resources within a specific platform, for example, Azure or VMware vCloud Director.

As part of the project, you can interact with different providers on different platforms.

Resources (description of resources).

The resource description allows you to manage platform components, such as virtual machines or networks.

You can create a resource description for the VMware vCloud Director provider yourself and use this description to create resources from any hosting that uses vCloud Director.  You will only need to replace the authentication parameters and network connection parameters to the required hosting provider


This component makes it possible to perform operations for the initial installation and maintenance of the operating system after the creation of virtual machines. After you have created a virtual machine resource, with the help of provisioners, you can configure and connect via SSH, update the operating system, and download and execute the script.

Input and Output variables.

Input variables — input variables for all types of blocks.

Output variables allow you to save values after creating resources and can be used as input variables in other modules, for example in the Provisioners block.

States (states).

States files store information about the configuration of the provider's platform resources.
When the platform is first created, there is no information about resources, and before any operation Terraform updates the state with the real infrastructure of the resources already described.

The main purpose of states is to save a bundle of objects of already created resources for comparing the configuration of added resources and objects in order to avoid re-creation and changes to the platform.

By default, the status information is stored in the local terraform.tfstate file, but if necessary, it is possible to use remote storage to work in a team.

You can also import the current platform resources into the state in order to further interact with other resources, which in turn were created without the help of Terraform.

Creating infrastructure

The components have been sorted out, now with the help of Terraform we will gradually create an infrastructure with three virtual machines. The first with an nginx proxy web server installed, the second with a Nextcloud-based file storage, and the third with a Bitrix CMS.

We will write code and execute it using the example of our cloud on VMware vCloud Director. Our users get an account with Organization Administrator rights, if you use an account with the same rights in another VMware cloud, you will be able to reproduce the code from our examples. Let's go!

First, we will create a directory for our new project, in which the files with the description of the infrastructure will be placed.

mkdir project01

Then we will describe the infrastructure components. Terraform creates links and processes files based on the description in the files. The files themselves can be named based on the purpose of the described blocks, for example, - describes the network parameters for the infrastructure.

The configuration language in Terraform is declarative and the order of the blocks does not matter, except for the provisioner blocks, because in this block we describe the commands to be executed when preparing the infrastructure and they will be executed in order.
The structure of the blocks.

To describe the blocks, its own programming language HCL (HashiCorp Configuration Language) is used, it is possible to describe the infrastructure using JSON. You can read more about the syntax on the developer's site.
Configuration of the environment variable, and vcd.tfvars

First, we will create two files that describe a list of all variables used and their values for the VMware vCloud Director module. Let's create the file first .
File Contents .
The values of variables that we receive from the provider.

And we enter our variables:

    vcd_edge_local_ip_nginx - IP address of the NGINX VM,

    vcd_edge_local_ip_bitrix - IP address of the virtual machine with 1C: Bitrix,

    vcd_edge_local_ip_nextcloud is the IP address of the virtual machine with Nextcloud.

With the second file, we create and specify variables for the VMware vCloud Director module in the vcd.tfvars file: Recall that in our example we use our own mClouds cloud, if you work with another provider, specify the values from it.
The contents of the vcd.tfvars file.
Network configuration, .

Environment variables are set, now we will configure the connection scheme of virtual machines — we will assign a private IP address to each virtual machine and use Destination NAT to "forward" ports to the external network. To restrict access to the management ports, we will set access only for our IP address.
Network diagram for the Terraform platform being created
Network diagram for the Terraform platform being created

Creating a virtual organizational network with the name net_lan01, default gateway:, and also with the address space:
We describe the virtual network.

Let's create rules for a firewall that allows virtual machines to access the Internet. Within this block, all virtual resources in the cloud will have access to the Internet:
We describe the rules for VM access to the Internet.

By setting the dependency that after processing the block we proceed to the configuration of the vcdnsxvfirewallrule block, using dependson. We use this option because some dependencies can be recognized implicitly in the configuration.

Next, we will create rules allowing access to ports from the external network and specify our IP address for SSH connection to web servers. Any Internet user has access to ports 80 and 443 on the server and a user with an IP address of has access to SSH ports of virtual servers.
We allow access to ports from the external network.

Creating Source NAT rules for accessing the Internet from a cloud LAN:
We describe the Source NAT rules.

And at the end of the network block configuration, we add Destination NAT rules for accessing services from an external network:
Adding Destination NAT rules.
Adding a NAT rule for port translation to an SSH web  server under Nginx.
Adding a NAT rule for port translation to an SSH server with 1C-Bitrix.
Adding a NAT rule for port translation to an SSH server from Nextcloud.
Virtual Environment Configuration

As we planned at the beginning of the article, we will create three virtual machines.
They will be prepared using "Guest Customization". We will write the network parameters according to the settings we specified, and the password from the user is generated automatically.

Let's describe the vApp in which the virtual machines and their configuration will be located.

Let's create a vApp container. So that we can immediately connect the vApp and VM to the virtual network, we also add the depends_on parameter:
Creating a container
Let's create a virtual machine with the description

The main parameters in the VM description:

    name - the name of the virtual machine,

    vappname - the name of the vApp to add a new VM to,

    catalogname / templatename - the name of the directory and the name of the virtual machine template,

    storageprofile is the default storage policy.

Network block Parameters:

    type - type of connected network,

    name - which virtual network to connect the VM to,

    isprimary - the main network adapter,

    ipallocation_mode - MANUAL / DHCP / POOL address allocation mode,

    ip - the IP address for the virtual machine, we will specify manually.

The override_template_disk block:

    sizeinmb - size of the boot disk for the VM

    storage_profile - storage policy for disk

Let's create a second VM with a description of the Nextcloud file storage

In the vcdvminternal_disk section, we describe a new virtual disk that connects to the virtual machine.

Explanation of the vcdvminternaldisk block:

    bustype - type of disk controller

    sizeinmb - disk size

    busnumber / unitnumber - connection location in the adapter

    storage_profile - storage policy for disk

Let's describe the latest VM on Bitrix
Updating the OS and installing additional scripts

The network is prepared, the virtual machines are described. Before importing our infrastructure, we can perform initial provisioning in advance with the help of block provisioners and without using Ansible.

Let's consider how to update the OS and run the CMS Bitrix installation script using the provisioner block.
First, let's install the CentOS service packs.

Designation of components:

    provisioner "remote-exec" - connect the remote "provisioning" unit

    In the connection block we describe the type and parameters for the connection:

    type - protocol, in our case SSH;

    user - user name;

    password - the user's password. In our case, we point to the parameter vcdvappvm.nginx.customization[0].admin_password, which stores the generated password from the system user.

    host - external IP address to connect to;

    port - the connection port that was previously specified in the DNAT settings;

    inline - we list the list of commands that will be entered. The commands will be entered in order, as indicated in this section.

As an example, we will additionally execute the 1C-Bitrix installation script. The output of the script execution result will be available during the execution of the plan. To install the script, first describe the block:
Describe the installation of 1C-Bitrix.

And we will immediately describe the Bitrix update.
An example of 1C-Bitrix provisioning.

Important! The script may not work if you do not disable SELinux beforehand! If you need a detailed article on installing and configuring CMS 1C-Bitrix using , oo you can use our blog article on web site.

Infrastructure initialization
Initialization of modules and plugins

To work, we use a simple "gentleman's kit": a laptop with Windows 10 OS and a distribution kit from the official site . Unpack and initialize using the command: terraform.exe init

After describing the computing and network infrastructure, we start planning to check our configuration, where we can see what will be created and how it is connected to each other.

    Execute the command - terraform plan -var-file=vcd.tfvars.

    We get the result - Plan: 16 to add, 0 to change, 0 to destroy. That is, according to this plan, 16 resources will be created.

    We launch the plan on command - terraform.exe apply -var-file=vcd.tfvars.

Virtual machines will be created, and then the packages listed by us are executed within the provisioner section — the OS will be updated and CMS Bitrix will be installed.
Getting data to connect

After executing the plan, we want to get data in text form for connecting to web servers, for this we will design the output section as follows:

output "nginxpassword" {

 value = vcdvappvm.nginx.customization[0].adminpassword


And the following output tells us the password from the created virtual machine:

Outputs: nginx_password = F#4u8!!N

As a result, we get access to virtual machines with an updated operating system and pre-installed packages for our further work. Everything is ready!

But what if you already have an existing infrastructure?
3.1. Terraform working with an existing infrastructure

It's simple, you can import the current virtual machines and their vApp containers using the import command.
Let's describe the vApp resource and the virtual machine.

The next step is to import the properties of vApp resources in vcdvapp format.<vApp> <org>.<orgvdc>.<vApp>, where:

    vApp - vApp name;

    org - name of the organization;

    org_vdc is the name of the virtual data center.

Importing vApp resource properties
Importing vApp resource properties

Let's import VM resource properties in the format: vcdvappvm.<VM> <org>.<orgvdc>.<vApp>.<VM> in which:

    VM - VM name;

    vApp - vApp name;

    org - name of the organization;

    orgvdc is the name of the virtual data center.

The import was successful

Now we can look at the newly imported resource:
Imported Resource

Now it's definitely ready - we've finished with the last moment (import into the existing infrastructure) and reviewed all the main points of working with Terraform.

The tool turned out to be very convenient and allows you to describe your infrastructure as code, ranging from virtual machines of one cloud provider to describing the resources of network components.

At the same time, independence from the environment makes it possible to work with local, cloud resources, and, ending with platform management.
And in the absence of a supported platform and the desire to add a new one, you can write your own provider and use it.


Terraform is an Open Source flexible infrastructure state management web system using a declarative style.
Terraform is written in Go and has an active and numerous community that constantly creates and improves modules and providers for Terraform.
Terraform connects to cloud providers using special provider modules. To connect to VMware Cloud Director, a VCD provider is used, which can be downloaded from GitHub.