Create AWS codebuild project with Terraform

Summary

AWS Codebuild is fully managed build service that compiles source code, run tests, and produces software packages that are ready to reploy. To make it easier, we can create it’s infrastructure using terraform.

Setup directory structure

Before we begin, we can create our own directory structure for the infrastructure. Why this is important? because whenever we setup something and we want to change it, when revisit these files and change what necessary. To do this, we can just simply create the one just like this:

$ mkdir test-codebuild
$ cd test-codebuild
~test-codebuild$ touch main.tf vars.tf terraform.tfvars buildspec.yml

Write some terraform codes

Let’s do the code! fill each one of the files we created :

main.tf

provider "aws" {
  region = "ap-southeast-1"
}

terraform {
  backend "s3" {
    bucket = "terraform-state-test-pulpn"
    key    = "test-codebuild-project"
    region = "ap-southeast-1"
  }
}

module "codebuild" {
  source       = "git::ssh://git@github.com/muffat/tf-codebuild-module.git?ref=master"
  project_name = "${var.project_name}"
  description  = "${var.description}"
  bucket_name  = "${var.bucket_name}"
  repo_type    = "${var.repo_type}"
  repo_url     = "${var.repo_url}"
  team         = "${var.team}"
  image_name   = "${var.image_name}"
  buildspec    = "${file("buildspec.yml")}"
}

terraform.tfvars

In this file, we should define our project based on what we need. You might need to change the each variables according with what fits you needs.

project_name = "test-project"
description  = "test python project"
bucket_name  = "python-artifact"
repo_type    = "GITHUB"
repo_url     = "https://github.com/muffat/test-python-pulpn"
team         = "pulpn"
image_name   = "aws/codebuild/python:3.6.5"

vars.tf

variable "project_name" {}
variable "description" {}
variable "bucket_name" {}
variable "repo_type" {}
variable "repo_url" {}
variable "team" {}
variable "image_name" {}

buildspec.yml

Buildspec is list of steps that should be doing during the build process.

version: 0.1

phases:
  build:
    commands:
      - pip install flask

Deploy the codes

$ cd test-codebuild
~test-codebuild$ terraform init
~test-codebuild$ terraform plan
......................
TL;DR
......................
Plan: 4 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

You should be able to seen anything like above. Terraform attemps to create the infrastructure that we’ve defined in the codes before.

~test-codebuild$ terraform apply
...............
TL;DR
...............
Plan: 4 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: 

After we ran command terraform apply, we should be prompted to accept the action that terraform asked. To pass this, enter the value with yes or no to cancel it.

Accept the action by enter, yes. Then terraform will be created the codebuild infrastructure in AWS.

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

Feeling lazy? Use the links below to get your codebuild deployed with terraform

References:

Create docker image and push to AWS ECR

Image tag : test-image

awsudo -u aws-profile aws ecr get-login --no-include-email --region ap-southeast-1
sudo docker build -t test-image .
sudo docker tag codebuild:test-image 743977200366.dkr.ecr.ap-southeast-1.amazonaws.com/codebuild:test-image
sudo docker push 743977200366.dkr.ecr.ap-southeast-1.amazonaws.com/codebuild:test-image

 

SSH tunneling to your secured database/RDS through bastion/jump server with forwarded port

$ ssh -f -N -v -t -L 5433:target_host:5432 user@jump_server
  • target_host is the host/database_server/RDS that you want to access that only can be accessed from jump _server or bastion if you’re using AWS
  • jump_server is the host that accessible from you and the only host that can access target_host
  • 5432 is local port (postgresql default)
  • 5433 is the forwarded host/database_server/RDS port that you can access through localhost
    What’s next?

    Afterwards, you should be able to get postgresql open with forwarded port through localhost (5433).

    Test the forwarded port using telnet:

    $ telnet localhost 5433
    

    or using netcat:

    $ nc -vz localhost 5433
    

SSH tunneling to your secured server through bastion/jump server with forwarded port

This is a quick guide will show you how to open ssh tunnel to ssh into your target server that can only be accessed from jump server. So this is how to do it:

ssh -v -t -L 10443:localhost:20443 <jump_server> ssh -t -L 20443:localhost:443 user@<target_server>
  • jump_server is the host that accessible from you and the only host that can access target_server
  • target_server is the host that you want to access that only can be accessed from jump _server or bastion if you’re using AWS
  • 10443 is the forwarded port that you can access to SSH to target_server

So, here is the example:

ssh -v -t -L 10443:localhost:20443 123.456.1.1 ssh -t -L 20443:localhost:443 user@10.1.1.1
  • 123.456.1.1 is my jump_server that I can only access to access target_server
  • 10.1.1.1 is the target_server

And try it out, see the magic for yourself! after the last command above executed, you will inside your target_server and 10443 port is open from your localhost.

target_server~$

If you want to just have your SSH session running in background and you want to SSH it by yourself, just try this command:

ssh -f -N -v -t -L 10443:localhost:20443 123.456.1.1 ssh -t -L 20443:localhost:443 user@10.1.1.1

if you want to remove the logs (disable verbose mode) when you logging in, just remove the “-v”

SSH to localhost with port 10443, to access your target_server

$ ssh localhost 10443

Magic!