rs-nomad 0.16.0

This crate provides access to a set of strongly typed apis to interact with nomad (https://www.nomadproject.io/)
Documentation
# WARNING: Do not attempt to use any docker volume mounts (=binding directories/files from the host into a container here). That will work fine on your local machine, but will fail in CircleCI
#          because it provisions a separate EC2 machine to run the docker/docker-compose environment on. The alternative is to add a Dockerfile which does nothing but copy over the files that
#          you require. See docker-utils/consul for an example.
version: "3"

services:
  consul:
    build:
      context: docker-utils/consul/region-1
    container_name: consul
    command: "consul agent -dev -log-level=trace -dns-port=53 -recursor=8.8.8.8 -client=0.0.0.0 -enable-local-script-checks -config-file=/etc/roblox-consul/config.hcl -datacenter dc1 -node consul"
    environment:
      - CONSUL_ALLOW_PRIVILEGED_PORTS=
    ports:
      - "8500:8500"
      - "53:53/udp"
    expose:
      - "8500"
      - 53/udp
    restart: always
    networks:
      persistence:
        # Give Consul a static IP (just any that's within the subnet mask assigned to the network) to allow for
        # other containers to use <this IP>:53 for DNS.
        ipv4_address: "172.16.238.99"
        aliases:
          - consul

  consul-2:
    build:
      context: docker-utils/consul/region-2
    container_name: consul-2
    command: "consul agent -dev -log-level=trace -dns-port=53 -recursor=8.8.8.8 -client=0.0.0.0 -enable-local-script-checks -config-file=/etc/roblox-consul/config.hcl -datacenter dc2 -node consul-2"
    environment:
      - CONSUL_ALLOW_PRIVILEGED_PORTS=
    ports:
      - "8501:8500"
    expose:
      - "8500"
      - 53/udp
    restart: always
    networks:
      persistence:
        # Give Consul a static IP (just any that's within the subnet mask assigned to the network) to allow for
        # other containers to use <this IP>:53 for DNS.
        ipv4_address: "172.16.238.101"
        aliases:
          - consul-2

  vault:
    container_name: vault
    image: hashicorp/vault:1.8.5
    environment:
      - VAULT_DEV_ROOT_TOKEN_ID=myroot
      - |
        VAULT_LOCAL_CONFIG=
        { "backend": { "inmem": {} } }
    ports:
      - "8200:8200"
    expose:
      - "8200"
    cap_add:
      - IPC_LOCK
    restart: always
    networks:
      persistence:
        aliases:
          - vault

  # Second vault container used to simulate MR EaaS
  vault-2:
    container_name: vault-2
    image: hashicorp/vault:1.8.5
    environment:
      - VAULT_DEV_ROOT_TOKEN_ID=myroot
      - |
        VAULT_LOCAL_CONFIG=
        { "backend": { "inmem": {} } }
    ports:
      - "8201:8200"
    expose:
      - "8200"
    cap_add:
      - IPC_LOCK
    restart: always
    networks:
      persistence:
        aliases:
          - vault-2

  nomad:
    container_name: nomad
    image: multani/nomad:1.6.2
    command: agent -dev
    privileged: true
    environment:
      NOMAD_DATA_DIR: /tmp/nomad
      NOMAD_LOCAL_CONFIG: |
        datacenter = "dc1"
        region     = "us-central"
        log_level  = "DEBUG"
        bind_addr  = "0.0.0.0"
        consul {
          address  = "consul:8500"
        }
        advertise {
          http = "{{ GetPrivateIP }}:4646"
          rpc  = "{{ GetPrivateIP }}:4647"
          serf = "{{ GetPrivateIP }}:4648"
        }
        client {
          reserved {
            # Only use ports 20001-20999 for tasks that we schedule. This is done to prevent conflicts
            # with tasks scheduled by any of the other nomad clients.
            reserved_ports = "1-20000,21000-65535"
          }
          # As per production config: https://github.com/Roblox/rblx_policyfiles/blob/0c5166962da77deaca4f4edefe202c2f8b41abbf/policy_roles/nomad-client.rb#L91
          meta {
            storage = "local"
            rack    = "AE20"
            pod     = "Pod0"
          }
        }
        telemetry {
          disable_hostname           = true
          datadog_address            = "telegraf:8125"
          prometheus_metrics         = true
          publish_allocation_metrics = true
          publish_node_metrics       = true
        }
        vault {
          enabled               = true
          address               = "http://vault:8200"
          # This is the root token defined in the Vault container
          token                 = "myroot"
          allow_unauthenticated = "false"
        }
        acl {
          enabled = true
        }
    ports:
      - "4646:4646"
    expose:
      - 4646
      - 4647
      - 4648
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:rw
      - /tmp:/tmp
      - /tmp/nomad:/tmp/nomad
    depends_on:
      - telegraf
      - consul
    restart: always
    networks:
      persistence:
        aliases:
          - nomad

  nomad-2:
    container_name: nomad-2
    image: multani/nomad:1.6.2
    command: agent -dev
    privileged: true
    environment:
      NOMAD_DATA_DIR: /tmp/nomad
      NOMAD_LOCAL_CONFIG: |
        datacenter = "dc2"
        region     = "us-east"
        log_level  = "DEBUG"
        bind_addr  = "0.0.0.0"
        consul {
          address  = "consul-2:8500"
        }
        advertise {
          http = "{{ GetPrivateIP }}:4646"
          rpc  = "{{ GetPrivateIP }}:4647"
          serf = "{{ GetPrivateIP }}:4648"
        }
        client {
          reserved {
            # Only use ports 20001-20999 for tasks that we schedule. This is done to prevent conflicts
            # with tasks scheduled by any of the other nomad clients.
            reserved_ports = "1-20000,21000-65535"
          }
          # As per production config: https://github.com/Roblox/rblx_policyfiles/blob/0c5166962da77deaca4f4edefe202c2f8b41abbf/policy_roles/nomad-client.rb#L91
          meta {
            storage = "local"
            rack    = "AE20"
            pod     = "Pod0"
          }
        }
        telemetry {
          disable_hostname           = true
          datadog_address            = "telegraf:8125"
          prometheus_metrics         = true
          publish_allocation_metrics = true
          publish_node_metrics       = true
        }
        vault {
          enabled               = true
          address               = "http://vault-2:8200"
          # This is the root token defined in the Vault container
          token                 = "myroot"
          allow_unauthenticated = "false"
        }
        acl {
          enabled = true
        }
    ports:
      - "4647:4646"
    expose:
      - 4646
      - 4647
      - 4648
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:rw
      - /tmp:/tmp
      - /tmp/nomad:/tmp/nomad
    depends_on:
      - telegraf
      - consul-2
    restart: always
    networks:
      persistence:
        aliases:
          - nomad-2


  # Ideally telegraf would be part of the "monitoring" profile that we use to disable a subset of components
  # in local development but it currently is a hard dependency for Nomad and hence we can't omit it.
  telegraf:
    build:
      context: docker-utils/telegraf
    container_name: telegraf
    expose:
      - 8125/udp # StatsD input
      - "9126"
    ports:
      - "8125:8125/udp"
      - "9126:9126"
    restart: always
    networks:
      persistence:
        aliases:
          - telegraf

 
  redis-cluster:
    container_name: redis-cluster
    # versions: https://grafana.simulprod.com/d/redis-control-plane/redis-as-a-service-control-plane?viewPanel=14
    image: grokzen/redis-cluster:6.0.8
    environment:
      - IP # put IP=0.0.0.0 in .env file to run tests locally
      # This defaults to 7000 which is a reserved port on MacOS Montery. https://developer.apple.com/forums/thread/682332
      - INITIAL_PORT=9000
    ports:
      - 9000-9005:9000-9005
    networks:
      - persistence
    restart: always

networks:
  persistence:
    name: persistence
    external: true