Skip to content

Instantly share code, notes, and snippets.

@unRob
Created May 29, 2020 04:17
Show Gist options
  • Save unRob/58043ac2189f0da3943469c438416deb to your computer and use it in GitHub Desktop.
Save unRob/58043ac2189f0da3943469c438416deb to your computer and use it in GitHub Desktop.
gcy + jq + bash cookbook Raw

gcy, bash and jq Cookbook

Terraform

# ./config.yml
nodes:
  zero:
    neither: {}
  one:
    consul: {}
    vault: {}
  two:
    consul: {}
    vault: {}
  three:
    vault: {}
  four:
    consul: {}
#!/usr/local/bin bash
# config.sh

config="${CONFIG_FILE:-./config.yml}"

set -o nounset
property="$1"
filter="$2"
if [[ "$#" == 3 ]]; then
  config="$1"
  property="$2"
  filter="$3"
fi

echo "filtering .$property of $config" >/dev/stderr
jq "{ data: ( ($filter) | @json) }" <(gcy get "$config" "$property")
# main.tf
data external nodes {
  # project the config data using jq filters
  program = ["./config.sh", "./config.yml", "nodes", <<-JQ
  {
    consul: ([ to_entries[] | select( .value | has("consul") ) | .key ]),
    vault: ([ to_entries[] | select( .value | has("vault") ) | .key ]),
    either: ([
      to_entries[] | select( .value | (has("vault") or has("consul")) ) | .key
    ])
  }
  JQ
  ]
}

locals {
  nodes = jsondecode(data.external.nodes.result.data)
}

// local.nodes.consul = ["one", "two", "four"]
// local.nodes.vault  = ["one", "two", "three"]
// local.nodes.either = ["one, "two", "three", "four"]

Ansible Inventory

This is a simplification of how I do ansible at home

# ./config.yml
dns:
  zone: my.ansible-managed.tld
consul:
  initial_token: "d34db33f"
vault:
  port: 1337
nomad:
  plugins: [raw_exec, docker, mock]
nodes:
  zero:
    dns:
      enabled: true
    platform: edegeos
    reachability: gateway
  one:
    consul: {}
    vault: {}
    platform: linux
    reachability: public
  two:
    consul: {}
    vault: {}
    platform: macos
    reachability: public
  three:
    dns:
      enabled: true
    vault: {}
    platform: linux
    reachability: public
  four:
    dns:
      enabled: true
    consul: {}
    platform: linux
    reachability: public
. as $data |
def store_this_as: "bin/inventory.jq";
def nodes: $data | .nodes;
def nodes(query): nodes | query;
def global(query): $data | query;

def filter(query):
  nodes(with_entries(select(.value | query)));
def filter(query; rdc):
  filter(query) | rdc;

def names(query):
  filter(query; keys);

def address_pairs(query):
  filter(query; to_entries | map({ name: .key, address: .value.address }));
def address_pairs(query; srt):
  filter(query; to_entries | sort_by(.value | srt) | map({ name: .key, address: .value.address }));

def addresses(query):
  address_pairs(query) | map(.address);
def addresses(query; srt):
  address_pairs(query; srt) | map(.address);

def node_tags($prop):
  nodes |
  to_entries |
  reduce .[] as $n ({}; . * {
      ($n.value[$prop]): ((.[$n.value[$prop]] // []) + [$n.key])
    }
  ) |
  to_entries |
  map({
    ($prop+"_"+(.key | gsub("\\W"; "_"))): { hosts: .value }
  }) |
  add;

{
  _meta: {
    hostvars: nodes(with_entries({
      key: .key,
      value: ({node: .value} + .value._ansible)
    }))
  },
  all: {
    hosts: nodes(keys),
    vars: {
      config: {
        consul: global(.consul),
        dns_servers: addresses(.dns.enabled; .dns.mode != "leader"),
        dns: global(.dns),
        nomad: global(.nomad),
        vault: global(.vault),
      }
    }
  },
  consul_server: {
    hosts: names(.consul)
  },
  nomad_server: {
    hosts: names(.nomad)
  },
  vault_server: {
    hosts: names(.vault)
  },
  ungrouped: {
    children: []
  }
}
* node_tags("reachability")
* node_tags("platform")
#!/usr/bin/env bash
# bin/inventory.ini
case $1 in
  --list)
    # continue
    ;;
  --host)
    echo "{}"
    exit 0
    ;;
  *)
    >&2 echo "unknown args: $*"
    exit 2
esac

CONFIG_FILE="${CONFIG_FILE:-../config.yml}"
SRC_DIR="${BASH_SOURCE%/*}"
jq -f "${SRC_DIR}/inventory.jq" <(gcy get "$CONFIG_FILE" ".")
# playbook.yml

- hosts: reachability_gateway
  gather_facts: no
  roles:
    - gateway
    - coredns
    - wireguard

- hosts: platform_macos
  roles:
    - server-users

- hosts: consul_server
  roles:
    - consul-server

- hosts: vault_server
  roles:
    - vault-server

- hosts: nomad_server
  roles:
    - nomad-server

- hosts: all
  tasks:
    - name: Do stuff with config
      debug: 
        msg: "your password is {{ config.consul.initial_token }}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment