IBM Cloud Global

 View Only

An Introduction to Terraform: Deploying an Apache Webserver on IBM Cloud

By JACK BERNHARDT posted 8 days ago

  

Overview

Building automation around infrastructure deployment can drastically reduce provisioning times and frequency of errors.  In this guide we will walk through automating the deployment of a vanilla apache web server using Terraform and Ansible. This is just a starting point, from which more customized solutions can be built.

The Terraform in this example will:

  • Create a Premium VLAN
  • Provision a CentOS virtual server
  • Kick off an Ansible Playbook that will:
    • Install apache on the virtual server
    • Start the apache service
    • Install dependent libraries
    • Copy your website source files from your workstation to the newly created server

    Prerequisites

    You will need to provision compute infrastructure on your IBM Cloud account in order to use the example code. IBM Cloud virtual server instances and bare metal servers can be ordered via your IBM Cloud account. Don’t have an IBM Cloud account yet? Sign up here.

    NOTE: This code is written to work with Terraform version 1.5.7 and above. If you would like to work with multiple versions of Terraform on the same machine take a look at tfswitch.

    Deploying the virtual server

    1.     Download example code

    $ git clone https://github.com/cloud-design-dev/apache-ibmcloud-terraform
    $ cd apache-ibmcloud-terraform

    2.     Load your SSH key

    If you don’t already have an SSH key pair generated and uploaded to your IBM Cloud account, we can do that here. We’ll need the SSH public key in IBM Cloud so that your workstation can authenticate against the virtual server we create with terraform. 

    Not sure if you have a key uploaded on IBM? Check here.

    Generate the SSH key

    $ ssh-keygen -t ed25519 -b 4096

    Add the public key to the IBM Cloud portal

    3.     Update our .tfvars file

    We will need to update terraform.tfvars.example with our respective identifiers, and then rename it so that Terraform picks up the variables. Check the file for details on each item that should be updated.

    $ vi/nano terraform.tfvars.example

    $ mv terraform.tfvars.example terraform.tfvars

    There are two options for authentication here: either using IBM Cloud API key or your “classic” username and API key. Our example uses the IBM Cloud API key. These can be retrieved or created in the cloud console here.

    API Key

    PLEASE NOTE! Though we are taking this approach for simplicity, storing secrets (such as API keys) in plaintext files is not best practice; it is highly recommended to use environment variables or some form of secrets management tooling (such as openbao) for real-world deployments.

    4.     Initialize Terraform providers

    Setting the provider informs Terraform on which provider to pull configuration files for. Initializing Terraform is what bootstraps the configuration for any listed providers, so we do that here.

    $ terraform init -upgrade

    5.     Create the Terraform plan

    It is considered good practice to run terraform plan, save your Terraform execution to a plan file, in order to both review and encapsulate the proposed changes in a static file. Let’s create the plan and output it to a file. Success here means that everything on Terraform’s end is appropriate - any syntax errors should be noted and corrected.

    $ terraform plan -out "out.tfplan"

    terraform plan -out “out.tfplan”

    6.  Apply the plan

    Now that we have written and reviewed our planned changes, let’s apply them based on the created file. Any errors here will not be from a Terraform configuration standpoint, but rather on the remote end that we’re running the plan against.

    terraform apply "out.tfplan"

    terraform apply “out.tfplan”

    From here, you should see Terraform work through each of your blocks in the main.tf file. Let’s break down each of these components:

    • data "ibm_compute_ssh_key" "ssh_key": This retrieves the public SSH key we previously uploaded onto IBM Cloud. This will be imported into the system we’re creating so that you may SSH in without a password. This is then referenced at the bottom of the apache_vm resource block. Consider disabling password login for root after provisioning is complete.
    • resource "ibm_network_vlan" "apache_vlan": A private VLAN in a datacenter of your choice, defaulting to Dallas 13, for the new system to be provisioned on. - resource "ibm_compute_vm_instance" "apache_vm": The CentOS system we are deploying Apache on. Minimal specs are provided, and the hostname and domain have been set through your .tfvars file. Many options for virtual servers can be found on the provider documentation here
    • module "ansible" and resource "null_resource" "ansible": These two tie our Ansible portion into the terraform runtime, so that we can run the playbook directly from our terraform. The local-exec provisioner provides the direct command to run the playbook.

    The Ansible module provides additional configuration for the virtual machine post-provision. This includes… - creating the Ansible inventory file via templatefile - installing apache (httpd) from the CentOS default repositories - copying our website - in this case only an index.html file - onto our apache server

    7.        Test! Either go to the IP address provided as an output from your terraform, or curl it to check the updated apache.

    a. Retrieve IP address from Terraform for the web page:

    terraform output

    b. Check with cURL:

    curl $(terraform output --raw vm_public_ip)

    curl

     

    If you review the index file we copied over to our apache server, we expect this output. We now have a functioning web server.

    When you’re done testing and amending, clean up the workspace with Terraform. This will show a list of resources to be removed - this is destructive behavior, so review carefully! When certain, you may provide Terraform with confirmation via “yes”.

    $ terraform destroy

    terraform destroy

    NOTE: Always let Terraform handle the decommissioning of the resources in its workspace. This will keep things clean from mismatches between what terraform has listed and what you actually have provisioned on your IBM Cloud account. Running terraform show can list what resources have been deployed in a given workspace.

    Summary

    And that’s it! This has been a simple example to deploy a CentOS server on IBM Cloud, and immediately bootstrap it with a custom Apache webpage. We hope that you can use this as a base to build your own custom solution using IBM, Terraform, and Ansible.

    If you have any questions around this post, please direct your questions to john.bernhardt@ibm.com or aabdull@us.ibm.com

    Further reading:

    0 comments
    48 views

    Permalink