env0 – A Terraform Cloud Alternative

Have you ever wondered what other Terraform Cloud alternatives are out there? Check out env0. You will find very interesting features for a solid Infrastructure as Code platform for your organization. This post is sponsored by env0.

Video

Below is a video explanation and demo.

Video Chapters

In this video, we look at env0, an alternative to Terraform Cloud. We will build an AWS EC2 instance hosting a Jenkins Docker container. We will use env0’s custom flows to get Ansible and Terraform working together to achieve all of this.

You can skip to the relevant timestamps below:

  • 00:00 – Introduction
  • 01:49 – Why TACOS?
  • 04:42 – Demo – Structure Overview
  • 08:02 – Demo – Create a Template
  • 12:45 – Demo – RBAC
  • 15:03 – Demo – Run an Environment Deployment
  • 18:30 – Demo – Cost Estimation
  • 19:20 – Demo – Organization Settings
  • 22:05 – Demo – Custom Flows
  • 25:46 – Demo – Jenkins Deployed
  • 26:18 – Demo – TTL To Destroy Environment
  • 28:11 – Demo – env0.yml Configuration
  • 29:42 – Other env0 Features
  • 31:19 – Wrap-up
env0 - A Terraform Cloud Alternative
env0 – A Terraform Cloud Alternative

Overview

If you’ve reached a point at your organization where you’re looking to scale and standardize on Terraform, then you need to look beyond Terraform open-source.

Check out env0. It’s a solid Infrastructure as Code platform.

Below are the main features that you would want to look for beyond OSS:
– Scaling Terraform for Organizations
– Secure Remote State Management
– Secrets and Variables
– RBAC
– SSO
– Policy as Code for Governance
– Private Module Registry (Store Reusable Terraform Modules)
– Cost Estimation
– Automatic Drift Detection

env0 has these features and more. Follow along in this blog post to see a demo of the following:

  • Structure Overview (Organizations, Projects, Templates, Environments)
  • RBAC
  • Custom Workflow (Terraform + Ansible to build a Jenkins Container in an EC2 Instance)
  • Automatic Destruction of the Environment based on a TTL

Code

Pre-requisites

The following is required to follow along:

  • A free GitLab account
  • Access to an AWS account, we’ll be running within the 12 months free tier
  • A free env0 account

What we’ll build

In this post we will build an AWS EC2 instance with Terraform and use Ansible to install the docker engine in it and then run a Jenkins container. We will leverage envzero’s custom flows to get Terraform and Ansible to work together to build this for us.

This is a use case where we would like to quickly build a Jenkins machine for testing purposes and rely on env0 to destroy the machine automatically based on a time-to-live (TTL). This TTL is a welcomed feature that helps reduce cost in case we forget the machine on.

env0's custom flow to build our Jenkins Container in AWS with Terraform and Ansible
env0’s custom flow to build our Jenkins Container in AWS with Terraform and Ansible

Create a Template in env0

A template defines an environment that can be deployed. The same template can be used to launch multiple environments, under different projects. This is useful for a center of excellence or a DevOps team to create certain approved templates and developers are only allowed to use these templates. Developers don’t have the privilege to create templates. This is very helpful for self-serve models to speed up developer productivity while adhering to company governance and policies.

env0 Template Creation
env0 Template Creation

Notice how in the above image, env0 allows you to not only create Terraform templates, but also other Infrastructure as Code templates from other providers. This is a differentiator for envzero.

Also as expected, env0 follows gitOps principles and ties in with version control systems. In our example we’ve tied the template to GitLab. Another neat feature of env0 is it’s ability to load variables from the Terraform code itself so you don’t have to type the variables yourself. Below is a screenshot showing that:

Easy way to load variables from theTerraform code
Easy way to load variables from theTerraform code

Now go ahead and create a template. For details on how to create this template please refer to the demo video above.

Create an Environment

Now that you’ve created a template, it’s time to create a new environment based on this template. Go to Project Environments and click CREATE NEW ENVIRONMENT button. You’ll get the option to build it directly from VCS or from a template. Choose template.

Create an Environment from a Template
Create an Environment from a Template

This will take you to the Project Templates section where you can click Run Now to deploy the template.

Run the Template
Run the Template

RBAC and Slack Notifications

Once the developer, Sameh Gabrail, deploys the environment from the Jenkins Container in EC2 template we start getting Slack notifications. You can see these notifications in the screenshot below.

Slack Notifications Showing RBAC and Approvals
Slack Notifications Showing RBAC and Approvals

Notice how the deployment is waiting on approval. Sameh Gabrail has the planner role which doesn’t allow him to approve his own deployments. Sam Gabrail who is an admin approves this deployment. For more information on user roles in a project, refer to the documentation.

Also, notice the estimated cost change is +12.92$. Another great feature of env0 is it’s ability to not only estimate actual cost, but also to monitor cloud costs over time.

Our Custom Flow Explained

env0 allows different hooks at different phases of a Terraform run. This is very useful for integrations with third-party tools such as checkov for security or to integrate with Ansible as in our case. What you need is to define a file called env0.yml and place it in the root directory of your repo. Check the different hooks for terraform in the documentation.

Below is the folder structure:

Folder Structure
Folder Structure

env0.yml file:

version: 1
deploy:
  steps:
    terraformOutput:
      after:
        - terraform output -raw private_key > /tmp/myKey.pem
        - chmod 400 /tmp/myKey.pem
        - sed -i "s/<placeholder_app>/$(terraform output -raw public_ip)/g" Ansible/inventory
        - pip3 install --user ansible
        - ls -lah
        - cat Ansible/inventory
        - cd Ansible && ansible-playbook --private-key /tmp/myKey.pem -i inventory jenkinsPlaybook.yaml

Notice the env0.yml code above. This is where we get env0’s agent to grab the EC2 instance’s private key and place it in a myKey.pem file so that Ansible can later use it to access the instance. We also use sed to replace the <placeholder_app> with the terraform output for the EC2 instance’s public IP in Ansible’s inventory file.

Then we use pip to install ansible as it’s not available in the env0 agent. We then run ls and cat the inventory file to verify all is working, we can really omit these two lines. They are only helpful for troubleshooting.

Finally, we run the ansible-playbook from within the Ansible folder to run the jenkinsPlaybook playbook. You can check out the Ansible and Terraform code here.

Conclusion

In this post, we learned about env0 and how it is a great Terraform Cloud alternative.

We also saw how to use env0 to create custom flows that allow us to integrate Terraform with Ansible. Terraform helps with provisioning and Ansible helps with configuration management. The beauty of custom flows from env0 is that it allows us to build everything on env0 without having to rely on another CI/CD platform.

env0 has many other features that fill the gap for organizations looking to standardize on Terraform where Terraform OSS falls short. Check out these features under env0’s pricing plans.

References

Suggested Reading

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top