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!

    Filed in: Terraform, Docker, Linux, Storage
    Reading Time: 3 minute(s)