Skip to content

danielpoonwj/gcp-iac-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Infrastrucure as Code Demo

Introduction

This project is a demonstration on using various tools to provision and deploy jenkins on Google Cloud Platform, with one jenkins job to build a docker container of a sample web application. This is by no means production ready, but the aim is to provide a brief run-through of the approach and various tools that can be used to accomplish this.

Note: This has only been tested for *nix systems (Mac OS/Linux). The tools may be supported on Windows but I've not personally tried.

Machine Image Provisioning

Overview

packer is a tool which specializes in the creation of various types of machine images. This allows the exact same provision steps for different targets (eg. Google Compute Engine Images, AWS AMIs, Vagrant Boxes). In this example, the core provisioning steps are performed with ansible, leveraging on open source Ansible Galaxy roles for the installation and configuration of jenkins and docker. However, there are other automation tools supported as packer provisoners, such as chef, puppet and salt.

One of the goals of this demo is to be able to develop locally for a faster feedback cycle, particularly for this provisioning stage. For this, we are using vagrant. Paired with packer's vagrant builder, the exact same provisioning steps can be performed locally.

One of the advantages of ansible is the included ansible-vault tool, which encrypts sensitive data. For this demo, the jenkins username and password are encrypted in ansible/vars/vault.yml. You can interact with the vault using the following commands. Note that checking in the password file to version control is only for demonstration purposes and should NOT be done under any other circumstances as it defeats the purpose of encrypting sensitive data.

# view the decrypted contents of the file
ansible-vault view --vault-password-file .ansible-vault-pass ansible/vars/vault.yml

# decrypt and edit the file if necessary
ansible-vault decrypt --vault-password-file .ansible-vault-pass ansible/vars/vault.yml

# encrypt the file after editing the contents
ansible-vault encrypt --vault-password-file .ansible-vault-pass ansible/vars/vault.yml

Requirements

Setup

There is a convenience wrapper script provided in packer/build.sh. This mainly wraps the packer command and does a bit of plumbing specifically for use with vagrant.

Note: For simplicity, the following sections will be assuming you are in the packer directory.

cd packer

Vagrant (Local Development)

This command downloads and starts the base Ubuntu box on which the provisioning steps will be run. The output of the packer command is a Box that will then be added as jenkins on your system. Note that this step may take a while if the ubuntu/xenial64 box had not yet been downloaded to your system.

bash build.sh vagrant jenkins

To start the vagrant VM locally, run the following steps. You can change the system resources allocated to the VM in the Vagrantfile provided.

cd vagrant/jenkins
vagrant up

Google Cloud

To be able to provision Google Compute Engine Images, packer will essentially be making authenticated API calls to start and stop instances. Access can be granted via the gcloud SDK.

# login to your account (https://cloud.google.com/sdk/gcloud/reference/init)
gcloud init

# set the application default credentials (https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login)
gcloud auth application-default login

This command handles the lifecycle on GCP in which an instance will be started on which the provisioning steps will be run, then it'll be stopped and the provisioned image subsequently saved.

Note: For this to work on your account, you would have to change the project value in packer/vars/googlecompute.vars to your GCP project id.

bash build.sh googlecompute jenkins

Infrastructure Management and Deployment

Overview

Once the machine image is built, the natural next concern is to set up the surrounding infrastructure as well as deploy the image as an instance. terraform is used to declare and create cloud infrastracture, including deploying the image built in the previous section.

Requirements

  • terraform >= 0.11 (this has only been tested to work on 0.11.x, but it should be compatible with 0.12)

A core concept in how terraform functions is that of state. This state can be stored as files in a remote file store, such as Google Cloud Storage, which is what this demo has chosen to do. While GCS buckets can be created and managed by terraform, this is a one-time procedure and honestly is easier to manually create the bucket via the UI, particularly since there is the limitation that the bucket names have to be globally unique.

Do create the bucket for the state to be stored, then change the values in the state.tf files and terraform/jenkins/main.tf from gcp-demo-terraform-state-bucket to the name of your newly created bucket.

Also do change the project values in the terraform.tfvars files to your Google Cloud project.

Setup

This terraform project structure generally follows the concept that modules are reusable components across environments. the dev directory contains the main entrypoints for the development environment, and should mainly be referencing modules defined in modules, and passing in environment specific values. For example to save resources, the dev environment may be the exact same structure as production, but use smaller instance types.

├── dev
│   ├── jenkins
│   └── network
└── modules
    ├── backend_service
    ├── jenkins
    └── network
        ├── nat
        ├── subnet
        └── vpc

Note: For simplicity, the following sections will be assuming you are in the terraform directory.

cd terraform

Network

This section creates an entirely new VPC, public and private subnets, as well as a Cloud NAT resource for the instances in the private subnet to connect to the internet.

cd dev/network

# compute and review resources that will the changed
terraform plan -out tf.plan

# apply the changes
terraform apply "tf.plan"

Jenkins

This section creates the resources specific to jenkins, including a HTTP(s) load balancer and a backend service pointing to a managed instance group with an instance template referencing the jenkins image previously created.

cd dev/jenkins

# compute and review resources that will the changed
terraform plan -out tf.plan

# apply the changes
terraform apply "tf.plan"

Cleaning up

terraform can destroy the created resources with the command terraform destroy within each of the directories (terraform/dev/jenkins and terraform/dev/network). Its advised to destroy them in that order as the jenkins resources are dependent on those managed in network.

About

Infrastructure as Code demo on GCP

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published