Combining Infrastructure as Code Software Tools to Create and Manage your Application

Matheus Leal
Nerd For Tech
Published in
7 min readOct 18, 2021

--

Infrastructure as Code usually refers to the practice of defining infrastructure in a declarative model defined in text files. This can be of great help for companies if combined with the DevOps culture, as it makes it easier to edit and distribute configurations across the infrastructure in a simple and reliable way. We present an approach to combining more than one infrastructure as code tools to manage and provision your application.

Credit: bridgecrew

Infrastructure as Code (IaC) is a way to automate the provisioning of IT infrastructure. IaC consists of using a high-level descriptive coding language that aims to automate the provisioning of your application infrastructure. This eliminates the need for developers to manually provision and manage servers, storage, and cloud services.

IaC concept is very similar to programming scripts. Both automate processes, but they differ in their ability to provision and deploy processes that are more versatile and adaptable to different types of environments. It is possible to create a server, or a set of them, all based on scripts and logic that meet the reality of the business. This can be of great help for companies if combined with the DevOps culture.

The goal of Infrastructure as Code is to make things faster by eliminating manual processes and eliminating the slack in the process. A code-based approach makes it easier to get more done in less time. We can highlight some advantages:

  • Agility: IaC accelerates the process of provisioning an infrastructure to develop, test, and produce applications. Allowing the configuration of a complete environment running just a script.
  • Consistency: Your configuration files have only one source of information. This ensures the ability to perform repeated provisioning consistently and without information disparity.
  • Security: These tools allow us to quickly fix errors and automated troubleshooting, leaving a more secure and managed infrastructure across the enterprise.

This article presents reasons to combine Infrastructure as Code software tools to manage and provision your application.

Orchestration vs Configuration Management

IaC tools can be divided into two categories: orchestration and configuration management tools. This is a critical distinction to make when we assume we can leverage virtualization and containers.

The first one is used to provision and manage components of the environment, such as cloud resources. AWS CloudFormation and Terraform are examples of Infrastructure as Code orchestration tools. The other one is aimed to install and manage software running on servers like Puppet, Chef, and Ansible. We must not choose a single tool.

It is important to recognize the difference between these two steps in the deployment process and take into consideration the impact of configuration after provisioning on that process. Depending on the method of configuration, this step can have a serious impact on the speed and efficiency of the deployment process as a whole.

Credit: devops.com

Combining Infrastructure as a Code software tools

Although virtualization and containers make provisioning a service instance a relatively easy experience, configuring these services must still be done manually. When deploying a new service, existing settings will not be fully valid. There will always be some customization that should take place, if only to ensure the service is interacting with the right application.

Orchestration addresses the need to automate the lifecycle of environments. These tools ensure that an environment is in its desired state continuously. He is concerned with the provisioning, sizing and operations of the infrastructure. Whenever there is any system failure, Terraform, for example, automatically restores and calculates the entire process in the system after recharging. It is the best fit in situations where a constant and invariant state is required. This will help to resolve all anomalies effectively.

This means that once service provisioning is complete, there is still work to be done. For example, you don’t just launch a load balancing service without instructing it on how to distribute the load and which set of servers.

Configuration management (CM) tools solve problems locally, rather than replacing the system entirely. They automate the configuration of applications or hardware. CM tools help configure every action and instrument and ensure smooth operation without any damage or error. As such, it tends to be highly specialized for specific applications or domains.

Orchestrators will delegate configuration managers to the elements of a deployment. This delegation can be triggered by the Orchestrator or completely delegated to operations depending on the CM tool. It is the optimization of the configuration processes, not the provisioning, that will ultimately provide the benefits in terms of reduced errors and improved time-to-market.

Credit: golibrary

Use Case - Setting Up WordPress Service

We want to provide you with a path to a ready-to-use WordPress page. On this journey, we leave you the freedom to deepen your knowledge of the tools and resources used. First, we need to build the resources on a cloud provider with Terraform. For this example, let’s use Google Cloud Platform (GCP).

provider "google" {
project = “google-demo”
region = "europe-west1"
}

To work with a virtual machine in our project or display our page in the web browser, we need a virtual network where other GCP resources, like nodes, addresses, firewall rules, could be added.

resource "google_compute_network" "this" {
auto_create_subnetworks = false
name = "example"
routing_mode = "REGIONAL"
}

resource "google_compute_subnetwork" "this" {
name = "example"
ip_cidr_range = 192.168.24.0/24
region = "europe-west1"
network = google_compute_network.this.id
}
resource "google_compute_global_address" "this" {
provider = google-beta

name = "private-ip-db-address"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = google_compute_network.this.id
}

