diff options
Diffstat (limited to 'example')
36 files changed, 1182 insertions, 7 deletions
diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..c6f6ac8 --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,10 @@ +../acme/.terraform +terraform.d +*.tfstate +*.tfstate.backup +plan + +.vault-password* +*.dot +*.png +.ninja_log diff --git a/example/.settings.sh b/example/.settings.sh new file mode 100644 index 0000000..7bd49fb --- /dev/null +++ b/example/.settings.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +basedir=$(dirname "$_") +basedir=$(cd "$basedir" && pwd) + +#echo "Adding tools/ to path" +#PATH="$basedir/tools:$PATH" + +alias terraform="TF_VAR_ansible_vault_pass=\$($(pwd)/.vault-password) $(pwd)/.terraform/bin/terraform" diff --git a/example/Makefile b/example/Makefile new file mode 100644 index 0000000..39d54a6 --- /dev/null +++ b/example/Makefile @@ -0,0 +1,41 @@ +terraform_version=0.14.4 +terraform_url=https://releases.hashicorp.com/terraform/$(terraform_version)/terraform_$(terraform_version)_linux_amd64.zip +terraform_unzip=.terraform/unzip/$(terraform_version)/ +terraform_zip=.terraform/zip/terraform_$(terraform_version)_linux_amd64.zip +terraform_bin=.terraform/bin/terraform + +ansiblevault_version=2.0.1 +ansiblevault_url=https://github.com/MeilleursAgents/terraform-provider-ansiblevault/releases/download/v$(ansiblevault_version)/terraform-provider-ansiblevault_linux_amd64_v$(ansiblevault_version) +ansiblevault_path=terraform.d/plugins/linux_amd64/terraform-provider-ansiblevault_v$(ansiblevault_version)_x4 + +all: $(terraform_bin) $(ansiblevault_path) setup + +$(terraform_bin): $(terraform_zip) + rm -rf $(dir $(terraform_unzip)) + mkdir -p $(terraform_unzip) + mkdir -p $(dir $(terraform_bin)) + unzip $(terraform_zip) -d $(terraform_unzip) + ln -sf $(PWD)/$(terraform_unzip)/terraform $(terraform_bin) + touch $(PWD)/$(terraform_unzip)/terraform + +$(terraform_zip): + mkdir -p $(dir $@) + curl -L -o "$@" $(terraform_url) + +$(ansiblevault_path): terraform.d + mkdir -p $(dir $@) + curl -L -o "$@" $(ansiblevault_url) + chmod +x $(@) + +terraform.d: + mkdir $@ + +MAIN=$(patsubst %/main.tf,%,$(wildcard */main.tf)) +setup: $(patsubst %,%/terraform.d,$(MAIN)) +.PHONY: setup + +%/terraform.d: terraform.d + ln -s ../terraform.d $@ + +.terraform/plugins/linux_amd64: + mkdir -p $@ diff --git a/example/acme-apps/ansible/dba/acme-myapp-ci.yml b/example/acme-apps/ansible/dba/acme-myapp-ci.yml new file mode 100644 index 0000000..e73360d --- /dev/null +++ b/example/acme-apps/ansible/dba/acme-myapp-ci.yml @@ -0,0 +1,37 @@ +# Generated + +# cluster: +--- +- host: + - acme-2 + tasks: + import_role: + name: docker-service + vars: + template: | + version: "3" + services: + mdb: + image: mongodb:3.2 + pdb: + image: postgresql:13 + +--- +- host: + - acme-1 + tasks: + import_role: + name: docker-service + vars: + template: | + version: "3" + services: + 4tune-api: + image: 4tune-api:development + 4tune-web: + image: 4tune-web:development + statera-console: + image: statera-console:development + statera: + image: statera:development + diff --git a/example/acme-apps/ansible/dba/acme-myapp-production.yml b/example/acme-apps/ansible/dba/acme-myapp-production.yml new file mode 100644 index 0000000..6b6bf6c --- /dev/null +++ b/example/acme-apps/ansible/dba/acme-myapp-production.yml @@ -0,0 +1,26 @@ +# Generated + +# cluster: +--- +- host: + - acme-3 + tasks: + import_role: + name: docker-service + vars: + template: | + version: "3" + services: + mdb: + image: mongodb:3.2 + pdb: + image: postgresql:13 + 4tune-api: + image: 4tune-api:master + 4tune-web: + image: 4tune-web:master + statera-console: + image: statera-console:master + statera: + image: statera:master + diff --git a/example/acme-apps/ansible/dba/acme-ops.yml b/example/acme-apps/ansible/dba/acme-ops.yml new file mode 100644 index 0000000..077c554 --- /dev/null +++ b/example/acme-apps/ansible/dba/acme-ops.yml @@ -0,0 +1,18 @@ +# Generated + +# cluster: +--- +- host: + - acme-2 + tasks: + import_role: + name: docker-service + vars: + template: | + version: "3" + services: + n8n: + image: n8n:0.84.1 + pdb: + image: postgresql:11 + diff --git a/example/acme-apps/terraform/acme-1-instance.tf b/example/acme-apps/terraform/acme-1-instance.tf new file mode 100644 index 0000000..e1aed14 --- /dev/null +++ b/example/acme-apps/terraform/acme-1-instance.tf @@ -0,0 +1,8 @@ +resource "scaleway_server_instance" "acme-1" { + name = "acme-1" + type = "DEV1-S" + image = "b3042271-d2b1-4f87-b407-aedd3bbd1663" + ip_id = scaleway_instance_ip.acme-1.ip + enable_dynamic_ip = false + enable_ipv6 = true +} diff --git a/example/acme-apps/terraform/acme-1-ip.tf b/example/acme-apps/terraform/acme-1-ip.tf new file mode 100644 index 0000000..283eb55 --- /dev/null +++ b/example/acme-apps/terraform/acme-1-ip.tf @@ -0,0 +1,4 @@ +resource "scaleway_instance_reverse_dns" "acme-1" { + reverse = "acme-1.machine.acme.com." + ip_id = scaleway_instance_ip.acme-1.id +} diff --git a/example/acme-apps/terraform/acme-2-instance.tf b/example/acme-apps/terraform/acme-2-instance.tf new file mode 100644 index 0000000..4ae0fe5 --- /dev/null +++ b/example/acme-apps/terraform/acme-2-instance.tf @@ -0,0 +1,8 @@ +resource "scaleway_server_instance" "acme-2" { + name = "acme-1" + type = "DEV1-S" + image = "b3042271-d2b1-4f87-b407-aedd3bbd1663" + ip_id = scaleway_instance_ip.acme-2.ip + enable_dynamic_ip = false + enable_ipv6 = true +} diff --git a/example/acme-apps/terraform/acme-2-ip.tf b/example/acme-apps/terraform/acme-2-ip.tf new file mode 100644 index 0000000..f72fe88 --- /dev/null +++ b/example/acme-apps/terraform/acme-2-ip.tf @@ -0,0 +1,4 @@ +resource "scaleway_instance_reverse_dns" "acme-2" { + reverse = "acme-2.machine.acme.com." + ip_id = scaleway_instance_ip.acme-2.id +} diff --git a/example/acme-apps/terraform/acme-3-instance.tf b/example/acme-apps/terraform/acme-3-instance.tf new file mode 100644 index 0000000..389b39b --- /dev/null +++ b/example/acme-apps/terraform/acme-3-instance.tf @@ -0,0 +1,8 @@ +resource "scaleway_server_instance" "acme-3" { + name = "acme-1" + type = "DEV1-S" + image = "b3042271-d2b1-4f87-b407-aedd3bbd1663" + ip_id = scaleway_instance_ip.acme-3.ip + enable_dynamic_ip = false + enable_ipv6 = true +} diff --git a/example/acme-apps/terraform/acme-3-ip.tf b/example/acme-apps/terraform/acme-3-ip.tf new file mode 100644 index 0000000..7d07eb9 --- /dev/null +++ b/example/acme-apps/terraform/acme-3-ip.tf @@ -0,0 +1,4 @@ +resource "scaleway_instance_reverse_dns" "acme-3" { + reverse = "acme-3.machine.acme.com." + ip_id = scaleway_instance_ip.acme-3.id +} diff --git a/example/acme-apps/terraform/main.tf b/example/acme-apps/terraform/main.tf new file mode 100644 index 0000000..74efe05 --- /dev/null +++ b/example/acme-apps/terraform/main.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + + scaleway = { + version = "2.0.0-rc1" + source = "scaleway" + } + } +} diff --git a/example/acme-apps/terraform/vars.tf b/example/acme-apps/terraform/vars.tf new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/example/acme-apps/terraform/vars.tf @@ -0,0 +1 @@ + diff --git a/example/acme-wireguard/host_vars/acme-1/wireguard.yml b/example/acme-wireguard/host_vars/acme-1/wireguard.yml new file mode 100644 index 0000000..3c71e52 --- /dev/null +++ b/example/acme-wireguard/host_vars/acme-1/wireguard.yml @@ -0,0 +1,15 @@ +# Generated +wireguard_port: 53476 +link_address: 192.168.10.3 +network_cidr: 10.55.255.0/24 +wireguard_peers: + acme-2: + public_address: acme-2.machine.acme.com + public_port: 53476 + gateway: 192.168.10.4 + network: 10.55.254.0/24 + acme-3: + public_address: acme-3.machine.acme.com + public_port: 53476 + gateway: 192.168.10.5 + network: 10.55.253.0/24 diff --git a/example/acme-wireguard/host_vars/acme-2/wireguard.yml b/example/acme-wireguard/host_vars/acme-2/wireguard.yml new file mode 100644 index 0000000..d7e4219 --- /dev/null +++ b/example/acme-wireguard/host_vars/acme-2/wireguard.yml @@ -0,0 +1,15 @@ +# Generated +wireguard_port: 53476 +link_address: 192.168.10.4 +network_cidr: 10.55.254.0/24 +wireguard_peers: + acme-1: + public_address: acme-1.machine.acme.com + public_port: 53476 + gateway: 192.168.10.3 + network: 10.55.255.0/24 + acme-3: + public_address: acme-3.machine.acme.com + public_port: 53476 + gateway: 192.168.10.5 + network: 10.55.253.0/24 diff --git a/example/acme-wireguard/host_vars/acme-3/wireguard.yml b/example/acme-wireguard/host_vars/acme-3/wireguard.yml new file mode 100644 index 0000000..7d7fa76 --- /dev/null +++ b/example/acme-wireguard/host_vars/acme-3/wireguard.yml @@ -0,0 +1,15 @@ +# Generated +wireguard_port: 53476 +link_address: 192.168.10.5 +network_cidr: 10.55.253.0/24 +wireguard_peers: + acme-1: + public_address: acme-1.machine.acme.com + public_port: 53476 + gateway: 192.168.10.3 + network: 10.55.255.0/24 + acme-2: + public_address: acme-2.machine.acme.com + public_port: 53476 + gateway: 192.168.10.4 + network: 10.55.254.0/24 diff --git a/example/acme-wireguard/host_vars/ws-1/wireguard.yml b/example/acme-wireguard/host_vars/ws-1/wireguard.yml new file mode 100644 index 0000000..0372db8 --- /dev/null +++ b/example/acme-wireguard/host_vars/ws-1/wireguard.yml @@ -0,0 +1,20 @@ +# Generated +wireguard_port: 53476 +link_address: 192.168.10.6 +network_cidr: 10.55.252.0/24 +wireguard_peers: + acme-1: + public_address: acme-1.machine.acme.com + public_port: 53476 + gateway: 192.168.10.3 + network: 10.55.255.0/24 + acme-2: + public_address: acme-2.machine.acme.com + public_port: 53476 + gateway: 192.168.10.4 + network: 10.55.254.0/24 + acme-3: + public_address: acme-3.machine.acme.com + public_port: 53476 + gateway: 192.168.10.5 + network: 10.55.253.0/24 diff --git a/example/acme-wireguard/host_vars/ws-2/wireguard.yml b/example/acme-wireguard/host_vars/ws-2/wireguard.yml new file mode 100644 index 0000000..133bd66 --- /dev/null +++ b/example/acme-wireguard/host_vars/ws-2/wireguard.yml @@ -0,0 +1,20 @@ +# Generated +wireguard_port: 53476 +link_address: 192.168.10.7 +network_cidr: 10.55.251.0/24 +wireguard_peers: + acme-1: + public_address: acme-1.machine.acme.com + public_port: 53476 + gateway: 192.168.10.3 + network: 10.55.255.0/24 + acme-2: + public_address: acme-2.machine.acme.com + public_port: 53476 + gateway: 192.168.10.4 + network: 10.55.254.0/24 + acme-3: + public_address: acme-3.machine.acme.com + public_port: 53476 + gateway: 192.168.10.5 + network: 10.55.253.0/24 diff --git a/example/acme-wireguard/inventory.yml b/example/acme-wireguard/inventory.yml new file mode 100644 index 0000000..de54c64 --- /dev/null +++ b/example/acme-wireguard/inventory.yml @@ -0,0 +1,21 @@ +# Generated +all: + hosts: + acme-1: + ansible_host: acme-1.machine.acme.com + acme-2: + ansible_host: acme-2.machine.acme.com + acme-3: + ansible_host: acme-3.machine.acme.com + ws-1: + ansible_host: + ws-2: + ansible_host: + children: + wireguard_vpn0: + hosts: + acme-1: + acme-2: + acme-3: + ws-1: + ws-2: diff --git a/example/acme-wireguard/wireguard-vpn0.yml b/example/acme-wireguard/wireguard-vpn0.yml new file mode 100644 index 0000000..a1309e2 --- /dev/null +++ b/example/acme-wireguard/wireguard-vpn0.yml @@ -0,0 +1,7 @@ +- hosts: wireguard_vpn0 + vars: + wireguard_if: vpn0 + tasks: + - name: wireguard + import_role: + name: wireguard diff --git a/example/acme.yaml b/example/acme.yaml new file mode 100644 index 0000000..741e711 --- /dev/null +++ b/example/acme.yaml @@ -0,0 +1,78 @@ +- type: io.trygvis.acme.apps.AcmeMyApp + data: + environment: ci + dockerTag: development + +- type: io.trygvis.acme.apps.AcmeMyApp + data: + environment: production + dockerTag: master + +- type: io.trygvis.acme.apps.AcmeOps + + + # DNS configuration +- type: io.trygvis.rules.terraform.GoogleManagedZoneTerraformExpression + data: + name: "acme_zone" + + +- type: io.trygvis.rules.machine.Machine + data: + name: acme-1 + +- type: io.trygvis.rules.dba.DbaMachineRole + data: + machine: acme-1 + roles: + - ci-app + + +- type: io.trygvis.rules.machine.MachineSpecificaiton + data: + mCpu: 2000 + memory: 2000 + +- type: io.trygvis.rules.machine.Machine + data: + name: acme-2 + +- type: io.trygvis.rules.dba.DbaMachineRole + data: + machine: acme-2 + roles: + - ops + - ci-db # This also runs the DB for the non-production environments to keep the other machines stateless + + +- type: io.trygvis.rules.machine.Machine + data: + name: acme-3 + +- type: io.trygvis.rules.dba.DbaMachineRole + data: + machine: acme-3 + roles: + - production-app + - production-db + + # Workstations + +- type: io.trygvis.rules.machine.Machine + data: + name: ws-1 + +- type: io.trygvis.rules.machine.Machine + data: + name: ws-2 + + # Wireguard VPN network +- type: io.trygvis.rules.wireguard.WgNet + data: + name: vpn0 + domain: vpn.acme.com + port: 53476 + linkCidr: 192.168.10.0/29 + networkCidr: 10.55.0.0/16 + networkBits: 24 +
\ No newline at end of file diff --git a/example/ansible.cfg b/example/ansible.cfg new file mode 100644 index 0000000..1790523 --- /dev/null +++ b/example/ansible.cfg @@ -0,0 +1,8 @@ +[defaults] +become_method = sudo +inventory = inventory.yml +nocows = True +stdout_callback = debug +vault_password_file = .vault-password +roles_path = roles +retry_files_enabled = False diff --git a/example/build.ninja b/example/build.ninja new file mode 100644 index 0000000..7ccc450 --- /dev/null +++ b/example/build.ninja @@ -0,0 +1 @@ +subninja engine.ninja diff --git a/example/db/apps.yaml b/example/db/apps.yaml new file mode 100644 index 0000000..b27231a --- /dev/null +++ b/example/db/apps.yaml @@ -0,0 +1,354 @@ +--- +- type: "io.trygvis.rules.machine.Machine" + data: + &acme-1 name: "acme-1" + fqdn: "acme-1.machine.acme.com" +- type: "io.trygvis.rules.machine.Machine" + data: + &acme-2 name: "acme-2" + fqdn: "acme-2.machine.acme.com" +- type: "io.trygvis.rules.machine.Machine" + data: + &acme-3 name: "acme-3" + fqdn: "acme-3.machine.acme.com" +- type: "io.trygvis.rules.machine.Machine" + data: + &ws-1 name: "ws-1" + fqdn: null +- type: "io.trygvis.rules.machine.Machine" + data: + &ws-2 name: "ws-2" + fqdn: null +- type: "io.trygvis.rules.dns.DnsZone" + data: + name: "ci.acme.com" +- type: "io.trygvis.rules.dns.DnsZone" + data: + name: "production.acme.com" +- type: "io.trygvis.rules.dba.Cluster" + data: + &acme-myapp-ci name: "acme-myapp-ci" +- type: "io.trygvis.rules.dba.Cluster" + data: + &acme-myapp-production name: "acme-myapp-production" +- type: "io.trygvis.rules.dba.Cluster" + data: + &acme-ops name: "acme-ops" +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-ci-4tune-api" + cluster: *acme-myapp-ci + name: "4tune-api" + machineRole: "ci-app" + image: "4tune-api" + tag: "development" + machine: *acme-1 + machineSpecification: + cpu: 200 + memory: 200 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-production-4tune-api" + cluster: *acme-myapp-production + name: "4tune-api" + machineRole: "production-app" + image: "4tune-api" + tag: "master" + machine: *acme-3 + machineSpecification: + cpu: 200 + memory: 200 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-ci-4tune-web" + cluster: *acme-myapp-ci + name: "4tune-web" + machineRole: "ci-app" + image: "4tune-web" + tag: "development" + machine: *acme-1 + machineSpecification: + cpu: 100 + memory: 50 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-production-4tune-web" + cluster: *acme-myapp-production + name: "4tune-web" + machineRole: "production-app" + image: "4tune-web" + tag: "master" + machine: *acme-3 + machineSpecification: + cpu: 100 + memory: 50 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-ci-mdb" + cluster: *acme-myapp-ci + name: "mdb" + machineRole: "ci-db" + image: "mongodb" + tag: "3.2" + machine: *acme-2 + machineSpecification: + cpu: 500 + memory: 200 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-production-mdb" + cluster: *acme-myapp-production + name: "mdb" + machineRole: "production-db" + image: "mongodb" + tag: "3.2" + machine: *acme-3 + machineSpecification: + cpu: 500 + memory: 200 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-ops-n8n" + cluster: *acme-ops + name: "n8n" + machineRole: "ops" + image: "n8n" + tag: "0.84.1" + machine: *acme-2 + machineSpecification: null +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-ci-pdb" + cluster: *acme-myapp-ci + name: "pdb" + machineRole: "ci-db" + image: "postgresql" + tag: "13" + machine: *acme-2 + machineSpecification: + cpu: 500 + memory: 500 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-production-pdb" + cluster: *acme-myapp-production + name: "pdb" + machineRole: "production-db" + image: "postgresql" + tag: "13" + machine: *acme-3 + machineSpecification: + cpu: 500 + memory: 500 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-ops-pdb" + cluster: *acme-ops + name: "pdb" + machineRole: "ops" + image: "postgresql" + tag: "11" + machine: *acme-2 + machineSpecification: null +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-ci-statera" + cluster: *acme-myapp-ci + name: "statera" + machineRole: "ci-app" + image: "statera" + tag: "development" + machine: *acme-1 + machineSpecification: + cpu: 200 + memory: 1000 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-production-statera" + cluster: *acme-myapp-production + name: "statera" + machineRole: "production-app" + image: "statera" + tag: "master" + machine: *acme-3 + machineSpecification: + cpu: 200 + memory: 1000 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-ci-statera-console" + cluster: *acme-myapp-ci + name: "statera-console" + machineRole: "ci-app" + image: "statera-console" + tag: "development" + machine: *acme-1 + machineSpecification: + cpu: 100 + memory: 50 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-production-statera-console" + cluster: *acme-myapp-production + name: "statera-console" + machineRole: "production-app" + image: "statera-console" + tag: "master" + machine: *acme-3 + machineSpecification: + cpu: 100 + memory: 50 +- type: "io.trygvis.rules.dba.DbaMachineRole" + data: + &1 machine: "acme-1" + roles: + - "ci-app" +- type: "io.trygvis.rules.dba.DbaMachineRole" + data: + &2 machine: "acme-2" + roles: + - "ops" + - "ci-db" +- type: "io.trygvis.rules.dba.DbaMachineRole" + data: + &3 machine: "acme-3" + roles: + - "production-app" + - "production-db" +- type: "io.trygvis.rules.wireguard.WgNet" + data: + &vpn0 name: "vpn0" + domain: "vpn.acme.com" + port: 53476 + linkCidr: "192.168.10.0/29" + networkCidr: "10.55.0.0/16" + networkBits: 24 +- type: "io.trygvis.rules.terraform.TerraformResource$ArrayTerraformValue" + data: + - "scaleway_instance_ip.acme-1.id" +- type: "io.trygvis.rules.terraform.TerraformResource$ArrayTerraformValue" + data: + - "scaleway_instance_ip.acme-3.id" +- type: "io.trygvis.rules.terraform.TerraformResource$ArrayTerraformValue" + data: + - "scaleway_instance_ip.acme-2.id" +- type: "io.trygvis.rules.terraform.TerraformResource" + data: + output: "terraform/acme-1-instance.tf" + kind: "scaleway_server_instance" + instance: "acme-1" + values: + name: "acme-1" + type: "DEV1-S" + image: "b3042271-d2b1-4f87-b407-aedd3bbd1663" + ip_id: "scaleway_instance_ip.acme-1.ip" + enable_dynamic_ip: false + enable_ipv6: true + name: "scaleway_server_instance.acme-1" +- type: "io.trygvis.rules.terraform.TerraformResource" + data: + output: "terraform/acme-1-ip.tf" + kind: "scaleway_instance_ip" + instance: "acme-1" + values: {} + name: "scaleway_instance_ip.acme-1" +- type: "io.trygvis.rules.terraform.TerraformResource" + data: + output: "terraform/acme-1-ip.tf" + kind: "scaleway_instance_reverse_dns" + instance: "acme-1" + values: + reverse: "acme-1.machine.acme.com." + ip_id: "scaleway_instance_ip.acme-1.id" + name: "scaleway_instance_reverse_dns.acme-1" +- type: "io.trygvis.rules.terraform.TerraformResource" + data: + output: "terraform/acme-2-instance.tf" + kind: "scaleway_server_instance" + instance: "acme-2" + values: + name: "acme-1" + type: "DEV1-S" + image: "b3042271-d2b1-4f87-b407-aedd3bbd1663" + ip_id: "scaleway_instance_ip.acme-2.ip" + enable_dynamic_ip: false + enable_ipv6: true + name: "scaleway_server_instance.acme-2" +- type: "io.trygvis.rules.terraform.TerraformResource" + data: + output: "terraform/acme-2-ip.tf" + kind: "scaleway_instance_ip" + instance: "acme-2" + values: {} + name: "scaleway_instance_ip.acme-2" +- type: "io.trygvis.rules.terraform.TerraformResource" + data: + output: "terraform/acme-2-ip.tf" + kind: "scaleway_instance_reverse_dns" + instance: "acme-2" + values: + reverse: "acme-2.machine.acme.com." + ip_id: "scaleway_instance_ip.acme-2.id" + name: "scaleway_instance_reverse_dns.acme-2" +- type: "io.trygvis.rules.terraform.TerraformResource" + data: + output: "terraform/acme-3-instance.tf" + kind: "scaleway_server_instance" + instance: "acme-3" + values: + name: "acme-1" + type: "DEV1-S" + image: "b3042271-d2b1-4f87-b407-aedd3bbd1663" + ip_id: "scaleway_instance_ip.acme-3.ip" + enable_dynamic_ip: false + enable_ipv6: true + name: "scaleway_server_instance.acme-3" +- type: "io.trygvis.rules.terraform.TerraformResource" + data: + output: "terraform/acme-3-ip.tf" + kind: "scaleway_instance_ip" + instance: "acme-3" + values: {} + name: "scaleway_instance_ip.acme-3" +- type: "io.trygvis.rules.terraform.TerraformResource" + data: + output: "terraform/acme-3-ip.tf" + kind: "scaleway_instance_reverse_dns" + instance: "acme-3" + values: + reverse: "acme-3.machine.acme.com." + ip_id: "scaleway_instance_ip.acme-3.id" + name: "scaleway_instance_reverse_dns.acme-3" +- type: "io.trygvis.rules.terraform.TerraformMain" + data: + module: "terraform" + providers: + scaleway: + source: "scaleway" + version: "2.0.0-rc1" +- type: "io.trygvis.rules.engine.KeyValue" + data: + key: "rm-gen" + value: null +- type: "io.trygvis.acme.AcmeServer" + data: + &acme-1 name: "acme-1" + machine: *acme-1 +- type: "io.trygvis.acme.AcmeServer" + data: + &acme-2 name: "acme-2" + machine: *acme-2 +- type: "io.trygvis.acme.AcmeServer" + data: + &acme-3 name: "acme-3" + machine: *acme-3 +- type: "io.trygvis.acme.apps.AcmeOps" + data: {} +- type: "io.trygvis.acme.apps.AcmeMyApp" + data: + environment: "ci" + dockerTag: "development" +- type: "io.trygvis.acme.apps.AcmeMyApp" + data: + environment: "production" + dockerTag: "master" diff --git a/example/db/wireguard.yaml b/example/db/wireguard.yaml new file mode 100644 index 0000000..a374351 --- /dev/null +++ b/example/db/wireguard.yaml @@ -0,0 +1,161 @@ +--- +- type: "io.trygvis.rules.machine.Machine" + data: + &acme-1 name: "acme-1" + fqdn: "acme-1.machine.acme.com" +- type: "io.trygvis.rules.machine.Machine" + data: + &acme-2 name: "acme-2" + fqdn: "acme-2.machine.acme.com" +- type: "io.trygvis.rules.machine.Machine" + data: + &acme-3 name: "acme-3" + fqdn: "acme-3.machine.acme.com" +- type: "io.trygvis.rules.machine.Machine" + data: + &ws-1 name: "ws-1" + fqdn: null +- type: "io.trygvis.rules.machine.Machine" + data: + &ws-2 name: "ws-2" + fqdn: null +- type: "io.trygvis.rules.dns.DnsEntry" + data: + fqdn: "acme-1.vpn.acme.com" + type: "A" +- type: "io.trygvis.rules.dns.DnsEntry" + data: + fqdn: "acme-2.vpn.acme.com" + type: "A" +- type: "io.trygvis.rules.dns.DnsEntry" + data: + fqdn: "acme-3.vpn.acme.com" + type: "A" +- type: "io.trygvis.rules.dns.DnsEntry" + data: + fqdn: "ws-1.vpn.acme.com" + type: "A" +- type: "io.trygvis.rules.dns.DnsEntry" + data: + fqdn: "ws-2.vpn.acme.com" + type: "A" +- type: "io.trygvis.rules.wireguard.WgNet" + data: + &vpn0 name: "vpn0" + domain: "vpn.acme.com" + port: 53476 + linkCidr: "192.168.10.0/29" + networkCidr: "10.55.0.0/16" + networkBits: 24 +- type: "io.trygvis.rules.wireguard.WgIpPool" + data: + &1 net: *vpn0 + role: "link" + cidr: + value: "192.168.10.0/29" +- type: "io.trygvis.rules.wireguard.WgIpPool" + data: + &2 net: *vpn0 + role: "networks" + cidr: + value: "10.55.0.0/16" +- type: "io.trygvis.rules.wireguard.WgHost" + data: + &3 machine: *ws-1 + net: *vpn0 + publicName: null + publicPort: 53476 + ip: "192.168.10.6" + networkCidr: "10.55.252.0/24" +- type: "io.trygvis.rules.wireguard.WgHost" + data: + &4 machine: *ws-2 + net: *vpn0 + publicName: null + publicPort: 53476 + ip: "192.168.10.7" + networkCidr: "10.55.251.0/24" +- type: "io.trygvis.rules.wireguard.WgHost" + data: + &5 machine: *acme-1 + net: *vpn0 + publicName: "acme-1.machine.acme.com" + publicPort: 53476 + ip: "192.168.10.3" + networkCidr: "10.55.255.0/24" +- type: "io.trygvis.rules.wireguard.WgHost" + data: + &6 machine: *acme-2 + net: *vpn0 + publicName: "acme-2.machine.acme.com" + publicPort: 53476 + ip: "192.168.10.4" + networkCidr: "10.55.254.0/24" +- type: "io.trygvis.rules.wireguard.WgHost" + data: + &7 machine: *acme-3 + net: *vpn0 + publicName: "acme-3.machine.acme.com" + publicPort: 53476 + ip: "192.168.10.5" + networkCidr: "10.55.253.0/24" +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &acme-1_x_acme-2 name: "acme-1_x_acme-2" + host: *5 + to: *6 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &acme-1_x_acme-3 name: "acme-1_x_acme-3" + host: *5 + to: *7 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &acme-2_x_acme-1 name: "acme-2_x_acme-1" + host: *6 + to: *5 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &acme-2_x_acme-3 name: "acme-2_x_acme-3" + host: *6 + to: *7 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &acme-3_x_acme-1 name: "acme-3_x_acme-1" + host: *7 + to: *5 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &acme-3_x_acme-2 name: "acme-3_x_acme-2" + host: *7 + to: *6 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &ws-1_x_acme-1 name: "ws-1_x_acme-1" + host: *3 + to: *5 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &ws-1_x_acme-2 name: "ws-1_x_acme-2" + host: *3 + to: *6 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &ws-1_x_acme-3 name: "ws-1_x_acme-3" + host: *3 + to: *7 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &ws-2_x_acme-1 name: "ws-2_x_acme-1" + host: *4 + to: *5 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &ws-2_x_acme-2 name: "ws-2_x_acme-2" + host: *4 + to: *6 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &ws-2_x_acme-3 name: "ws-2_x_acme-3" + host: *4 + to: *7 diff --git a/example/engine.ninja b/example/engine.ninja index 3e6c6f3..3c53218 100644 --- a/example/engine.ninja +++ b/example/engine.ninja @@ -5,7 +5,7 @@ rule engine-yaml-to-ninja command = engine ninja -build engine.ninja: engine.yaml +build engine.ninja: engine-yaml-to-ninja engine.yaml ### engine.png @@ -22,35 +22,32 @@ build engine.png: dot-to-png engine.dot # Jobs rule acme - command=engine run $name $inputs $output_state $agenda_group $modules + command=engine run $name $inputs $output_state $output_includes $generated_output $agenda_groups $modules build db/acme.yaml: acme name=--name acme output_state=--output-state db/acme.yaml - agenda_group= modules=$ --module=foo $ --module=bar rule acme-apps - command=engine run $name $inputs $output_state $agenda_group $modules + command=engine run $name $inputs $output_state $output_includes $generated_output $agenda_groups $modules build db/acme-apps.yaml: acme-apps db/acme.yaml name=--name acme-apps inputs=$ --input=db/acme.yaml output_state=--output-state db/acme-apps.yaml - agenda_group= rule acme-wireguard - command=engine run $name $inputs $output_state $agenda_group $modules + command=engine run $name $inputs $output_state $output_includes $generated_output $agenda_groups $modules build db/acme-wireguard.yaml: acme-wireguard db/acme.yaml name=--name acme-wireguard inputs=$ --input=db/acme.yaml output_state=--output-state db/acme-wireguard.yaml - agenda_group= modules=$ --module=foo $ --module=$$MODULE_HOME/bar diff --git a/example/main.tf b/example/main.tf new file mode 100644 index 0000000..c7b91b2 --- /dev/null +++ b/example/main.tf @@ -0,0 +1,60 @@ +terraform { + required_providers { + scaleway = { + source = "scaleway/scaleway" + version = "1.17.2" + } + + ansiblevault = { + source = "MeilleursAgents/ansiblevault" + version = "2.2.0" + } + } +} + +variable "ansible_vault_pass" { + type = string +} + +provider "ansiblevault" { + # vault_path = ".vault-password" + vault_pass = var.ansible_vault_pass + root_folder = "." +} + +data "ansiblevault_path" "scaleway_access_key" { + path = "vault/scaleway.yml" + key = "scaleway_access_key" +} +data "ansiblevault_path" "scaleway_secret_key" { + path = "vault/scaleway.yml" + key = "scaleway_secret_key" +} +data "ansiblevault_path" "scaleway_organization" { + path = "vault/scaleway.yml" + key = "scaleway_organization" +} + +provider "scaleway" { + region = "fr-par" + zone = "fr-par-1" + access_key = data.ansiblevault_path.scaleway_access_key.value + secret_key = data.ansiblevault_path.scaleway_secret_key.value + organization_id = data.ansiblevault_path.scaleway_organization.value +} + +# This can also be generated from input objects, but it might be reused between different modules so some control +# over if/when it is generated is required. +resource "google_dns_managed_zone" "acme" { + name = "acme" + dns_name = "machine.acme.com." +} + +module "acme-apps" { + source = "../acme-apps/terraform" + providers = { + scaleway = scaleway + } + + acme_zone = google_dns_managed_zone.acme.name +} diff --git a/example/modules/acme/pom.xml b/example/modules/acme/pom.xml new file mode 100644 index 0000000..01b9ab0 --- /dev/null +++ b/example/modules/acme/pom.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>io.trygvis.rules-sandbox.module</groupId> + <artifactId>ri-module-parent</artifactId> + <version>1.0-SNAPSHOT</version> + <relativePath>../../../modules/ri-module-parent/pom.xml</relativePath> + </parent> + + <artifactId>acme</artifactId> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ri-base</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ri-wireguard</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + +</project> diff --git a/example/modules/acme/src/main/java/io/trygvis/acme/AcmeAppsMain.java b/example/modules/acme/src/main/java/io/trygvis/acme/AcmeAppsMain.java new file mode 100644 index 0000000..c65a3b2 --- /dev/null +++ b/example/modules/acme/src/main/java/io/trygvis/acme/AcmeAppsMain.java @@ -0,0 +1,14 @@ +package io.trygvis.acme; + +public class AcmeAppsMain { +// public static void main(String[] args) throws IOException { +// try (var engine = new Engine( +// "acme-apps", +// new File("acme.yaml"), +// new File("acme-apps"), +// new String[]{"init", "generate"}, +// new File[0])) { +// engine.io.dump(new File("out", "acme/apps.yaml"), engine.session.getFactHandles()); +// } +// } +} diff --git a/example/modules/acme/src/main/java/io/trygvis/acme/VpnMain.java b/example/modules/acme/src/main/java/io/trygvis/acme/VpnMain.java new file mode 100644 index 0000000..cbf962c --- /dev/null +++ b/example/modules/acme/src/main/java/io/trygvis/acme/VpnMain.java @@ -0,0 +1,21 @@ +package io.trygvis.acme; + +public class VpnMain { +// public static void main(String[] args) throws IOException { +// try (var engine = new Engine( +// "acme-wireguard", +// new File("acme.yaml"), +// new File("acme-wireguard"), +// new String[]{"init", "generate"}, +// new File[0])) { +// var outputFile = new File("out", "acme/wireguard.yaml"); +// engine.io.dump(outputFile, engine.session.getFactHandles(), (Object o) -> +// o.getClass().getName().contains("Wg") +// || o instanceof Machine +// || o instanceof DnsEntry +// || o instanceof Ipv4Cidr +// || o instanceof Ipv4Address +// ); +// } +// } +} diff --git a/example/modules/acme/src/main/java/io/trygvis/acme/apps/AcmeMyApp.java b/example/modules/acme/src/main/java/io/trygvis/acme/apps/AcmeMyApp.java new file mode 100644 index 0000000..9371af2 --- /dev/null +++ b/example/modules/acme/src/main/java/io/trygvis/acme/apps/AcmeMyApp.java @@ -0,0 +1,6 @@ +package io.trygvis.acme.apps; + +public class AcmeMyApp { + public String environment; + public String dockerTag; +} diff --git a/example/modules/acme/src/main/java/io/trygvis/acme/apps/AcmeOps.java b/example/modules/acme/src/main/java/io/trygvis/acme/apps/AcmeOps.java new file mode 100644 index 0000000..be9d82b --- /dev/null +++ b/example/modules/acme/src/main/java/io/trygvis/acme/apps/AcmeOps.java @@ -0,0 +1,4 @@ +package io.trygvis.acme.apps; + +public class AcmeOps { +} diff --git a/example/modules/acme/src/main/resources/META-INF/kmodule.xml b/example/modules/acme/src/main/resources/META-INF/kmodule.xml new file mode 100644 index 0000000..da435d6 --- /dev/null +++ b/example/modules/acme/src/main/resources/META-INF/kmodule.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://www.drools.org/xsd/kmodule" + xsi:schemaLocation="http://www.drools.org/xsd/kmodule https://www.drools.org/xsd/kmodule_7_1.xsd"> + + <kbase name="acme-apps" packages="io.trygvis.acme.apps" includes="dba,engine,machine,terraform, acme-shared"> + <ksession name="acme-apps" default="true"/> + </kbase> + + <kbase name="acme-wireguard" packages="io.trygvis.acme.wireguard" includes="engine,wireguard, acme-shared"> + <ksession name="acme-wireguard" default="true"/> + </kbase> + + <kbase name="acme-shared" packages="io.trygvis.acme"> + <ksession name="acme-shared" default="true"/> + </kbase> +</kmodule> diff --git a/example/modules/acme/src/main/resources/io/trygvis/acme/acme.drl b/example/modules/acme/src/main/resources/io/trygvis/acme/acme.drl new file mode 100644 index 0000000..6a2f33b --- /dev/null +++ b/example/modules/acme/src/main/resources/io/trygvis/acme/acme.drl @@ -0,0 +1,81 @@ +package io.trygvis.acme; + +import io.trygvis.rules.machine.Machine; +import io.trygvis.rules.dba.Cluster; +import io.trygvis.rules.dba.Container +import io.trygvis.rules.terraform.TerraformResource; +import io.trygvis.rules.terraform.TerraformMain +import io.trygvis.rules.terraform.TerraformProvider; + +dialect "mvel" + +declare AcmeServer + name : String + machine : Machine +end + +rule "Create Acme servers" +when + $m : Machine(name.startsWith("acme-")) + not(AcmeServer(name == $m.name)) +then + var s = new AcmeServer(); + s.name = $m.name; + s.machine = $m; + insert(s); +end + +rule "Set public domain for ACME servers" +when + $m : Machine(fqdn == null) + $s : AcmeServer(machine == $m) +then + var fqdn = "%s.machine.acme.com".formatted($m.name); + modify ($m) { + fqdn = fqdn + } +end + +rule "Make Terraform module for machines" +when + not TerraformMain(module == "terraform") +then + var module = new TerraformMain("terraform"); + + var scaleway = new TerraformProvider("scaleway", "2.0.0-rc1"); + module.getProviders().put("scaleway", scaleway); + + insert(module) +end + +rule "Make Scaleway Terraform resources for Machine" +when + $m : Machine() + $s : AcmeServer(machine == $m) +then + var ip = new TerraformResource("terraform/" + $m.name + "-ip.tf", "scaleway_instance_ip", $m.name); + var instance = new TerraformResource("terraform/" + $m.name + "-instance.tf", "scaleway_server_instance", $m.name) + .set("name", "acme-1") + .set("type", "DEV1-S") + .set("image", "b3042271-d2b1-4f87-b407-aedd3bbd1663") + .setExpression("ip_id", ip.name + ".ip") + .set("enable_dynamic_ip", false) + .set("enable_ipv6", true); + + + var rev = new TerraformResource("terraform/" + $m.name + "-ip.tf", "scaleway_instance_reverse_dns", $m.name) + .set("reverse", $m.fqdn + ".") + .setExpression("ip_id", ip.name + ".id"); + var dns = new TerraformResource("terraform/" + $m.name + "-dns.tf", "google_dns_record_set", $m.name) + .set("name", $m.fqdn) + .setExpression("managed_zone", "var.dns_zone") + .set("type", "A") + .set("ttl", 300) + .array("rrdatas") + .addExpression(ip.name + ".id"); + + insert(instance) + insert(ip) + insert(rev) + insert(dns) +end diff --git a/example/modules/acme/src/main/resources/io/trygvis/acme/apps/apps.drl b/example/modules/acme/src/main/resources/io/trygvis/acme/apps/apps.drl new file mode 100644 index 0000000..670079f --- /dev/null +++ b/example/modules/acme/src/main/resources/io/trygvis/acme/apps/apps.drl @@ -0,0 +1,44 @@ +package io.trygvis.acme.apps + +import io.trygvis.rules.machine.Machine; +import io.trygvis.rules.dba.Cluster; +import io.trygvis.rules.dba.Container +import io.trygvis.rules.dns.DnsZone; +import io.trygvis.rules.machine.Machine +import io.trygvis.rules.machine.MachineSpecification +import io.trygvis.rules.dba.Cluster +import io.trygvis.rules.dba.Container + +dialect "mvel" + +rule "Ops" +when + $ops: AcmeOps() +then + var cluster = new Cluster("acme-ops"); + insert(cluster); + insert(new Container(cluster, "pdb", "ops", "postgresql", "11", null)); + insert(new Container(cluster, "n8n", "ops", "n8n", "0.84.1", null)); +end + +rule "MyApp" +when + $app: AcmeMyApp() +then + var zone = new DnsZone($app.environment + ".acme.com"); + insert(zone) + + var cluster = new Cluster("acme-myapp-" + $app.environment); + insert(cluster); + + var app = $app.environment + "-app"; + var db = $app.environment + "-db"; + + var tag = $app.dockerTag; + insert(new Container(cluster, "statera", app, "statera", tag, new MachineSpecification(200, 1000))); + insert(new Container(cluster, "statera-console", app, "statera-console", tag, new MachineSpecification(100, 50))); + insert(new Container(cluster, "4tune-web", app, "4tune-web", tag, new MachineSpecification(100, 50))); + insert(new Container(cluster, "4tune-api", app, "4tune-api", tag, new MachineSpecification(200, 200))); + insert(new Container(cluster, "pdb", db, "postgresql", "13", new MachineSpecification(500, 500))); + insert(new Container(cluster, "mdb", db, "mongodb", "3.2", new MachineSpecification(500, 200))); +end |