Executing remote commands at bootstrap using Terraform

It's a very common practice to have a set of initial commands executed right after bootstrap, even before the proper configuration management system such as Chef or Ansible takes responsibility. It can include immediate full updating of the OS, initial registration on discovery systems such as Consul, or initial addition of local DNS servers. It really shouldn't go farther than delivering a system in a slightly more advanced and expected state for the next configuration system to take over. Under no circumstance should it replace a proper configuration management tool.

In this recipe, we'll launch a CentOS 7.2 system, then fully update it so it's as secure as possible, install EPEL so we have a greater library of available packages, add the Puppet Labs Yum repository and install a Puppet agent, and add a different name server so our system is ready for the next step (which we won't cover here, as it's probably executing Puppet code).

Getting ready

To step through this recipe, you will need the following:

  • A working Terraform installation
  • An AWS account with an SSH key configured in Terraform and a security group allowing SSH connections from outside (refer to the chapter 2, Provisioning IaaS with Terraform recipes)
  • An Internet connection

How to do it…

Before diving into the provisioning part, let's start by describing a classic CentOS 7.2 AMI in instances.tf:

resource "aws_instance" "centos" {
  ami                         = "${lookup(var.aws_centos_ami, var.aws_region)}"
  instance_type               = "${var.aws_instance_type}"
  key_name                    = "${aws_key_pair.admin_key.key_name}"
  security_groups             = ["${aws_security_group.base_security_group.name}"]
  associate_public_ip_address = true

  tags {
    Name = "CentOS"
  }
}

The variables in the variables.tf file are as follows:

variable "aws_centos_ami" {
  type = "map"

  default = {
    eu-west-1 = "ami-7abd0209"
    us-east-1 = "ami-6d1c2007"
  }
}

variable "aws_instance_type" {
  default     = "t2.micro"
  description = "Instance Type"
}

Now, what are our immediate objectives for this system?:

  • Fully update it: sudo yum install -y
  • Enable the EPEL repository: sudo yum install epel-release -y
  • Add a custom name server: echo "nameserver 8.8.8.8" | sudo tee -a /etc/resolv.conf
  • Add the Puppet Labs repository: sudo yum install https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm -y
  • Install the Puppet agent: sudo yum install puppet-agent -y
  • Display the Puppet version: sudo /opt/puppetlabs/bin/puppet agent --version

Let's add those commands inside a remote-exec provisioner inside our aws_instance resource, changing the default username to centos:

provisioner "remote-exec" {
    inline = [
      "echo "nameserver 8.8.8.8" | sudo tee -a /etc/resolv.conf",
      "sudo yum update -y",
      "sudo yum install epel-release -y",
      "sudo yum install https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm -y",
      "sudo yum install puppet-agent -y",
      "sudo /opt/puppetlabs/bin/puppet agent --version"
    ]
    connection {
        user = "centos"
      }
  }

When you terraform apply this, you'll end up with a fully updated CentOS 7.2 system, with EPEL available, a custom DNS server added and Puppet agent installed.

Ready for the next stage of deployment with Puppet!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.94.152