resource "google_service_networking_connection" "this" {
provider = google-beta

network = google_compute_network.this.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges =[google_compute_global_address.this.name]
}

To properly launch a functional WordPress instance, we need a database. We can create a virtual machine for the database, install it and configure it. We can also utilize managed services using the cloud and do not need to worry about creating the whole infrastructure from scratch. With a few lines of code we can deploy a new and shiny MySQL instance ready to work.

resource "google_sql_database_instance" "this" {
database_version = "MYSQL_5_7"
name = example-wordpress
region = "europe-west1"

depends_on = [
google_service_networking_connection.this]

settings {
availability_type = "REGIONAL"
disk_autoresize = false
disk_size = 50
disk_type = "PD_HDD"
tier = "db-g1-small"

backup_configuration {
enabled = true
start_time = "04:00"
binary_log_enabled = true
}

ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.this.id
}

location_preference {
zone = "europe-west1-a"
}

database_flags {
name = "max_connections"
value = 500
}
}
}

resource "google_sql_database" "this" {
name = "wordpress"
instance = google_sql_database_instance.this.name
charset = "utf8"
collation = "utf8_general_ci"
}

Finally, we need to create a virtual machine for our WordPress application. To do that, we will need some details about:

  • Which type of machine we chose,
  • What image we chose,
  • What size of disk we chose.

We can check it in GCP documentation. For tutorial purposes, we don’t need a big machine with a ton of vCPUs and RAM available, so we chose a small one.

resource "google_compute_instance" "this" {
name = "example-wordpress"
machine_type = "e2-standard-2"
zone = "europe-west1-b"
metadata_startup_script = templatefile("${path.module}/init.sh", {
DB_USERNAME = random_string.this.result
DB_PASSWORD = random_password.this.result
DB_HOST = google_sql_database_instance.this.private_ip_address
})

boot_disk {
initialize_params {
image = “debian-cloud/debian-10”
size = 50
}
}

network_interface {
subnetwork = google_compute_subnetwork.this.id

access_config {
nat_ip = google_compute_address.this.address
}
}

service_account {
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
}
}

After that we have the entire environment provisioned. But we only have the generic features. We need to turn this infrastructure into a WordPress application. So we need to set up this environment with WordPress. For this, we will use Ansible.

---
- name: Download WordPress
get_url: url=http://wordpress.org/wordpress-{{ wp_version }}.tar.gz dest=/srv/wordpress-{{ wp_version }}.tar.gz
sha256sum="{{ wp_sha256sum }}"

- name: Extract archive
unarchive:
creates: /srv/wordpress
src: /srv/wordpress-{{ wp_version }}.tar.gz
dest: /srv/wordpress

- name: Add group "wordpress"
group: name=wordpress

- name: Add user "wordpress"
user: name=wordpress group=wordpress home=/srv/wordpress/

- name: Fetch random salts for WordPress config
get_url:
url: https://api.wordpress.org/secret-key/1.1/salt/
register: "wp_salt"
become: no
become_method: sudo
changed_when: true
delegate_to: localhost

- name: Create WordPress database
mysql_db: name={{ wp_db_name }} state=present

- name: Create WordPress database user
mysql_user: name={{ wp_db_user }} password={{ wp_db_password }} priv={{ wp_db_name }}.*:ALL host='localhost' state=present

- name: Copy WordPress config file
template: src=wp-config.php dest=/srv/wordpress/

- name: Change ownership of WordPress installation
file: path=/srv/wordpress/ owner=wordpress group=wordpress state=directory recurse=yes setype=httpd_sys_content_t

- name: Start php-fpm Service
service: name=php-fpm state=started enabled=yes

This Ansible playbook deploys a simple configuration of WordPress platform. To use, copy the hosts.example file to hosts and edit the hosts inventory file to include the necessary variables. Then you will need to just run the playbook, like this:

ansible-playbook -i hosts wordpress.yml

After that, you will have a WordPress service with all the infrastructure configured through code.

Conclusion

Infrastructure as Code consists of using a high-level descriptive coding language that aims to automate the provisioning of your application infrastructure. The goal of IaC is to make things faster by eliminating manual processes and eliminating the slack in the process. A code-based approach makes it easier to get more done in less time. Combining Infrastructure as Code software tool can help you with the consistency, agility, and security of your environment. We presented a use case where orchestration and configuration management tools were used to create a ready-to-use WordPress page.

--

--

Matheus Leal
Nerd For Tech

M.Sc at Pontifícia Universidade Católica do Rio de Janeiro & Applying DevOps culture at Globo