Today marks a big step for us here at Enclave Networks as we help DevOps practitioners using Terraform bring Zero Trust to their automated infrastructure.
We’ve officially released our Terraform provider for Enclave! 🚀
For those that don’t know, Terraform is a really popular way of automating infrastructure by defining the desired end-state of your servers, firewalls, services, networks, and so on, all from a set of YAML files.
With this Terraform Provider you’ll be able to configure Enrolment Keys, Policies, DNS Zones and DNS Records, all from your Terraform YAML files.
If you’d like to take a look at the docs, you can find them here.
First Steps
To start using the Enclave Terraform provider, you will need to:
- Set up your Enclave account (if you haven’t already); you can register here.
- Create a Personal Access Token from the account page in the Enclave portal
- Get your Org Id by going to the settings page here and copying your
Organisation ID
. You can find your Organisation ID in any portal URL e:ghttps://portal.enclave.io/org/<orgId>/systems
.
Simple Configuration
The example below will get you started; we recommend using a variable for the enclave-token
as this should remain secret.
Warning! Do not commit your Enclave Personal Access Token to your Source Control system. If you do so accidentally, you should go into your Enclave account and delete the token, then create a new one.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
terraform {
required_providers {
enclave = {
source = "enclave-networks/enclave"
}
}
}
variable "enclave_token" {
type = string
nullable = false
sensitive = true
}
provider "enclave" {
token = var.enclave_token
}
Configuring an AWS EC2 Instance
Let’s dive into a full example of how to set up an AWS EC2 Linux server via terraform, and automatically set up Enclave connectivity to it, while denying any access to it from the public internet.
First let’s setup our providers.
Here we’ll use the AWS Provider and the same Enclave provider config as above.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
terraform {
required_providers {
enclave = {
source = "enclave-networks/enclave"
}
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "eu-west-2"
}
variable "enclave_token" {
type = string
nullable = false
sensitive = true
}
provider "enclave" {
token = var.enclave_token
organisation_id = "<orgId>"
}
Now that’s all setup we can get onto the good stuff. We’re going to setup a simple policy
here for ssh access to our aws-ec2
instance from our developer
systems. As well as an enrolment key
which we will then pass over to the ec2
instance so it can be enrolled into our Enclave account.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
resource "enclave_policy_acl" "ssh" {
protocol = "tcp"
ports = "22"
}
resource "enclave_policy" "dev_to_ec2" {
description = "Developer to EC2"
sender_tags = ["developer"]
receiver_tags = ["aws-ec2"]
acl = [
enclave_policy_acl.ssh,
]
}
resource "enclave_enrolment_key" "aws" {
description = "AWS Enrolment"
approval_mode = "automatic"
tags = [
"aws-ec2"
]
}
Next, define a script to run to set up and enrol Enclave on the created EC2 box.
We’ll create a new file, scripts/rpm_install.sh.tpl
, and put the below content in there. We use a ${enclave_key}
variable that we’ll set in a moment.
1
2
3
4
5
6
7
#!/bin/bash
dnf -y install dnf-plugins-core
dnf config-manager --add-repo https://packages.enclave.io/rpm/enclave.repo
dnf install enclave -y --refresh
sudo enclave enrol ${enclave_key}
Then, we’ll bring this templated script into our terraform file. You can see that we’re specifying that the enclave_key
variable
should come from the enclave_enrolment_key.aws
resource we defined above.
1
2
3
4
5
6
7
data "template_file" "install_enclave_rpm" {
template = file("scripts/rpm_install.sh.tpl")
vars = {
enclave_key = "${enclave_enrolment_key.aws.key}"
}
}
The last bit of terraform to define is setting up your ec2 instance definition. This example uses an AMI provided by the team at Rocky Linux a distro that is bug-for-bug compatible with RHEL.
We specify our template file as user_data
for the EC2 instance, which runs our script when the instance launches.
In order to connect to this system over SSH you will need an AWS Keypair you have access to, and then specify the name in the instance.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
data "aws_ami" "rocky_linux" {
most_recent = true
filter {
name = "name"
values = ["Rocky-8-ec2-8.6-20220515.0.x86_64"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["792107900819"]
}
resource "aws_instance" "rocky_server_1" {
ami = data.aws_ami.rocky_linux.id
instance_type = "t2.micro"
# Specify the name of a configured keypair in your AWS region.
key_name = "<your-key-pair-name>"
# If you set up a Managed NAT gateway for your AWS subnet, it
# won't need a public IP address.
# associate_public_ip_address = "false"
user_data = data.template_file.install_enclave_rpm.rendered
tags = {
Name = "TerraformTestInstance1"
}
}
Finally, tag your local Enclave system with the developer
tag, and run terraform apply
.
Once EC2 has finished setting up the instance (it can take a minute or two), you should automatically get SSH connectivity to the EC2 system, but without that system being visible to anyone else on the internet!
Closing
We’d love to hear from you on how you use Enclave with Terraform and if you have any comments, suggestions or issues we’d love to hear from you over on the provider’s github repository!
One last little tidbit, as part of this work we’ve also released a Go Module for our Enclave Api which can be found here.