Skip to main content

· 2 min read

How do we know if we can run terraform apply to our infrastructure without negatively affecting critical business applications? We can run terraform validate and terraform plan to check our configuration, but will that be enough? Whether we've updated some HashiCorp Terraform configuration or a new version of a module, we want to catch errors quickly before we apply any changes to production infrastructure.

In this post, We will discuss some testing strategies for HashiCorp Terraform configuration and modules so that we can terraform apply with greater confidence.

The Testing Pyramid

In theory, we might decide to align our infrastructure testing strategy with the test pyramid, which groups tests by type, scope, and granularity. The testing pyramid suggests that we write fewer tests in the categories at the top of the pyramid, and more at the bottom. Those on the pyramid take more time to run and cost more due to the higher number of resources we have to configure and create.

Error loading pyramid.png

In reality, our tests may not perfectly align with the pyramid shape. The pyramid offers a common framework to describe what scope a test can cover to verify configuration and infrastructure resources. We'll start at the bottom of the pyramid with unit tests and work the way up the pyramid to end-to-end tests.

note

hashistack does not merit any manual testing; so it is not discussed here

Linting and Formatting

While not on the test pyramid, we often encounter tests to verify the hygiene of your Terraform configuration. Use terraform fmt -check and terraform validate to format and validate the correctness of our Terraform configuration.

When we collaborate on Terraform, we may consider testing the Terraform configuration for a set of standards and best practices. Build or use a linting tool to analyze our Terraform configuration for specific best practices and patterns. For example, a linter can verify that our teammate defines a Terraform variable for an instance type instead of hard-coding the value.

Unit Tests

At the bottom of the pyramid, unit tests verify individual resources and configurations for expected values. They should answer the question, “Does my configuration or plan contain the correct metadata?” Traditionally, unit tests should run independently, without external resources or API calls.

· 2 min read
Jiaqi Liu

Overview

Being a strong proponent of Immutable Infrastructure, [hashistack] is constantly pushing the limits of its ability in various use cases, one of which is the Configuration Management

Traditional configuration management includes Chef, Puppet, and Ansible. They all assume mutable infrastructure being present. For example, Chef has a major component responsible for jumping into a VM, checking if config has been mutated before apply any operations.

With the adoption of Immutable infrastructure, we initially stored and managed our configuration, such as SSL certificate or AWS SECRET ACCESS KEY directly in GitHub Secrets. This has the disadvantage of not being able to see their values after creation, making it very hard to manage.

Then we moved to a centralized runbook, where everything can easily be seen and modified by authorized team members. In this approache, CI/CD server will pull down the entire runbook and simply pick up the config files. This, however, exposed a great security risk because illegal usage could simply leak any credentials to public by cating that credential file out

So the problem, or what [hashistack] is trying to solve here, is

  • being able to keep credentials, whether it's string values or values stored in files, secure, and
  • allowing team member to easily manage those credentials
note

We tried HashiCorp Vault but it doesn't support storing file credential, [hashistack] addressed exactly how file can be managed in this case

So this brought us to the alternative way of thinking about Configuration Management in Immutable Infrastructure, which is depicted below:

We still need GitHub Secrets because our tech dev has a deep integratin with it and that's the most secure way to pass our organization credentials around.

In addition, we will also keep runbook for config management. The runbook will be hosted separately, not in GitHub Secrets.

info

Runbooks was used in Yahoo that keeps all DevOps credentials in a dedicated GitHub private repo. It's been proven to be an effective way to manage and share a software configurations within a team.

hashistack's github-secret now comes into play to bridge the gap between two componet.

· 5 min read
Jiaqi Liu

OpenSSL is a powerful cryptography toolkit. Many of us have already used OpenSSL for creating RSA Private Keys or CSR (Certificate Signing Request). However, did you know that we can use OpenSSL to benchmark our computer speed or that we can also encrypt files or messages? This post will provide you with some simple to follow tips on how to encrypt messages and files using OpenSSL.

· 3 min read
Jiaqi Liu

Node Version Manager is a tool that helps us manage Node versions and is a convenient way to install Node. Think of it as npm or Yarn that helps manage Node packages, but instead of packages, NVM manages Node versions.

This also means you can install multiple Node versions onto your machine at the same time and switch among them if needed.

· 45 min read
Jiaqi Liu

Jenkins is an open-source automation server that integrates with a number of AWS Services, including: AWS CodeCommit, AWS CodeDeploy, Amazon EC2 Spot, and Amazon EC2 Fleet. We can use Amazon Elastic Compute Cloud (Amazon EC2) to deploy a Jenkins application on AWS.

This post documents the process of deploying a Jenkins application. We will launch an EC2 instance, install Jenkins on that instance, and configure Jenkins to automatically spin up Jenkins agents if build abilities need to be augmented on the instance.