Use GitHub Actions and Terraform to provision EC2 instance
Hi, I’m DevOps Engineer at Tikal Knowledge.
In this tutorial, I will create a simple and practical example of how to provision EC2 instance with Github Actions and Terraform. I will use workflow_dispatch type of workflow which is triggered manually by the user, using Terraform Github action from HashiCorp.
This tutorial will be the first in a series of tutorials for Github Actions, in the following tutorials, I will show how to create and use self-hosted GitHub runners with EC2, docker containers running on Kubernetes, and much more.
I will try to be as practical as possible in my tutorials, so there will not be much theory.
On YouTube you can watch also: https://youtu.be/cV1LhQT1bK4
Github Actions Published guides:
- Use GitHub Actions and Terraform to provision EC2 instance
- GitOps way with Github Actions and self-hosted runner on Kubernetes
- Automatic scaling with Github Actions and self-hosted runners
- Github Actions with k8s and Karpenter to dynamically provision your runners on spot instances
- Github Actions with ChatOps to write beautiful python code
- Use OpenID Connect with Github Actions to authenticate with Amazon Web Services
Goal
Deploy EC2 instance of t3.small size to your AWS account using Github Actions and Terraform.
I will use ‘workflow_dispatch’ event for this, which is manually triggered.
What is GitHub actions?
GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. You can create workflows that build and test every pull request to your repository, or deploy merged pull requests to production.
GitHub Actions goes beyond just DevOps and lets you run workflows when other events happen in your repository. For example, you can run a workflow to automatically add the appropriate labels whenever someone creates a new issue in your repository.
GitHub provides Linux, Windows, and macOS virtual machines to run your workflows, or you can host your own self-hosted runners in your own data center or cloud infrastructure.
workflow_dispatch
This event occurs when someone triggers a workflow run on GitHub or sends a
POST
request to the "Create a workflow dispatch event" endpoint. For more information, see "Events that trigger workflows."
Why use it?
GitHub Actions makes it easy to automate all your software workflows, now with world-class CI/CD. Build, test, and deploy your code right from GitHub. Make code reviews, branch management, and issue triaging work the way you want.
Let’s do it
Generate AWS Credentials for terraform user
Go to your AWS account -> IAM -> Add a new user
We need only ‘Programmatic access’
To simplify this tutorial, I will use EC2 Full Access permissions.
Download and save the Access key id and Secret access key which will be added as secrets to Github repo.
The next step will be to add credentials to Github as secrets
Go to your Github repository -> settings -> secrets -> actions
My repo is https://github.com/warolv/github-actions-series, with all the code and the github actions workflow.
Add new repository secret
Need to add two secrets: TF_USER_AWS_KEY (Access key id) and TF_USER_AWS_SECRET (Secret access key) which will be used later in workflow I build.
Add TF_USER_AWS_SECRET in the same way.
Overview of the Terraform script to provision EC2 instance
- The provisioned instance is based on ubuntu
AMI.
- The instance type is t3.micro.
- The instance will be provisioned to default VPC | subnet | security group.
- Need to create SSH key pair to connect with the provisioned instance.
- EC2 will be provisioned to ‘us-east-2’ region.
Generate SSH key pair to connect with EC2 instance
AWS console -> EC2 -> Key Pair -> Create Key Pair
Download .pem file, it will be used later to connect with EC2 instance.
Terraform script to provision EC2 instance (app_server)
https://github.com/warolv/github-actions-series/blob/master/tf-example/main.tf
# main.tf
# use ubuntu 20 AMI for EC2 instance
data "aws_ami" "ubuntu" {
most_recent = truefilter {
name = "name"
values = ["ubuntu/images/hvm-ssd/*20.04-amd64-server-*"]
}filter {
name = "virtualization-type"
values = ["hvm"]
}owners = ["099720109477"] # Canonical
}# provision to us-east-2 region
provider "aws" {
region = "us-east-2"
}resource "aws_instance" "app_server" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
key_name = "app-ssh-key"tags = {
Name = var.ec2_name
}
}
# variables.tf
The EC2 name will be set through workflow using the inputs.
variable "ec2_name" {
type = string
}
Create a workflow with Github Actions to provision EC2 instance
- ‘configure-aws-credentials’ action used to set AWS credentials with docker container to be used by Terraform.
- You need to define name of EC2 instance using terraform variables: TF_VAR_ec2_name, before TF runs.
- Used setup-terraform action from HashiCorp.
- Used GitHub-hosted runner: ubuntu-latest.
https://github.com/warolv/github-actions-series/blob/master/.github/workflows/provision_ec2.yaml
To see your workflow in actions -> workflows, first need to create ‘.github/workflows/provision_ec2.yaml’ and add it to your repository.
# .github/workflows/provision_ec2.yaml
name: Provision t3.micro EC2on:
workflow_dispatch:
inputs:
ec2-name:
description: EC2 name
required: true
default: 'App Server'
type: string
jobs:
provision-ec2:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: '${{ secrets.TF_USER_AWS_KEY }}'
aws-secret-access-key: '${{ secrets.TF_USER_AWS_SECRET }}'
aws-region: us-east-2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_wrapper: false
- name: Terraform Apply
id: apply
env:
TF_VAR_ec2_name: "${{ github.event.inputs.ec2-name }}"
run: |
cd tf-example/
terraform init
terraform validate
terraform plan
terraform apply -auto-approve
I am using ‘workflow_dispatch’ type of workflow which is triggered manually.
Click ‘Run workflow’
You can see using AWS console that EC2 instance created!
Now try to connect to this instance using ‘app-ssh-key’
I downloaded app-ssh-key.pem file in my mac to ~/Downloads folder
cp ~/Downloads/app-ssh-key.pem ~/.ssh
cd ~/.ssh
chmod 600 app-ssh-key.pem
ssh -i app-ssh-key.pem ubuntu@13.58.251.181
Success!
You can get all tutorials for Github Action from my github repo by cloning it: ‘git clone https://github.com/warolv/github-actions-series.git‘
You can find video on YouTube also: https://youtu.be/-910lhQXJIs
Conclusion
In this tutorial, I explained how to provision EC2 instances using Terraform and Github Actions workflow, I used GitHub-hosted runner and workflow_dispatch type of workflow which is triggered manually.
Thank you for reading, I hope you enjoyed it, see you in the next post.
If you want to be notified when the next post of this tutorial is published, please follow me here on medium and on Twitter (@warolv).