Integrate BIG-IP policy management into CI/CD pipeline using Terraform and GitHub Actions

AS3 (Application Services 3) is a part of F5 Automation Toolchain which provides a flexible, low overhead mechanism for managing configurations on a BIG-IP device. In this blog, I will show you how to integrate your security and network policy management into your CICD pipelines using AS3, Terraform, GitHub Actions.

With Terraform and GitHub Actions, you can enable continuous integration and deployment practices to automate, test and deploy BIG-IP configurations as part of a pipeline.

Environment Setup

In the rest of this blog, we will go over how to create a sample workflow using GitHub Actions and Terraform. This workflow will be used to deploy an AS3 template which contains WAF (ASM) policy that will protect the backend application from any attacks.

Prerequisite

·     BIG-IP device with AS3 rpm installed and ASM enabled.

·     Backend application instance

·     GitHub account

·     AWS account

·     Local instance of Terraform installed and running (I am using Terraform version 0.14.7)

·     Terraform Cloud account

 

Setting up local CLI for Terraform Cloud

Sign in into Terraform cloud at https://www.terraform.io/

Click on Create a New workspace, select CLI (Command Line Interface) Driven Workspace and assign your workspace a name – e.g., ‘bigip-ci’

Leave the browser window and go to your terminal to clone the ‘f5devcentral/bigip-ci.git’ repository.

 

git clone https://github.com/f5devcentral/bigip-ci.git
cd bigip-ci
terraform login

 

When prompted, say ‘YES’ to proceed. This will open a new browser window where you will be asked to Create API token as shown. Give a name for your token and click ‘create API token’.


Copy the token you created and paste it into your terminal window. Your terminal will be waiting for input as shown.

Token for app.terraform.io:
Enter a value: <your token>

Set up GitHub environment to access AWS and Terraform Cloud

Go to https://github.com/<yourusername>/bigip-ci/settings/secrets/actions and create the secrets as shown below, also update the TF_API_TOKEN which you have created before

 

Enter all the secrets as shown above in your GitHub repo - AWS Secrets Key and Key ID, also update ASW_SESSION_TOKEN if you are using it.

Add your infrastructure details in Terraform cloud

On the Terraform Cloud, under the Workspace bigip-ci update the terraform variables listed below.

BIG-IP variables - address, port, username, password.  Variable deployWAF is the AS3 configuration file that has a WAF policy referenced. You can customize this to meet your requirements.

 

Before proceeding, review the main.tf and deployWAF.json and customize it as per your deployment.

cat main.tf 
terraform {
 required_providers {
  bigip = {
   source = "F5Networks/bigip"
   version = "1.4.0"
  }
 }
 backend "remote" {
  organization = "SCStest"
  workspaces {
   name = "bigip-ci"
  }
 }
}
provider "aws" {
 region = "us-west-2"
}
provider "bigip" {
 address = "https://${var.address}:${var.port}"
 username = var.username
 password = var.password
}

# deploy application using as3
resource "bigip_as3" "DeployApp" {
 as3_json = file(var.deployWAF)
}

 

Testing the CI workflow

Our environment is now setup such that the Actions workflow gets trigged when there is a PULL REQUEST to the MASTER branch. Let’s test it out by committing a minor change. On the terminal execute:

# check you are pointing to which branch
git status
#  checkout to the dev branch
git checkout dev. 
# add the changed files to gitHub, this will be your main.tf and deployWAF.json 
git add .
git commit -m "deployWAF"
# push the files to  dev branch
git push

 

Create a pull request, merge to master to trigger the Actions Workflow

 

 

Merge the pull request:

 

Click on the ‘Actions’ tab in your GitHub repo to see the trigged workflow as shown below:

 

 

When you click on the workflow, you can see the summary of jobs that are executed. A green check means the run was successful.

 

The GitHub Actions Workflow

The above merge of the Pull Request executed the sample workflow at .github/workflow/bigip-ci.yml. As shown below, the workflow has various ‘event definitions’ and ‘jobs’. In this case the event is on pull_request, and the jobs are terraform runs. The jobs listed in this workflow are: Setup Terraform, Terraform Init, Terraform Plan and Terraform Apply.

name: "bigip_waf"

on:
  push:
    branches:
      - master
  pull_request:

jobs:
  terraform:
    name: "Terraform"
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v1
        with:
          # terraform_version: 0.13.0:
          cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}

      - name: Terraform Init
        id: init
        run: terraform init

      - name: Terraform Plan
        id: plan
        if: github.event_name == 'pull_request'
        run: terraform plan -no-color
        continue-on-error: true

      - uses: actions/github-script@0.9.0
        if: github.event_name == 'pull_request'
        env:
          PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\`
            #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\`
            #### Terraform Plan 📖\`${{ steps.plan.outcome }}\`

            <details><summary>Show Plan</summary>

            \`\`\`${process.env.PLAN}\`\`\`

            </details>

            *Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`;

              
            github.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: output
            })

      - name: Terraform Plan Status
        if: steps.plan.outcome == 'failure'
        run: exit 1

      - name: Terraform Apply
        if: github.ref == 'refs/heads/master' && github.event_name == 'push'
        run: terraform apply -auto-approve

 

Conclusion:

BIG-IP policy management can be very easily included into your CI/CD pipelines. You can use any tools such as Jenkins, GitHub actions etc. I showed how to use GitHub Actions workflow and Terraform cloud for my setup. You can use this in your environment using the same workflow, and by changing the terraform file depending upon your BIG-IP configurations. Using similar concepts, you can test BIG-IP configurations in every state of the application delivery lifecycle – development, staging as well as in production. I hope this is helpful. Please share your thoughts and comments below.

Published Mar 09, 2021
Version 1.0

Was this article helpful?

No CommentsBe the first to comment