├── deploy ├── requirements.yml ├── data.tf ├── playbook.yml └── main.tf ├── run.sh ├── .gitignore ├── README.md ├── gen_env.sh └── Dockerfile /deploy/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: geerlingguy.nginx -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker exec -it hashiconf-demo /bin/bash -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | docker_env 2 | deploy/.terraform* 3 | deploy/terraform.tfstate* 4 | deploy/cert/* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hashiconf Demo 2 | 3 | ## Instructions 4 | 5 | 1. Edit `main.tf` with your appropriate local values 6 | 2. Run `gen_env.sh` to create your `docker_env` file 7 | 3. Run `build.sh` to spin up the docker container 8 | 4. Run `run.sh` to enter the container 9 | 5. (in docker) `terraform init` 10 | 6. (in docker) `terraform plan` 11 | -------------------------------------------------------------------------------- /gen_env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Remove the docker_env file if it exists 4 | [ -e docker_env ] && rm docker_env 5 | 6 | # These are the environment vars we want to pull into Docker 7 | env_vars=("VAULT_TOKEN" "VAULT_ADDR" "VAULT_SKIP_VERIFY" "VSPHERE_SERVER" "VSPHERE_PASSWORD" "VSPHERE_USER") 8 | 9 | echo "ANSIBLE_HOST_KEY_CHECKING=False" >> docker_env 10 | 11 | # Loop through the vars and add them to the docker_env file 12 | for var in ${env_vars[@]}; do 13 | echo "$var=${!var}" >> docker_env 14 | done -------------------------------------------------------------------------------- /deploy/data.tf: -------------------------------------------------------------------------------- 1 | data "vsphere_datacenter" "dc" { 2 | name = "Winghaven Cyber Range" 3 | } 4 | 5 | data "vsphere_datastore" "datastore" { 6 | name = local.datastore 7 | datacenter_id = data.vsphere_datacenter.dc.id 8 | } 9 | 10 | data "vsphere_compute_cluster" "cluster" { 11 | name = local.cluster 12 | datacenter_id = data.vsphere_datacenter.dc.id 13 | } 14 | 15 | data "vsphere_network" "network" { 16 | name = local.network 17 | datacenter_id = data.vsphere_datacenter.dc.id 18 | } 19 | 20 | data "vsphere_virtual_machine" "template" { 21 | name = local.template_path 22 | datacenter_id = data.vsphere_datacenter.dc.id 23 | } 24 | 25 | -------------------------------------------------------------------------------- /deploy/playbook.yml: -------------------------------------------------------------------------------- 1 | - hosts: all 2 | vars: 3 | nginx_remove_default_vhost: true 4 | nginx_vhosts: 5 | - listen: "80" 6 | server_name: "_" 7 | return: "301 https://$host$request_uri" 8 | filename: "nginx.cyber.range.80.conf" 9 | - listen: "443 ssl http2" 10 | server_name: "_" 11 | state: "present" 12 | template: "{{ nginx_vhost_template }}" 13 | filename: "nginx.cyber.range.conf" 14 | root: "/var/www/hashiconf" 15 | index: "index.html" 16 | extra_parameters: | 17 | ssl_certificate "/etc/ssl/cert/public.crt"; 18 | ssl_certificate_key "/etc/ssl/private/private.key"; 19 | ssl_protocols TLSv1.1 TLSv1.2; 20 | ssl_ciphers HIGH:!aNULL:!MD5; 21 | tasks: 22 | - name: Ensure ssl folders exist 23 | file: 24 | path: /etc/ssl/cert 25 | state: directory 26 | 27 | - name: Copy public cert 28 | copy: 29 | src: cert/nginx-public.crt 30 | dest: /etc/ssl/cert/public.crt 31 | - name: Copy private key 32 | copy: 33 | src: cert/nginx-private.key 34 | dest: /etc/ssl/private/private.key 35 | - name: Ensure /var/www/ exists 36 | file: 37 | path: /var/www 38 | state: directory 39 | - name: clone repo 40 | git: 41 | repo: https://github.com/pezhore/hashiconf-demo-web.git 42 | dest: /var/www/hashiconf 43 | roles: 44 | - role: geerlingguy.nginx 45 | become: true 46 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ventx/alpine 2 | 3 | ARG VSPHERE_SERVER 4 | ARG VSPHERE_USER 5 | ARG VSPHERE_PASSWORD 6 | ARG VAULT_ADDR 7 | ARG VAULT_TOKEN 8 | ARG VAULT_TLS_SKIP_VERIFY 9 | ARG ANSIBLE_HOST_KEY_CHECKING 10 | 11 | ENV VSPHERE_SERVER=${VSPHERE_SERVER} 12 | ENV VSPHERE_USER=${VSPHERE_USER} 13 | ENV VSPHERE_PASSWORD=${VSPHERE_PASSWORD} 14 | ENV VAULT_ADDR=${VAULT_ADDR} 15 | ENV VAULT_TOKEN=${VAULT_TOKEN} 16 | ENV VAULT_TLS_SKIP_VERIFY=${VAULT_TLS_SKIP_VERIFY} 17 | ENV ANSIBLE_HOST_KEY_CHECKING=${ANSIBLE_HOST_KEY_CHECKING}} 18 | 19 | 20 | ENV TERRAFORM_VERSION 0.12.7 21 | ENV VSPHERE_SERVER=$ 22 | 23 | RUN set -eux \ 24 | && apk --update --no-cache add gcc libc6-compat git openssh-client python py-pip python3 sshpass && pip install awscli 25 | 26 | RUN set -eux && \ 27 | apk add --no-cache \ 28 | bc \ 29 | gcc \ 30 | libffi-dev \ 31 | make \ 32 | musl-dev \ 33 | openssl-dev \ 34 | python3 \ 35 | python3-dev 36 | 37 | RUN set -eux && \ 38 | pip3 install --no-cache-dir --no-compile ansible; \ 39 | find /usr/lib/ -name '__pycache__' -print0 | xargs -0 -n1 rm -rf \ 40 | && find /usr/lib/ -name '*.pyc' -print0 | xargs -0 -n1 rm -rf 41 | 42 | RUN set -eux && \ 43 | cd /usr/local/bin && \ 44 | curl https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip -o terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \ 45 | unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \ 46 | rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip 47 | 48 | WORKDIR /work 49 | 50 | CMD ["/bin/bash"] -------------------------------------------------------------------------------- /deploy/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.12" 3 | } 4 | 5 | provider "vsphere" { 6 | # If you have a self-signed cert 7 | allow_unverified_ssl = true 8 | } 9 | 10 | locals { 11 | name = "nginx.cyber.range" 12 | hostname = "nginx" 13 | domain = "cyber.range" 14 | nameservers = ["172.16.0.20", "172.16.0.19"] 15 | dns_suffix_list = ["cyber.range"] 16 | ipaddress = "172.16.1.45" 17 | netmask = 16 18 | gateway = "172.16.0.1" 19 | provisioning_username = "range" 20 | provisioning_password = "range" 21 | datastore = "Range Storage 1" 22 | cluster = "Turing" 23 | network = "Range Management" 24 | template_path = "Templates/ubuntu-server-1804-3-template" 25 | } 26 | 27 | resource "vault_pki_secret_backend_cert" "nginx" { 28 | backend = "pki_int" 29 | name = "cyber-dot-range" 30 | common_name = local.name 31 | ttl = "26280h" 32 | 33 | provisioner "local-exec" { 34 | when = destroy 35 | command = < cert/nginx-public.crt; 46 | echo '${self.ca_chain}' > cert/nginx-ca_chain.pem; 47 | echo '${self.private_key}' > cert/nginx-private.key 48 | EOT 49 | } 50 | } 51 | 52 | 53 | resource "vsphere_virtual_machine" "nginx" { 54 | depends_on = [vault_pki_secret_backend_cert.nginx] 55 | name = local.name 56 | resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id 57 | datastore_id = data.vsphere_datastore.datastore.id 58 | 59 | num_cpus = 2 60 | memory = 4096 61 | guest_id = data.vsphere_virtual_machine.template.guest_id 62 | 63 | scsi_type = data.vsphere_virtual_machine.template.scsi_type 64 | 65 | network_interface { 66 | network_id = data.vsphere_network.network.id 67 | } 68 | 69 | disk { 70 | label = "disk0" 71 | size = data.vsphere_virtual_machine.template.disks.0.size 72 | eagerly_scrub = data.vsphere_virtual_machine.template.disks.0.eagerly_scrub 73 | thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned 74 | } 75 | 76 | clone { 77 | template_uuid = data.vsphere_virtual_machine.template.id 78 | 79 | customize { 80 | dns_server_list = local.nameservers 81 | dns_suffix_list = local.dns_suffix_list 82 | linux_options { 83 | host_name = local.hostname 84 | domain = local.domain 85 | } 86 | 87 | network_interface { 88 | ipv4_address = local.ipaddress 89 | ipv4_netmask = local.netmask 90 | } 91 | 92 | ipv4_gateway = local.gateway 93 | } 94 | } 95 | 96 | provisioner "file" { 97 | when = create 98 | source = "cert" 99 | destination = "/tmp/tf" 100 | 101 | connection { 102 | type = "ssh" 103 | user = local.provisioning_username 104 | password = local.provisioning_password 105 | host = self.default_ip_address 106 | } 107 | } 108 | 109 | provisioner "local-exec" { 110 | when = create 111 | command = <