Terraform Container NAS

Terraform

Following up from my recent post on a NAS device I had built and used for Linux containers, I had built using a Synology NAS. I have since added more memory to the device, maxing out the memory that the vendor supported 16GB. I have seen unsupported configuration with 20GB on the internet, I have not ventured into this area yet.

I have also migrated what resources and containers I had in Docker to be managed by Terraform, HashiCorp’s Infrastructure as Code (IaC) tool. Which was a lot of re-creating of what I already had created, Docker volumes, images, and containers.

I backed up current volume data to restore. Grafana and InfluxDB. Now all Docker resources are done through Terraform configuration and kept in source repository.

With the secure endpoint setup in the previous post, we can use it to configure docker Terraform provider to help manage your docker resources, keeping the configuration in repository

terraform {
  # Providers
  required_providers {
    docker = {
      source = "kreuzwerker/docker"
      version = "2.11.0"
    }
  }
}

# Configure the Docker provider
provider "docker" {
  host = "tcp://phong.hq.cormier.co:2376"

  # Certificates
  cert_path = pathexpand("~/.docker")

  registry_auth {
    address = "registry.hub.docker.com"
    username = "rancorm"
    password = "X"
  }
}

A simple docker resource can be declared by use the resource keyword. This is a simple InfluxDB Telegraf agent container resource.

This resource entry creates a new Docker container using the latest telegraf image, two file volumes for private CA certificate and telegraf.conf file, and some advanced networking.

Container resource

# Enzo - Telegraf Agent
resource "docker_container" "enzo" {
  image = docker_image.telegraf.latest
  name  = "enzo"
  hostname = "enzo.hq.cormier.co"

  # Enable db log driver
  log_driver = "db"

  volumes {
    host_path = "/volume1/docker/Cormier_HQ_CA.pem"
    container_path = "/etc/ssl/certs/Cormier_HQ_CA.pem"
    read_only = true
  }

  volumes {
    host_path = var.enzo_volume_config
    container_path = "/etc/telegraf/telegraf.conf"
    read_only = true
  }

   networks_advanced {
     name = docker_network.lan.name
     ipv4_address = "10.0.80.4"
   }
}

Image resouce with pull trigger to update to latest version when digest changes.

# Image
resource "docker_image" "telegraf" {
  name = data.docker_registry_image.telegraf.name
  pull_triggers = [data.docker_registry_image.telegraf.sha256_digest]
}

Network for dedicated network

# Network
resource "docker_network" "lan" {
  name = "lan"

  ipam_config {
    subnet = "10.0.80.0/24"
    gateway = "10.0.80.1"
  }
}

Docker Hub registry image

data "docker_registry_image" "telegraf" {
  name = "telegraf:latest"
}

If you would like to interface with your NAS container endpoint using the docker command line tools. You can set the proper environment variables.

export DOCKER_HOST=tcp://phong.hq.cormier.co:2376 DOCKER_TLS_VERIFY=1

Quick check of the docker version running on the device should let you know if the communication is working properly.

 ~/Projects/myinfra/ [master*] docker version
Client: Docker Engine - Community
 Cloud integration: 1.0.9
 Version:           20.10.5
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        55c4c88
 Built:             Tue Mar  2 20:13:00 2021
 OS/Arch:           darwin/amd64
 Context:           default
 Experimental:      true

Run terraform plan to see what changes will be made and terraform apply to make those changes.

Stay safe!
Apr 10, 2021 - Filed in: Terraform Docker Linux Storage
Words: 500