Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
05d1624bdd
|
|||
|
19f599e502
|
|||
|
457f2bd810
|
|||
|
3e12b13d95
|
|||
|
01fc509795
|
|||
|
a19c71009f
|
|||
|
9e45ff6376
|
|||
|
bbc4fef0e8
|
|||
|
5d2f50feb9
|
|||
|
a0ac55e746
|
|||
|
17a54f6792
|
|||
|
9de7d52192
|
|||
|
4d4f085c3e
|
|||
|
d1267f816b
|
|||
|
e6e85b00f7
|
|||
|
6adbd50c6d
|
|||
|
b04871a60c
|
|||
|
b961de0455
|
|||
|
596f2b13ba
|
|||
|
51ba9821a0
|
|||
|
02e79deb5c
|
|||
|
5b341c9430
|
|||
|
0eaadbe6a7
|
|||
|
0d3f4a0a30
|
|||
|
b7408fb4d8
|
|||
|
58fb1ea167
|
|||
|
654cf500f9
|
|||
|
761c183ce2
|
|||
|
3c7c95c8ee
|
|||
|
89c48246fd
|
|||
|
4e5346e2e0
|
|||
|
2fbe4dd1cc
|
|||
|
30e2b0c440
|
|||
|
9ad18067de
|
|||
|
70988e3cf3
|
|||
|
53f3ae37cc
|
|||
|
85cbfb51ef
|
|||
|
d81590c8a1
|
|||
|
bd8bf86227
|
|||
|
cc15ff3247
|
|||
|
2d50aa1820
|
|||
|
9839a3c9c6
|
|||
|
427372da83
|
|||
|
6975026fc5
|
|||
|
eaf344f159
|
|||
|
e9c492d149
|
|||
|
41ee9e0618
|
|||
|
835784a7a8
|
|||
|
d15ee52a49
|
|||
|
b4178c92a2
|
|||
|
558c867bc7
|
|||
|
e980abcb2e
|
|||
|
5253d4dd41
|
|||
|
4b8ad821b4
|
|||
|
087b5840ff
|
|||
|
9bbc4262b3
|
|||
|
4abdccef21
|
|||
|
25698de08f
|
|||
|
e31cb71572
|
@@ -18,7 +18,7 @@ inputs:
|
||||
default: "/tmp/ssh_agent.sock"
|
||||
host-group:
|
||||
description: "The host group to setup the Ansible environment"
|
||||
default: "all"
|
||||
default: "public"
|
||||
outputs:
|
||||
ssh-auth-sock:
|
||||
description: "The SSH_AUTH_SOCK environment variable"
|
||||
@@ -30,12 +30,10 @@ outputs:
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Install Python and required packages
|
||||
- name: Install required python packages
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y python3-pip
|
||||
python3 -m pip install -r requirements.txt
|
||||
python3 -m pip install -r requirements/ansible.txt
|
||||
|
||||
- name: Prepare SSH key
|
||||
shell: bash
|
||||
@@ -56,7 +54,7 @@ runs:
|
||||
env:
|
||||
HOST_GROUP: ${{ inputs.host-group }}
|
||||
run: |
|
||||
ansible-inventory -i inventory/hosts --list --yaml $HOST_GROUP | grep -oP '([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}' | sort -u > /tmp/ansible_hosts
|
||||
ansible-inventory -i inventory/hosts --list --yaml --limit $HOST_GROUP | grep -oP '([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}' | sort -u > /tmp/ansible_hosts
|
||||
echo "hosts=$(cat /tmp/ansible_hosts)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Read SSH host keys from remote hosts
|
||||
|
||||
@@ -17,3 +17,9 @@ runs:
|
||||
|
||||
- name: Setup Sectool
|
||||
uses: a13labs/setup-sectool@v1
|
||||
|
||||
- name: Install Python and required packages
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y python3-pip rsync
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
name: Setup OpenTofu Environment
|
||||
description: Prepare the environment for A13labs CI/CD pipelines
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Setup OpenTofu
|
||||
uses: opentofu/setup-opentofu@v1
|
||||
with:
|
||||
tofu_version: 1.9.1
|
||||
|
||||
- name: Install required python packages
|
||||
shell: bash
|
||||
run: |
|
||||
python3 -m pip install -r requirements/opentofu.txt
|
||||
@@ -8,3 +8,8 @@ runs:
|
||||
uses: hashicorp/setup-terraform@v1
|
||||
with:
|
||||
terraform_version: 1.10.5
|
||||
|
||||
- name: Install required python packages
|
||||
shell: bash
|
||||
run: |
|
||||
python3 -m pip install -r requirements/terraform.txt
|
||||
|
||||
@@ -29,6 +29,9 @@ jobs:
|
||||
- name: Setup Terraform environment
|
||||
uses: ./.github/actions/setup-terraform-env
|
||||
|
||||
- name: Setup Tofu environment
|
||||
uses: ./.github/actions/setup-opentofu-env
|
||||
|
||||
- name: Setup Kubernetes Environment
|
||||
uses: ./.github/actions/setup-k8s-env
|
||||
with:
|
||||
@@ -50,7 +53,7 @@ jobs:
|
||||
env:
|
||||
ANSIBLE_USER: ${{ secrets.ANSIBLE_USER }}
|
||||
run: |
|
||||
ansible -i inventory/hosts -u ${{ secrets.ANSIBLE_USER }} -m ping all
|
||||
ansible -i inventory/hosts -u ${{ secrets.ANSIBLE_USER }} -m ping public
|
||||
|
||||
- name: Test kubectl get nodes
|
||||
run: |
|
||||
@@ -60,6 +63,7 @@ jobs:
|
||||
run: |
|
||||
terraform --version
|
||||
|
||||
- name: Show remote host info
|
||||
- name: Test opentofu
|
||||
run: |
|
||||
echo "System ID: ${{ steps.get-host-info.outputs.system-id }}"
|
||||
tofu --version
|
||||
|
||||
@@ -4,7 +4,9 @@ on:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- ansible/host_vars/*.yml
|
||||
- ansible/host_vars/*.alexpires.me.yml
|
||||
- ansible/host_vars/*.a13labs.me.yml
|
||||
- ansible/host_vars/*.a13labs.pt.yml
|
||||
jobs:
|
||||
ansible-apply:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -38,13 +40,14 @@ jobs:
|
||||
CHANGED_FILES: ${{ steps.setup_env.outputs.CHANGED_FILES }}
|
||||
run: |
|
||||
cd ansible
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_login.yml
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_cis.yml --skip-tags roles::cis::suid
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_fail2ban.yml
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_geoip.yml
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_duo_security.yml
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_encryption.yml
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_microk8s.yml
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_gitea.yml
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_nextcloud.yml
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_wordpress.yml
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_websites.yml
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_m3uproxy.yml
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_monitoring.yml
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_rustdesk.yml
|
||||
|
||||
@@ -5,6 +5,8 @@ on:
|
||||
- main
|
||||
paths:
|
||||
- ansible/playbook_*.yml
|
||||
- '!ansible/playbook_websites.yml'
|
||||
- '!ansible/playbook_hardening*.yml'
|
||||
jobs:
|
||||
ansible-apply:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
name: Build and Release Websites
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'ansible/playbook_websites.yml'
|
||||
- 'bin/hugo_build'
|
||||
- 'websites/**'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Websites
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Hugo
|
||||
uses: peaceiris/actions-hugo@v2
|
||||
with:
|
||||
hugo-version: 'latest'
|
||||
|
||||
- name: Setup environment
|
||||
id: setup_env
|
||||
uses: ./.github/actions/setup-env
|
||||
|
||||
- name: Setup Ansible environment
|
||||
uses: ./.github/actions/setup-ansible-env
|
||||
with:
|
||||
project-id: ${{ secrets.BW_PROJECT_ID }}
|
||||
organization-id: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
access-token: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
ansible-user: ${{ secrets.ANSIBLE_USER }}
|
||||
trusted-hosts: ${{ secrets.TRUSTED_HOSTS }}
|
||||
|
||||
- name: Run hugo_build command
|
||||
run: bin/hugo_build
|
||||
|
||||
- name: Run the playbook to deploy websites
|
||||
env:
|
||||
BW_PROJECT_ID: ${{ secrets.BW_PROJECT_ID }}
|
||||
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
BW_ACCESS_TOKEN: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
ANSIBLE_USER: ${{ secrets.ANSIBLE_USER }}
|
||||
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
||||
CHANGED_FILES: ${{ steps.setup_env.outputs.CHANGED_FILES }}
|
||||
run: |
|
||||
cd ansible
|
||||
sectool -f ../sectool.json exec ansible-playbook -u $ANSIBLE_USER playbook_websites.yml
|
||||
@@ -9,7 +9,7 @@ on:
|
||||
paths:
|
||||
- "terraform/aws-iac/**"
|
||||
jobs:
|
||||
terraform-apply:
|
||||
iac-apply:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -21,15 +21,15 @@ jobs:
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-env
|
||||
|
||||
- name: Setup Terraform environment
|
||||
uses: ./.github/actions/setup-terraform-env
|
||||
- name: Setup OpenTofu environment
|
||||
uses: ./.github/actions/setup-opentofu-env
|
||||
|
||||
- name: Terraform Init and Apply
|
||||
- name: OpenTofu Init and Apply
|
||||
env:
|
||||
BW_PROJECT_ID: ${{ secrets.BW_PROJECT_ID }}
|
||||
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
BW_ACCESS_TOKEN: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
run: |
|
||||
cd terraform/aws-iac
|
||||
sectool -f ../../sectool.json exec terraform init
|
||||
sectool -f ../../sectool.json exec terraform apply --auto-approve
|
||||
sectool -f ../../sectool.json exec tofu init
|
||||
sectool -f ../../sectool.json exec tofu apply --auto-approve
|
||||
|
||||
@@ -11,7 +11,7 @@ on:
|
||||
- synchronize
|
||||
- reopened
|
||||
jobs:
|
||||
terraform-validate:
|
||||
iac-validate:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -23,17 +23,17 @@ jobs:
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-env
|
||||
|
||||
- name: Setup Terraform environment
|
||||
uses: ./.github/actions/setup-terraform-env
|
||||
- name: Setup OpenTofu environment
|
||||
uses: ./.github/actions/setup-opentofu-env
|
||||
|
||||
- name: Terraform Init and Validate
|
||||
- name: OpenTofu Init and Validate
|
||||
env:
|
||||
BW_PROJECT_ID: ${{ secrets.BW_PROJECT_ID }}
|
||||
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
BW_ACCESS_TOKEN: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
run: |
|
||||
cd terraform/aws-iac
|
||||
sectool -f ../../sectool.json exec terraform init
|
||||
sectool -f ../../sectool.json exec terraform validate
|
||||
sectool -f ../../sectool.json exec terraform fmt -check
|
||||
sectool -f ../../sectool.json exec terraform plan
|
||||
sectool -f ../../sectool.json exec tofu init
|
||||
sectool -f ../../sectool.json exec tofu validate
|
||||
sectool -f ../../sectool.json exec tofu fmt -check
|
||||
sectool -f ../../sectool.json exec tofu plan
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
name: Terraform CLouDNS IAC Apply
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 1 * * 0"
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "terraform/cloudns-iac/**"
|
||||
jobs:
|
||||
iac-apply:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-env
|
||||
|
||||
- name: Setup OpenTofu environment
|
||||
uses: ./.github/actions/setup-opentofu-env
|
||||
|
||||
- name: OpenTofu Init and Apply
|
||||
env:
|
||||
BW_PROJECT_ID: ${{ secrets.BW_PROJECT_ID }}
|
||||
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
BW_ACCESS_TOKEN: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
run: |
|
||||
cd terraform/cloudns-iac
|
||||
sectool -f ../../sectool.json exec tofu init
|
||||
sectool -f ../../sectool.json exec tofu apply --auto-approve
|
||||
@@ -0,0 +1,39 @@
|
||||
name: Terraform ClouDNS IAC Validate on Pull Request
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "terraform/cloudns-iac/**"
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
jobs:
|
||||
iac-validate:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-env
|
||||
|
||||
- name: Setup OpenTofu environment
|
||||
uses: ./.github/actions/setup-opentofu-env
|
||||
|
||||
- name: OpenTofu Init and Validate
|
||||
env:
|
||||
BW_PROJECT_ID: ${{ secrets.BW_PROJECT_ID }}
|
||||
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
BW_ACCESS_TOKEN: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
run: |
|
||||
cd terraform/cloudns-iac
|
||||
sectool -f ../../sectool.json exec tofu init
|
||||
sectool -f ../../sectool.json exec tofu validate
|
||||
sectool -f ../../sectool.json exec tofu fmt -check
|
||||
sectool -f ../../sectool.json exec tofu plan
|
||||
@@ -0,0 +1,35 @@
|
||||
name: Terraform Contabo IAC Apply
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 1 * * 0"
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "terraform/contabo-iac/**"
|
||||
jobs:
|
||||
iac-apply:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-env
|
||||
|
||||
- name: Setup OpenTofu environment
|
||||
uses: ./.github/actions/setup-opentofu-env
|
||||
|
||||
- name: OpenTofu Init and Apply
|
||||
env:
|
||||
BW_PROJECT_ID: ${{ secrets.BW_PROJECT_ID }}
|
||||
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
BW_ACCESS_TOKEN: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
run: |
|
||||
cd terraform/contabo-iac
|
||||
sectool -f ../../sectool.json exec tofu init
|
||||
sectool -f ../../sectool.json exec tofu apply --auto-approve
|
||||
@@ -0,0 +1,39 @@
|
||||
name: Terraform Contabo IAC Validate on Pull Request
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "terraform/contabo-iac/**"
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
jobs:
|
||||
iac-validate:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-env
|
||||
|
||||
- name: Setup OpenTofu environment
|
||||
uses: ./.github/actions/setup-opentofu-env
|
||||
|
||||
- name: OpenTofu Init and Validate
|
||||
env:
|
||||
BW_PROJECT_ID: ${{ secrets.BW_PROJECT_ID }}
|
||||
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
BW_ACCESS_TOKEN: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
run: |
|
||||
cd terraform/contabo-iac
|
||||
sectool -f ../../sectool.json exec tofu init
|
||||
sectool -f ../../sectool.json exec tofu validate
|
||||
sectool -f ../../sectool.json exec tofu fmt -check
|
||||
sectool -f ../../sectool.json exec tofu plan
|
||||
@@ -1,60 +0,0 @@
|
||||
name: Terraform IAC Validate on Pull Request
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "terraform/iac/**"
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
jobs:
|
||||
terraform-validate:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-env
|
||||
|
||||
- name: Setup Ansible environment
|
||||
uses: ./.github/actions/setup-ansible-env
|
||||
with:
|
||||
project-id: ${{ secrets.BW_PROJECT_ID }}
|
||||
organization-id: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
access-token: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
ansible-user: ${{ secrets.ANSIBLE_USER }}
|
||||
host-group: iac
|
||||
|
||||
- name: Get Host Info
|
||||
uses: ./.github/actions/get-host-info
|
||||
id: get-host-info
|
||||
with:
|
||||
project-id: ${{ secrets.BW_PROJECT_ID }}
|
||||
organization-id: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
access-token: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
ansible-user: ${{ secrets.ANSIBLE_USER }}
|
||||
target-host: iac
|
||||
|
||||
- name: Setup Terraform environment
|
||||
uses: ./.github/actions/setup-terraform-env
|
||||
|
||||
- name: Terraform Init and Validate
|
||||
env:
|
||||
BW_PROJECT_ID: ${{ secrets.BW_PROJECT_ID }}
|
||||
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
BW_ACCESS_TOKEN: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
SYSTEM_ID: ${{ steps.get-host-info.outputs.system-id }}
|
||||
run: |
|
||||
cd terraform/iac
|
||||
export TF_VAR_system_id=$SYSTEM_ID
|
||||
sectool -f ../../sectool.json exec terraform init
|
||||
sectool -f ../../sectool.json exec terraform validate
|
||||
sectool -f ../../sectool.json exec terraform fmt -check
|
||||
sectool -f ../../sectool.json exec terraform plan
|
||||
+7
-7
@@ -1,4 +1,4 @@
|
||||
name: Terraform K8S Apps apply
|
||||
name: OpenTofu K8S Apps apply
|
||||
|
||||
on:
|
||||
schedule:
|
||||
@@ -9,7 +9,7 @@ on:
|
||||
paths:
|
||||
- "terraform/k8sapps/**"
|
||||
jobs:
|
||||
terraform-apply:
|
||||
iac-apply:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -31,8 +31,8 @@ jobs:
|
||||
ansible-user: ${{ secrets.ANSIBLE_USER }}
|
||||
host-group: microk8s
|
||||
|
||||
- name: Setup Terraform Environment
|
||||
uses: ./.github/actions/setup-terraform-env
|
||||
- name: Setup OpenTofu Environment
|
||||
uses: ./.github/actions/setup-opentofu-env
|
||||
|
||||
- name: Setup Kubernetes Environment
|
||||
uses: ./.github/actions/setup-k8s-env
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
access-token: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
ansible-user: ${{ secrets.ANSIBLE_USER }}
|
||||
|
||||
- name: Terraform Init and Apply
|
||||
- name: OpenTofu Init and Apply
|
||||
env:
|
||||
BW_PROJECT_ID: ${{ secrets.BW_PROJECT_ID }}
|
||||
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
@@ -51,5 +51,5 @@ jobs:
|
||||
SSH_AUTH_SOCK: ${{ steps.setup_ansible_env.outputs.ssh-auth-sock }}
|
||||
run: |
|
||||
cd terraform/k8sapps
|
||||
sectool -f ../../sectool.json exec terraform init
|
||||
sectool -f ../../sectool.json exec terraform apply --auto-approve
|
||||
sectool -f ../../sectool.json exec tofu init
|
||||
sectool -f ../../sectool.json exec tofu apply --auto-approve
|
||||
+9
-9
@@ -1,4 +1,4 @@
|
||||
name: Terraform K8s Apps Validate on Pull Request
|
||||
name: OpenTofu K8s Apps Validate on Pull Request
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -11,7 +11,7 @@ on:
|
||||
- synchronize
|
||||
- reopened
|
||||
jobs:
|
||||
terraform-validate:
|
||||
iac-validate:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -33,8 +33,8 @@ jobs:
|
||||
ansible-user: ${{ secrets.ANSIBLE_USER }}
|
||||
host-group: microk8s
|
||||
|
||||
- name: Setup Terraform Environment
|
||||
uses: ./.github/actions/setup-terraform-env
|
||||
- name: Setup OpenTofu Environment
|
||||
uses: ./.github/actions/setup-opentofu-env
|
||||
|
||||
- name: Setup Kubernetes Environment
|
||||
uses: ./.github/actions/setup-k8s-env
|
||||
@@ -44,14 +44,14 @@ jobs:
|
||||
access-token: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
ansible-user: ${{ secrets.ANSIBLE_USER }}
|
||||
|
||||
- name: Terraform Init and Validate
|
||||
- name: OpenTofu Init and Validate
|
||||
env:
|
||||
BW_PROJECT_ID: ${{ secrets.BW_PROJECT_ID }}
|
||||
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
BW_ACCESS_TOKEN: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
run: |
|
||||
cd terraform/k8sapps
|
||||
sectool -f ../../sectool.json exec terraform init
|
||||
sectool -f ../../sectool.json exec terraform validate
|
||||
sectool -f ../../sectool.json exec terraform fmt -check
|
||||
sectool -f ../../sectool.json exec terraform plan
|
||||
sectool -f ../../sectool.json exec tofu init
|
||||
sectool -f ../../sectool.json exec tofu validate
|
||||
sectool -f ../../sectool.json exec tofu fmt -check
|
||||
sectool -f ../../sectool.json exec tofu plan
|
||||
+9
-9
@@ -1,4 +1,4 @@
|
||||
name: Terraform IAC Apply
|
||||
name: OpenTofu Scaleway IAC Apply
|
||||
|
||||
on:
|
||||
schedule:
|
||||
@@ -7,9 +7,9 @@ on:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "terraform/iac/**"
|
||||
- "terraform/scaleway-iac/**"
|
||||
jobs:
|
||||
terraform-apply:
|
||||
iac-apply:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -40,17 +40,17 @@ jobs:
|
||||
ansible-user: ${{ secrets.ANSIBLE_USER }}
|
||||
target-host: iac
|
||||
|
||||
- name: Setup Terraform environment
|
||||
uses: ./.github/actions/setup-terraform-env
|
||||
- name: Setup OpenTofu environment
|
||||
uses: ./.github/actions/setup-opentofu-env
|
||||
|
||||
- name: Terraform Init and Apply
|
||||
- name: OpenTofu Init and Apply
|
||||
env:
|
||||
BW_PROJECT_ID: ${{ secrets.BW_PROJECT_ID }}
|
||||
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
BW_ACCESS_TOKEN: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
SYSTEM_ID: ${{ steps.get-host-info.outputs.system-id }}
|
||||
run: |
|
||||
cd terraform/iac
|
||||
cd terraform/scaleway-iac
|
||||
export TF_VAR_system_id=$SYSTEM_ID
|
||||
sectool -f ../../sectool.json exec terraform init
|
||||
sectool -f ../../sectool.json exec terraform apply --auto-approve
|
||||
sectool -f ../../sectool.json exec tofu init
|
||||
sectool -f ../../sectool.json exec tofu apply --auto-approve
|
||||
@@ -0,0 +1,39 @@
|
||||
name: Terraform Scaleway IAC Validate on Pull Request
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "terraform/scaleway-iac/**"
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
jobs:
|
||||
iac-validate:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-env
|
||||
|
||||
- name: Setup OpenTofu environment
|
||||
uses: ./.github/actions/setup-opentofu-env
|
||||
|
||||
- name: OpenTofu Init and Validate
|
||||
env:
|
||||
BW_PROJECT_ID: ${{ secrets.BW_PROJECT_ID }}
|
||||
BW_ORGANIZATION_ID: ${{ secrets.BW_ORGANIZATION_ID }}
|
||||
BW_ACCESS_TOKEN: ${{ secrets.BW_ACCESS_TOKEN }}
|
||||
run: |
|
||||
cd terraform/scaleway-iac
|
||||
sectool -f ../../sectool.json exec tofu init
|
||||
sectool -f ../../sectool.json exec tofu validate
|
||||
sectool -f ../../sectool.json exec tofu fmt -check
|
||||
sectool -f ../../sectool.json exec tofu plan
|
||||
@@ -42,3 +42,4 @@ drafts/*
|
||||
.molecule
|
||||
*.auto.tfvars
|
||||
dev/*
|
||||
.ansible
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "websites/themes/hugo-profile"]
|
||||
path = websites/themes/hugo-profile
|
||||
url = https://github.com/gurusabarish/hugo-profile.git
|
||||
@@ -17,4 +17,13 @@ code DELETE immediately. We have been warned.
|
||||
./bin/occ db:add-missing-primary-keys
|
||||
# Disable maintenance
|
||||
./bin/occ maintenance:mode --off
|
||||
```
|
||||
|
||||
# Contabo CLI
|
||||
|
||||
Download latest version from [here](https://github.com/contabo/cntb/releases).
|
||||
|
||||
Setup:
|
||||
```
|
||||
sectool exec cntb get instances --oauth2-clientid="$CONTABO_CLIENT_ID" --oauth2-client-secret="$CONTABO_CLIENT_SECRET" --oauth2-user="$CONTABO_API_USER" --oauth2-password="$CONTABO_API_PASSWORD"
|
||||
```
|
||||
@@ -1 +0,0 @@
|
||||
../repository.vault
|
||||
@@ -0,0 +1,76 @@
|
||||
hostname: dev-01.alexpires.local
|
||||
ansible_user: "{{ lookup('env', 'ANSIBLE_USER') }}"
|
||||
|
||||
# Users
|
||||
login_users:
|
||||
- username: "{{ ansible_user }}"
|
||||
comment: "Managed by Ansible"
|
||||
sudoer: true
|
||||
sudoer_root_only: true
|
||||
sudoer_no_password: true
|
||||
pubkey: "{{ lookup('file', 'keys/ansible_user.pub') }}"
|
||||
password_disabled: true
|
||||
- username: operator
|
||||
comment: "Managed by Ansible"
|
||||
sudoer: true
|
||||
pubkey: "{{ lookup('file', 'keys/operator.pub') }}"
|
||||
|
||||
# SSH Connection and security
|
||||
sshd_port: 22
|
||||
ssh_allowed_networks:
|
||||
- "0.0.0.0/0"
|
||||
sshd_admin_net: "0.0.0.0/0"
|
||||
sshd_allow_groups: "{{ ansible_user }} users"
|
||||
sshd_permit_root_login: "no"
|
||||
sshd_password_authentication: "no"
|
||||
sshd_allow_tcp_forwarding: "yes"
|
||||
|
||||
# Due to an issue increase the number of max auth tries
|
||||
sshd_max_auth_tries: 10
|
||||
|
||||
# Firewall ports
|
||||
ufw_enable: true
|
||||
fw_allowed_ports:
|
||||
- { rule: "allow", port: "80", proto: "tcp" }
|
||||
- { rule: "allow", port: "443", proto: "tcp" }
|
||||
- { rule: "allow", port: "22", proto: "tcp" }
|
||||
|
||||
ufw_outgoing_traffic:
|
||||
- 22 # SSH
|
||||
- 53 # DNS
|
||||
- 80 # HTTP
|
||||
- 123 # NTP
|
||||
- 443 # HTTPS
|
||||
- 853 # DNS over TLS
|
||||
|
||||
ufw_default_forward_policy: "ACCEPT"
|
||||
|
||||
ipv4_sysctl_settings:
|
||||
net.ipv4.ip_forward: 1
|
||||
|
||||
disable_ipv6: true
|
||||
|
||||
# geoip will override hosts_allow and hosts_deny (so it's disabled - CIS hardening)
|
||||
custom_hosts_acls: true
|
||||
|
||||
# fail2ban
|
||||
fail2ban_jails:
|
||||
ssh:
|
||||
enabled: true
|
||||
port: "{{ sshd_port }}"
|
||||
filter: "sshd"
|
||||
logpath: "/var/log/auth.log"
|
||||
maxretry: 5
|
||||
findtime: 600
|
||||
bantime: 3600
|
||||
|
||||
# aide
|
||||
install_aide: false
|
||||
|
||||
# Unattended upgrades
|
||||
unattended_reboot: true
|
||||
unattended_reboot_time: "04:30"
|
||||
|
||||
# Duo Security
|
||||
duo_users: ["*", "!provision"]
|
||||
duo_api_hostname: api-7cda1654.duosecurity.com
|
||||
@@ -93,6 +93,20 @@ fail2ban_jails:
|
||||
maxretry: 5
|
||||
findtime: 600
|
||||
bantime: 3600
|
||||
postfix:
|
||||
enabled: true
|
||||
port: "smtp,ssmtp"
|
||||
filter: "postfix-k8s"
|
||||
logpath: "/var/log/postfix/current"
|
||||
maxretry: 3
|
||||
findtime: 18000
|
||||
bantime: -1
|
||||
|
||||
fail2ban_filters:
|
||||
postfix-k8s:
|
||||
Definition:
|
||||
failregex: "^.*?postfix/smtps/smtpd\\[\\d+\\]:.*\\[<HOST>\\]: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed.*$"
|
||||
ignoreregex: ""
|
||||
|
||||
# aide
|
||||
install_aide: true
|
||||
@@ -124,6 +138,10 @@ encryption_volumes:
|
||||
mount_service_before: snap.microk8s.daemon-kubelite.service
|
||||
mount_service_wantedby: snap.microk8s.daemon-kubelite.service
|
||||
mount_permission: "0755"
|
||||
encryption_aws_access_key_id: "{{ lookup('env', 'KMS_ACCESS_KEY') }}"
|
||||
encryption_aws_secret_access_key: "{{ lookup('env', 'KMS_SECRET_KEY') }}"
|
||||
encryption_kms_arn: "arn:aws:kms:eu-west-1:001604727293:key/977d08fd-8230-40bf-8a4f-d8a3264c5990"
|
||||
encryption_kms_socket: /var/run/kmsplugin/socket.sock
|
||||
|
||||
# Kubernetes specific settings
|
||||
microk8s_version: 1.29
|
||||
@@ -135,6 +153,7 @@ microk8s_alt_names: "{{ hostname }}"
|
||||
microk8s_issuer_email: c.alexandre.pires@alexpires.me
|
||||
microk8s_encryption_cfg: /mnt/microk8s_config/microk8s_encryption.yaml
|
||||
microk8s_encryption_secret: "{{ lookup('env', 'MICROK8S_ENCRYPTION_SECRET') }}"
|
||||
microk8s_encryption_kms_socket: /var/run/kmsplugin/socket.sock
|
||||
microk8s_users:
|
||||
- username: operator
|
||||
enabled: true
|
||||
@@ -149,3 +168,7 @@ duo_api_hostname: api-7cda1654.duosecurity.com
|
||||
# Apps
|
||||
persistent_data: "/mnt/microk8s_persistent"
|
||||
database_path: "/var/lib"
|
||||
|
||||
# Websites
|
||||
websites:
|
||||
- "alexpires.me"
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
- name: CIS Hardening
|
||||
hosts: linux
|
||||
gather_facts: true
|
||||
|
||||
roles:
|
||||
- role: "cis"
|
||||
tags:
|
||||
- roles
|
||||
- roles::cis
|
||||
- role: "fail2ban"
|
||||
tags:
|
||||
- roles
|
||||
- roles::fail2ban
|
||||
- role: "geoip"
|
||||
tags:
|
||||
- roles
|
||||
- roles::geoip
|
||||
- role: "duo"
|
||||
tags:
|
||||
- roles
|
||||
- roles::duosecurity
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: Duo Security
|
||||
hosts: public
|
||||
gather_facts: true
|
||||
|
||||
roles:
|
||||
- role: "duo"
|
||||
tags:
|
||||
- roles
|
||||
- roles::duosecurity
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
- name: Setup encrypted volumes
|
||||
hosts: linux
|
||||
hosts: public
|
||||
gather_facts: true
|
||||
|
||||
roles:
|
||||
@@ -8,3 +8,5 @@
|
||||
tags:
|
||||
- roles
|
||||
- roles::encryption
|
||||
- roles::encryption::kms
|
||||
- roles::encryption::volume
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: Fail2Ban
|
||||
hosts: public
|
||||
gather_facts: true
|
||||
|
||||
roles:
|
||||
- role: "fail2ban"
|
||||
tags:
|
||||
- roles
|
||||
- roles::fail2ban
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: Fail2Ban
|
||||
hosts: public
|
||||
gather_facts: true
|
||||
|
||||
roles:
|
||||
- role: "geoip"
|
||||
tags:
|
||||
- roles
|
||||
- roles::geoip
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
- name: CIS Hardening
|
||||
hosts: localnetwork
|
||||
hosts: hardening
|
||||
gather_facts: true
|
||||
|
||||
roles:
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
- name: Login setup
|
||||
hosts: linux
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
roles:
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
- name: Set required facts
|
||||
ansible.builtin.set_fact:
|
||||
mail_folders:
|
||||
mail_folders:
|
||||
- "{{ mail_home }}/getmail"
|
||||
- "{{ mail_home }}/mailboxes"
|
||||
tags: always
|
||||
@@ -54,7 +54,7 @@
|
||||
mode: "0750"
|
||||
owner: "{{ postfix_user_id }}"
|
||||
group: "{{ postfix_group_id }}"
|
||||
loop:
|
||||
loop:
|
||||
- "{{ mail_home }}/postfix"
|
||||
tags:
|
||||
- tasks
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
---
|
||||
- name: Wordpress Playbook (K8s)
|
||||
hosts: wordpress
|
||||
- name: SFTPGo Playbook (K8s)
|
||||
hosts: sftpgo
|
||||
gather_facts: true
|
||||
|
||||
# Specific tasks for this playbook
|
||||
tasks:
|
||||
- name: Set required facts
|
||||
ansible.builtin.set_fact:
|
||||
wordpress_home: "{{ persistent_data | default('/var/lib') }}/wordpress"
|
||||
wordpress_mysql_home: "{{ database_path | default('/var/lib') }}/mysql.wordpress"
|
||||
wordpress_user_id: 33
|
||||
wordpress_group_id: 26
|
||||
sftpgo_home: "{{ persistent_data | default('/var/lib') }}/sftpgo"
|
||||
sftpgo_mysql_home: "{{ database_path | default('/var/lib') }}/mysql.sftpgo"
|
||||
sftpgo_user_id: 1000
|
||||
sftpgo_group_id: 1000
|
||||
mysql_user_id: 999
|
||||
mysql_group_id: 107
|
||||
tags: always
|
||||
|
||||
- name: Create required wordpress data folder
|
||||
- name: Create required sftpgo data folder
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
path: "{{ wordpress_home }}"
|
||||
path: "{{ sftpgo_home }}"
|
||||
mode: "0750"
|
||||
owner: "{{ wordpress_user_id }}"
|
||||
group: "{{ wordpress_group_id }}"
|
||||
owner: "{{ sftpgo_user_id }}"
|
||||
group: "{{ sftpgo_group_id }}"
|
||||
tags:
|
||||
- tasks
|
||||
- tasks::folders
|
||||
@@ -31,8 +31,8 @@
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
path: "{{ wordpress_mysql_home }}"
|
||||
mode: "0750"
|
||||
path: "{{ sftpgo_mysql_home }}"
|
||||
mode: "0755"
|
||||
owner: "{{ mysql_user_id }}"
|
||||
group: "{{ mysql_group_id }}"
|
||||
tags:
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
- name: Trivy Playbook (K8s)
|
||||
hosts: trivy
|
||||
gather_facts: true
|
||||
|
||||
# Specific tasks for this playbook
|
||||
tasks:
|
||||
- name: Set required facts
|
||||
ansible.builtin.set_fact:
|
||||
trivy_home: "{{ persistent_data | default('/var/lib') }}/trivy"
|
||||
trivy_user_id: 1000
|
||||
trivy_group_id: 1000
|
||||
tags: always
|
||||
|
||||
- name: Create required trivy data folder
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
path: "{{ item }}"
|
||||
mode: "0750"
|
||||
owner: "{{ trivy_user_id }}"
|
||||
group: "{{ trivy_group_id }}"
|
||||
with_items:
|
||||
- "{{ trivy_home }}"
|
||||
- "{{ trivy_home }}/cache"
|
||||
tags:
|
||||
- tasks
|
||||
- tasks::folders
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
- name: Websites (Static Files) Playbook (K8s)
|
||||
hosts: web
|
||||
gather_facts: true
|
||||
|
||||
# Specific tasks for this playbook
|
||||
tasks:
|
||||
- name: Set required facts
|
||||
ansible.builtin.set_fact:
|
||||
web_home: "{{ persistent_data | default('/var/lib') }}/web"
|
||||
web_user_id: 1000
|
||||
web_group_id: 1000
|
||||
tags: always
|
||||
|
||||
- name: Create required web data folder
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
path: "{{ web_home }}"
|
||||
mode: "0750"
|
||||
owner: "{{ web_user_id }}"
|
||||
group: "{{ web_group_id }}"
|
||||
tags:
|
||||
- tasks
|
||||
- tasks::folders
|
||||
|
||||
- name: Create required web data folder
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
path: "{{ web_home }}/{{ item }}"
|
||||
mode: "0750"
|
||||
owner: "{{ web_user_id }}"
|
||||
group: "{{ web_group_id }}"
|
||||
with_items:
|
||||
- "{{ websites | default([]) }}"
|
||||
tags:
|
||||
- tasks
|
||||
- tasks::folders
|
||||
|
||||
- name: Synchronize websites
|
||||
become: true
|
||||
ansible.posix.synchronize:
|
||||
mode: push
|
||||
src: "{{ lookup('env', 'GITHUB_WORKSPACE') + '/websites/releases/' + item }}/"
|
||||
dest: "{{ web_home }}/{{ item }}"
|
||||
delete: true
|
||||
recursive: true
|
||||
with_items:
|
||||
- "{{ websites | default([]) }}"
|
||||
@@ -199,7 +199,10 @@
|
||||
|
||||
- name: Install Extras and HA for RHEL7
|
||||
become: true
|
||||
ansible.builtin.command: subscription-manager repos --enable "rhel-*-optional-rpms" --enable "rhel-*-extras-rpms" --enable "rhel-ha-for-rhel-*-server-rpms"
|
||||
ansible.builtin.command: >
|
||||
subscription-manager repos --enable "rhel-*-optional-rpms"
|
||||
--enable "rhel-*-extras-rpms"
|
||||
--enable "rhel-ha-for-rhel-*-server-rpms"
|
||||
changed_when: false
|
||||
tags:
|
||||
- dnf
|
||||
|
||||
@@ -2,3 +2,9 @@
|
||||
encryption_volumes: []
|
||||
encryption_volumes_path: /var/lib/encrypted_volumes
|
||||
encryption_volumes_default_size: 1G
|
||||
|
||||
encryption_aws_access_key_id:
|
||||
encryption_aws_secret_access_key:
|
||||
encryption_kms_arn:
|
||||
encryption_kms_region: eu-west-1
|
||||
encryption_kms_socket: /var/run/kmsplugin/socket.sock
|
||||
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
- name: Check if required facts are set
|
||||
ansible.builtin.fail:
|
||||
msg: "The following variables are required: encryption_aws_access_key_id, encryption_aws_secret_access_key, encryption_kms_arn"
|
||||
when:
|
||||
- encryption_aws_access_key_id is not defined
|
||||
- encryption_aws_secret_access_key is not defined
|
||||
- encryption_kms_arn is not defined
|
||||
|
||||
- name: Copy aws-encryption-provider binary to the host
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: aws-encryption-provider
|
||||
dest: /usr/local/bin/aws-encryption-provider
|
||||
mode: '0755'
|
||||
|
||||
- name: Copy start script to the host
|
||||
become: true
|
||||
ansible.builtin.template:
|
||||
src: start-encryption-provider.sh.j2
|
||||
dest: /usr/local/bin/start-encryption-provider.sh
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create KMS socket directory
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: /var/run/kmsplugin
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create systemd service file for aws-encryption-provider
|
||||
become: true
|
||||
ansible.builtin.template:
|
||||
src: aws-encryption-provider.service.j2
|
||||
dest: /etc/systemd/system/aws-encryption-provider.service
|
||||
mode: '0644'
|
||||
|
||||
- name: Reload systemd daemon
|
||||
become: true
|
||||
ansible.builtin.systemd:
|
||||
daemon_reload: true
|
||||
name: aws-encryption-provider
|
||||
|
||||
- name: Enable aws-encryption-provider service
|
||||
become: true
|
||||
ansible.builtin.systemd:
|
||||
name: aws-encryption-provider
|
||||
enabled: true
|
||||
|
||||
- name: Start aws-encryption-provider service
|
||||
become: true
|
||||
ansible.builtin.systemd:
|
||||
name: aws-encryption-provider
|
||||
state: started
|
||||
@@ -5,8 +5,12 @@
|
||||
name:
|
||||
- cryptsetup
|
||||
- curl
|
||||
- libc6
|
||||
state: present
|
||||
when: ansible_os_family == 'Debian'
|
||||
tags:
|
||||
- roles::encryption::packages
|
||||
- roles::encryption::volume
|
||||
|
||||
- name: Create folder to store volume
|
||||
become: true
|
||||
@@ -14,6 +18,8 @@
|
||||
path: "{{ encryption_volumes_path }}"
|
||||
state: directory
|
||||
mode: "0750"
|
||||
tags:
|
||||
- roles::encryption::volume
|
||||
|
||||
- name: Copy required scripts
|
||||
become: true
|
||||
@@ -24,9 +30,19 @@
|
||||
with_items:
|
||||
- "open_volume"
|
||||
- "read_system_id"
|
||||
tags:
|
||||
- roles::encryption::volume
|
||||
|
||||
- name: Create encrypted volumes
|
||||
ansible.builtin.include_tasks: volume.yml
|
||||
loop: "{{ encryption_volumes }}"
|
||||
loop_control:
|
||||
loop_var: item
|
||||
tags:
|
||||
- roles::encryption::volume
|
||||
|
||||
- name: Create KMS service
|
||||
ansible.builtin.include_tasks: kms.yml
|
||||
when: encryption_aws_access_key_id is defined and encryption_aws_secret_access_key is defined and encryption_kms_arn is defined
|
||||
tags:
|
||||
- roles::encryption::kms
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
- name: Read system id
|
||||
ansible.builtin.command: |
|
||||
read_system_id
|
||||
changed_when: false
|
||||
register: system_id
|
||||
|
||||
- name: Download key file from Key server
|
||||
@@ -88,45 +89,17 @@
|
||||
|
||||
- name: Create service to fetch key file and open LUKS device
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
ansible.builtin.template:
|
||||
src: key_fetch.service.j2
|
||||
dest: /etc/systemd/system/{{ key_fetch_service }}
|
||||
mode: "0644"
|
||||
content: |
|
||||
[Unit]
|
||||
Description={{ item.name }} key fetch service
|
||||
After={{ fetch_key_service_after }}
|
||||
Before={{ fetch_key_service_before }}
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=true
|
||||
ExecStart=/usr/local/bin/open_volume "{{ key_server }}" {{ disk_image_path }} {{ device_name }}
|
||||
ExecStop=/usr/sbin/cryptsetup close {{ device_name }}
|
||||
|
||||
[Install]
|
||||
WantedBy={{ fetch_key_service_wantedby }}
|
||||
|
||||
- name: Create service to mount the local filesystem
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
ansible.builtin.template:
|
||||
src: mount.service.j2
|
||||
dest: /etc/systemd/system/{{ mount_service }}
|
||||
mode: "0644"
|
||||
content: |
|
||||
[Unit]
|
||||
|
||||
Description={{ item.name }} mount service
|
||||
After={{ key_fetch_service }}
|
||||
Requires={{ key_fetch_service }}
|
||||
Before={{ mount_service_before }}
|
||||
|
||||
[Mount]
|
||||
What=/dev/mapper/{{ device_name }}
|
||||
Where={{ mount_point }}
|
||||
Type=ext4
|
||||
Options=defaults
|
||||
|
||||
[Install]
|
||||
WantedBy={{ mount_service_wantedby }}
|
||||
|
||||
- name: Reload systemd daemon
|
||||
become: true
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=AWS Encryption Provider
|
||||
After=network.target
|
||||
Before=snap.microk8s.daemon-kubelite.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/start-encryption-provider.sh
|
||||
Restart=on-failure
|
||||
User=root
|
||||
|
||||
[Install]
|
||||
WantedBy=snap.microk8s.daemon-kubelite.service
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description={{ item.name }} key fetch service
|
||||
After={{ fetch_key_service_after }}
|
||||
Before={{ fetch_key_service_before }}
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=true
|
||||
ExecStart=/usr/local/bin/open_volume "{{ key_server }}" {{ disk_image_path }} {{ device_name }}
|
||||
ExecStop=/usr/sbin/cryptsetup close {{ device_name }}
|
||||
|
||||
[Install]
|
||||
WantedBy={{ fetch_key_service_wantedby }}
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description={{ item.name }} mount service
|
||||
After={{ key_fetch_service }}
|
||||
Requires={{ key_fetch_service }}
|
||||
Before={{ mount_service_before }}
|
||||
|
||||
[Mount]
|
||||
What=/dev/mapper/{{ device_name }}
|
||||
Where={{ mount_point }}
|
||||
Type=ext4
|
||||
Options=defaults
|
||||
|
||||
[Install]
|
||||
WantedBy={{ mount_service_wantedby }}
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
# This script is used to start the encryption provider for the application.
|
||||
# Managed by Ansible.
|
||||
export AWS_ACCESS_KEY_ID={{ encryption_aws_access_key_id }}
|
||||
export AWS_SECRET_ACCESS_KEY={{ encryption_aws_secret_access_key }}
|
||||
/usr/local/bin/aws-encryption-provider --key={{ encryption_kms_arn }} --region={{ encryption_kms_region }} --listen={{ encryption_kms_socket }}
|
||||
@@ -6,7 +6,7 @@ microk8s_lb_provider: "metallb"
|
||||
microk8s_lb_ips: "10.2.0.40-10.2.0.49"
|
||||
microk8s_lb_http_port: 80
|
||||
microk8s_lb_https_port: 443
|
||||
microk8s_metallb_version: 0.14.5
|
||||
microk8s_metallb_version: 0.14.9
|
||||
|
||||
# certificate manager
|
||||
microk8s_issuer_email: webmaster@localhost.localdomain
|
||||
@@ -39,3 +39,4 @@ microk8s_iac_user: "provision"
|
||||
|
||||
microk8s_encryption_secret: "a13labs"
|
||||
microk8s_encryption_cfg: "/etc/microk8s_encryption.yaml"
|
||||
microk8s_encryption_kms_socket:
|
||||
|
||||
@@ -7,21 +7,8 @@
|
||||
|
||||
- name: Create encryption configuration
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
content: |
|
||||
---
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: EncryptionConfiguration
|
||||
resources:
|
||||
- resources:
|
||||
- secrets
|
||||
- configmaps
|
||||
providers:
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: k8s-crypto
|
||||
secret: {{ microk8s_encryption_secret }}
|
||||
- identity: {}
|
||||
ansible.builtin.template:
|
||||
src: encryption-provider-config.yml.j2
|
||||
dest: "{{ microk8s_encryption_cfg }}"
|
||||
mode: "0600"
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: EncryptionConfiguration
|
||||
resources:
|
||||
- resources:
|
||||
- secrets
|
||||
- configmaps
|
||||
providers:
|
||||
{% if microk8s_encryption_kms_socket is defined %}
|
||||
- kms:
|
||||
apiVersion: v2
|
||||
name: aws-encryption-provider
|
||||
endpoint: unix://{{ microk8s_encryption_kms_socket }}
|
||||
timeout: 3s
|
||||
{% endif %}
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: k8s-crypto
|
||||
secret: {{ microk8s_encryption_secret }}
|
||||
- identity: {}
|
||||
@@ -7,3 +7,6 @@ USER_PASSWORD_OPERATOR=$USER_PASSWORD_OPERATOR
|
||||
ANSIBLE_FORCE_COLOR=True
|
||||
BUCKET_SUFFIX=$BUCKET_SUFFIX
|
||||
MICROK8S_ENCRYPTION_SECRET=$MICROK8S_ENCRYPTION_SECRET
|
||||
KMS_ACCESS_KEY=$KMS_ACCESS_KEY
|
||||
KMS_SECRET_KEY=$KMS_SECRET_KEY
|
||||
KMS_KEY_ARN=$KMS_KEY_ARN
|
||||
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# This script is used to build a Hugo site and prepare it for deployment.
|
||||
GITHUB_WORKSPACE=${GITHUB_WORKSPACE:-$(pwd)}
|
||||
|
||||
command -v hugo >/dev/null 2>&1 || { echo >&2 "Hugo is not installed. Please install Hugo to use this script."; exit 1; }
|
||||
|
||||
mkdir -p "$GITHUB_WORKSPACE/websites/releases"
|
||||
|
||||
for dir in $(find "$GITHUB_WORKSPACE/websites" -maxdepth 1 -type d | grep -vE '^\.$'); do
|
||||
if [ "$dir" == "$GITHUB_WORKSPACE/websites" ]; then
|
||||
echo "Skipping $dir"
|
||||
continue
|
||||
fi
|
||||
if [ "$dir" == "$GITHUB_WORKSPACE/websites/themes" ]; then
|
||||
echo "Skipping $dir"
|
||||
continue
|
||||
fi
|
||||
if [ "$dir" == "$GITHUB_WORKSPACE/websites/releases" ]; then
|
||||
echo "Skipping $dir"
|
||||
continue
|
||||
fi
|
||||
if [ -d "$dir" ]; then
|
||||
echo "Building Hugo site in $dir"
|
||||
cd "$dir" || exit 1
|
||||
hugo --minify --themesDir $GITHUB_WORKSPACE/websites/themes --destination $GITHUB_WORKSPACE/websites/releases/$(basename "$dir") --baseURL "https://$(basename "$dir").example.com"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Hugo build failed in $dir"
|
||||
exit 1
|
||||
fi
|
||||
echo "Hugo site built successfully in $dir"
|
||||
else
|
||||
echo "$dir is not a directory, skipping..."
|
||||
fi
|
||||
done
|
||||
+1
-1
@@ -24,7 +24,7 @@ def parse_ansible_inventory(inventory_file):
|
||||
|
||||
return inventory_dict
|
||||
|
||||
parser = argparse.ArgumentParser(description='Run a command on a group of hosts')
|
||||
parser = argparse.ArgumentParser(description='Get host system ID')
|
||||
parser.add_argument('group', type=str, help='Group of hosts to run the command on')
|
||||
parser.add_argument('host', type=str, help='Host to run the command on', default=None, nargs='?')
|
||||
args = parser.parse_args()
|
||||
|
||||
+18
-3
@@ -1,19 +1,28 @@
|
||||
[all]
|
||||
prod-01.alexpires.me
|
||||
dev-01.alexpires.dev
|
||||
|
||||
[linux]
|
||||
[hardening]
|
||||
prod-01.alexpires.me
|
||||
dev-01.alexpires.dev
|
||||
|
||||
[ubuntu]
|
||||
prod-01.alexpires.me
|
||||
dev-01.alexpires.dev
|
||||
|
||||
[public]
|
||||
prod-01.alexpires.me
|
||||
|
||||
[private]
|
||||
dev-01.alexpires.dev
|
||||
|
||||
[gitea]
|
||||
prod-01.alexpires.me
|
||||
|
||||
[wordpress]
|
||||
[nextcloud]
|
||||
prod-01.alexpires.me
|
||||
|
||||
[nextcloud]
|
||||
[sftpgo]
|
||||
prod-01.alexpires.me
|
||||
|
||||
[m3uproxy]
|
||||
@@ -33,3 +42,9 @@ prod-01.alexpires.me
|
||||
|
||||
[mail]
|
||||
prod-01.alexpires.me
|
||||
|
||||
[web]
|
||||
prod-01.alexpires.me
|
||||
|
||||
[trivy]
|
||||
prod-01.alexpires.me
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
bcrypt
|
||||
@@ -0,0 +1 @@
|
||||
bcrypt
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY
|
||||
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_KEY
|
||||
CONTABO_CLIENT_ID=$CONTABO_CLIENT_ID
|
||||
CONTABO_CLIENT_SECRET=$CONTABO_CLIENT_SECRET
|
||||
CONTABO_API_USER=$CONTABO_USER_NAME
|
||||
CONTABO_API_PASSWORD=$CONTABO_API_PASSWORD
|
||||
SCW_ACCESS_KEY=$SCALEWAY_ACCESS_KEY
|
||||
SCW_SECRET_KEY=$SCALEWAY_SECRET_KEY
|
||||
SCW_DEFAULT_PROJECT_ID=$SCALEWAY_PROJECT_ID
|
||||
SCW_DEFAULT_ORGANIZATION_ID=$SCALEWAY_ORGANIZATION_ID
|
||||
@@ -1 +0,0 @@
|
||||
../../repository.vault
|
||||
@@ -1,7 +1,7 @@
|
||||
terraform {
|
||||
backend "s3" {
|
||||
bucket = "a13labs.infra"
|
||||
key = "aws-alarms.tfstate"
|
||||
region = "us-east-1"
|
||||
bucket = "a13labs.infra.eu"
|
||||
key = "aws.core.infra.tfstate"
|
||||
region = "eu-west-1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
resource "aws_s3_bucket" "infra_bucket" {
|
||||
bucket = "a13labs.infra.eu"
|
||||
force_destroy = true
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_public_access_block" "infra_bucket" {
|
||||
bucket = aws_s3_bucket.infra_bucket.id
|
||||
|
||||
block_public_acls = true
|
||||
ignore_public_acls = true
|
||||
block_public_policy = true
|
||||
restrict_public_buckets = true
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_versioning" "infra_bucket" {
|
||||
bucket = aws_s3_bucket.infra_bucket.id
|
||||
|
||||
versioning_configuration {
|
||||
status = "Enabled"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_lifecycle_configuration" "infra_bucket" {
|
||||
bucket = aws_s3_bucket.infra_bucket.id
|
||||
|
||||
rule {
|
||||
id = "clenaup"
|
||||
status = "Enabled"
|
||||
filter {
|
||||
prefix = "/"
|
||||
}
|
||||
expiration {
|
||||
days = 30
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import {
|
||||
id = "a13labs.infra.eu"
|
||||
to = aws_s3_bucket.infra_bucket
|
||||
}
|
||||
|
||||
import {
|
||||
id = "a13labs.infra.eu"
|
||||
to = aws_s3_bucket_public_access_block.infra_bucket
|
||||
}
|
||||
|
||||
import {
|
||||
id = "a13labs.infra.eu"
|
||||
to = aws_s3_bucket_versioning.infra_bucket
|
||||
}
|
||||
@@ -1,5 +1,25 @@
|
||||
locals {
|
||||
region = "us-east-1"
|
||||
billing_alarm_limit = 20
|
||||
billing_alarm_emails = "c.alexandre.pires@gmail.com"
|
||||
billing_alarm_emails = "c.alexandre.pires@alexpires.me"
|
||||
instance_ips = [
|
||||
"${local.vps_1.ip}/32",
|
||||
]
|
||||
|
||||
vps_1 = {
|
||||
id = data.terraform_remote_state.contabo.outputs.instances[0].id
|
||||
name = data.terraform_remote_state.contabo.outputs.instances[0].name
|
||||
ip = data.terraform_remote_state.contabo.outputs.instances[0].ip_config[0].v4[0].ip
|
||||
}
|
||||
}
|
||||
|
||||
data "terraform_remote_state" "contabo" {
|
||||
backend = "s3"
|
||||
config = {
|
||||
bucket = "a13labs.infra.eu"
|
||||
key = "contabo.core.infra.tfstate"
|
||||
region = "eu-west-1"
|
||||
}
|
||||
}
|
||||
|
||||
data "aws_caller_identity" "current" {}
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
data "aws_iam_policy_document" "kms_key_policy" {
|
||||
statement {
|
||||
sid = "Enable IAM User Permissions"
|
||||
effect = "Allow"
|
||||
actions = ["kms:*"]
|
||||
resources = ["*"]
|
||||
|
||||
principals {
|
||||
type = "AWS"
|
||||
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
|
||||
}
|
||||
}
|
||||
|
||||
statement {
|
||||
sid = "Allow IAM User Access"
|
||||
effect = "Allow"
|
||||
actions = [
|
||||
"kms:Encrypt",
|
||||
"kms:Decrypt",
|
||||
"kms:ReEncrypt*",
|
||||
"kms:GenerateDataKey*",
|
||||
"kms:DescribeKey"
|
||||
]
|
||||
resources = ["*"]
|
||||
|
||||
principals {
|
||||
type = "AWS"
|
||||
identifiers = [aws_iam_user.k8s_secrets_user.arn]
|
||||
}
|
||||
|
||||
condition {
|
||||
# Only allow from specific IP addresses
|
||||
test = "IpAddress"
|
||||
variable = "aws:SourceIp"
|
||||
values = ["${join(",", local.instance_ips)}"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_kms_key" "k8s_secrets" {
|
||||
description = "KMS key for encrypting Kubernetes secrets"
|
||||
deletion_window_in_days = 30
|
||||
enable_key_rotation = true
|
||||
|
||||
policy = data.aws_iam_policy_document.kms_key_policy.json
|
||||
}
|
||||
|
||||
resource "aws_iam_user" "k8s_secrets_user" {
|
||||
name = "alexpires-me-microk8s"
|
||||
}
|
||||
|
||||
resource "aws_iam_access_key" "k8s_secrets_user_key" {
|
||||
user = aws_iam_user.k8s_secrets_user.name
|
||||
}
|
||||
|
||||
data "aws_iam_policy_document" "k8s_secrets_user_policy" {
|
||||
statement {
|
||||
effect = "Allow"
|
||||
|
||||
actions = [
|
||||
"kms:Encrypt",
|
||||
"kms:Decrypt",
|
||||
"kms:ReEncrypt*",
|
||||
"kms:GenerateDataKey*",
|
||||
"kms:DescribeKey"
|
||||
]
|
||||
|
||||
resources = [aws_kms_key.k8s_secrets.arn]
|
||||
condition {
|
||||
# Only allow from specific IP addresses
|
||||
test = "IpAddress"
|
||||
variable = "aws:SourceIp"
|
||||
values = ["${join(",", local.instance_ips)}"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_iam_user_policy" "k8s_secrets_user_policy" {
|
||||
name = "alexpires-me-microk8s-policy"
|
||||
user = aws_iam_user.k8s_secrets_user.name
|
||||
policy = data.aws_iam_policy_document.k8s_secrets_user_policy.json
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#
|
||||
# Copyright 2019 Alexandre Pires (alexandre.pires@mov.ai)
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# File: outputs.tf
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
variable "region" {
|
||||
description = "AWS Default region"
|
||||
default = "us-east-1"
|
||||
default = "eu-west-1"
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
terraform {
|
||||
required_version = ">= 0.13"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
terraform {
|
||||
backend "s3" {
|
||||
bucket = "a13labs.infra.eu"
|
||||
key = "cloudns.core.infra.tfstate"
|
||||
region = "eu-west-1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
locals {
|
||||
vps_1 = {
|
||||
id = data.terraform_remote_state.contabo.outputs.instances[0].id
|
||||
name = data.terraform_remote_state.contabo.outputs.instances[0].name
|
||||
ip = data.terraform_remote_state.contabo.outputs.instances[0].ip_config[0].v4[0].ip
|
||||
}
|
||||
|
||||
default_ttl = "3600"
|
||||
|
||||
domains = {
|
||||
"a13labs.me" = [
|
||||
{
|
||||
type = "A"
|
||||
value = local.vps_1.ip
|
||||
},
|
||||
{
|
||||
type = "MX"
|
||||
priority = "10"
|
||||
value = "mail-pt.securemail.pro"
|
||||
},
|
||||
{
|
||||
type = "TXT"
|
||||
value = "v=spf1 include:_spf.tem.scaleway.com include:spf.webapps.net ~all"
|
||||
},
|
||||
{
|
||||
name = "imap"
|
||||
type = "CNAME"
|
||||
value = "${local.vps_1.name}.a13labs.me"
|
||||
},
|
||||
{
|
||||
name = "mail"
|
||||
type = "CNAME"
|
||||
value = "mail-pt.securemail.pro"
|
||||
},
|
||||
{
|
||||
name = "smtp"
|
||||
type = "CNAME"
|
||||
value = "${local.vps_1.name}.a13labs.me"
|
||||
},
|
||||
{
|
||||
name = "_dmarc"
|
||||
type = "TXT"
|
||||
value = "v=DMARC1; p=none; rua=mailto:admin@a13labs.me"
|
||||
},
|
||||
{
|
||||
name = local.vps_1.name
|
||||
type = "A"
|
||||
value = local.vps_1.ip
|
||||
},
|
||||
{
|
||||
name = "_imap._tcp"
|
||||
type = "SRV"
|
||||
priority = "0"
|
||||
weight = "1"
|
||||
port = "993"
|
||||
value = "imap.a13labs.me"
|
||||
},
|
||||
{
|
||||
name = "_smtp._tcp"
|
||||
type = "SRV"
|
||||
priority = "0"
|
||||
weight = "1"
|
||||
port = "465"
|
||||
value = "smtp.a13labs.me"
|
||||
},
|
||||
{
|
||||
name = "${var.scaleway_dkim_key}._domainkey"
|
||||
type = "TXT"
|
||||
value = "v=DKIM1; h=sha256; k=rsa; p=${var.a13labs_me_scaleway_dkim_value}"
|
||||
},
|
||||
],
|
||||
"alexpires.me" = [
|
||||
{
|
||||
type = "A"
|
||||
value = local.vps_1.ip
|
||||
},
|
||||
{
|
||||
name = ""
|
||||
type = "MX"
|
||||
priority = "10"
|
||||
value = "mail-pt.securemail.pro"
|
||||
},
|
||||
{
|
||||
type = "TXT"
|
||||
value = "v=spf1 include:_spf.tem.scaleway.com include:spf.webapps.net ~all"
|
||||
},
|
||||
{
|
||||
name = "tv"
|
||||
type = "CNAME"
|
||||
value = "${local.vps_1.name}.alexpires.me"
|
||||
},
|
||||
{
|
||||
name = "www"
|
||||
type = "CNAME"
|
||||
value = "${local.vps_1.name}.alexpires.me"
|
||||
},
|
||||
{
|
||||
name = "blog"
|
||||
type = "CNAME"
|
||||
value = "${local.vps_1.name}.alexpires.me"
|
||||
},
|
||||
{
|
||||
name = "code"
|
||||
type = "CNAME"
|
||||
value = "${local.vps_1.name}.alexpires.me"
|
||||
},
|
||||
{
|
||||
name = "imap"
|
||||
type = "CNAME"
|
||||
value = "${local.vps_1.name}.alexpires.me"
|
||||
},
|
||||
{
|
||||
name = "mail"
|
||||
type = "CNAME"
|
||||
value = "mail-pt.securemail.pro"
|
||||
},
|
||||
{
|
||||
name = "smtp"
|
||||
type = "CNAME"
|
||||
value = "${local.vps_1.name}.alexpires.me"
|
||||
},
|
||||
{
|
||||
name = "cloud"
|
||||
type = "CNAME"
|
||||
value = "${local.vps_1.name}.alexpires.me"
|
||||
},
|
||||
{
|
||||
name = "_dmarc"
|
||||
type = "TXT"
|
||||
value = "v=DMARC1; p=none; rua=mailto:admin@alexpires.me"
|
||||
},
|
||||
{
|
||||
name = "prod-01"
|
||||
type = "CNAME"
|
||||
value = "${local.vps_1.name}.alexpires.me"
|
||||
},
|
||||
{
|
||||
name = "_keybase"
|
||||
type = "TXT"
|
||||
value = "keybase-site-verification=${var.keybase_site_verification}"
|
||||
},
|
||||
{
|
||||
name = "rustdesk"
|
||||
type = "CNAME"
|
||||
value = "${local.vps_1.name}.alexpires.me"
|
||||
},
|
||||
{
|
||||
name = local.vps_1.name
|
||||
type = "A"
|
||||
value = local.vps_1.ip
|
||||
},
|
||||
{
|
||||
name = "_imap._tcp"
|
||||
type = "SRV"
|
||||
priority = "0"
|
||||
weight = "1"
|
||||
port = "993"
|
||||
value = "imap.alexpires.me"
|
||||
},
|
||||
{
|
||||
name = "_smtp._tcp"
|
||||
type = "SRV"
|
||||
priority = "0"
|
||||
weight = "1"
|
||||
port = "465"
|
||||
value = "smtp.alexpires.me"
|
||||
},
|
||||
{
|
||||
name = "${var.scaleway_dkim_key}._domainkey"
|
||||
type = "TXT"
|
||||
value = "v=DKIM1; h=sha256; k=rsa; p=${var.alexpires_me_scaleway_dkim_value}"
|
||||
},
|
||||
{
|
||||
name = "webdav"
|
||||
type = "CNAME"
|
||||
value = "${local.vps_1.name}.alexpires.me"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
records = flatten([for domain, records in local.domains : [
|
||||
for record in records : {
|
||||
name = lookup(record, "name", "")
|
||||
zone = domain
|
||||
type = record.type
|
||||
value = record.value
|
||||
priority = lookup(record, "priority", null)
|
||||
weight = lookup(record, "weight", null)
|
||||
port = lookup(record, "port", null)
|
||||
}
|
||||
]])
|
||||
}
|
||||
|
||||
data "terraform_remote_state" "contabo" {
|
||||
backend = "s3"
|
||||
config = {
|
||||
bucket = "a13labs.infra.eu"
|
||||
key = "contabo.core.infra.tfstate"
|
||||
region = "eu-west-1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
terraform {
|
||||
required_version = "~>1.8"
|
||||
required_providers {
|
||||
cloudns = {
|
||||
source = "ClouDNS/cloudns"
|
||||
version = "~>1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "cloudns" {
|
||||
auth_id = var.cloudns_auth_id
|
||||
password = var.cloudns_password
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
resource "cloudns_dns_zone" "zones" {
|
||||
for_each = local.domains
|
||||
domain = each.key
|
||||
type = "master"
|
||||
}
|
||||
|
||||
import {
|
||||
for_each = local.domains
|
||||
to = cloudns_dns_zone.zones[each.key]
|
||||
id = each.key
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "records" {
|
||||
for_each = {
|
||||
for i, record in local.records :
|
||||
i => record
|
||||
}
|
||||
name = each.value.name
|
||||
zone = each.value.zone
|
||||
type = each.value.type
|
||||
value = each.value.value
|
||||
priority = lookup(each.value, "priority", null)
|
||||
weight = lookup(each.value, "weight", null)
|
||||
port = lookup(each.value, "port", null)
|
||||
ttl = lookup(each.value, "ttl", local.default_ttl)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY
|
||||
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_KEY
|
||||
TF_VAR_cloudns_auth_id=$CLOUDNS_AUTH_ID
|
||||
TF_VAR_cloudns_password=$CLOUDNS_PASSWORD
|
||||
TF_VAR_scaleway_dkim_key=$SCALEWAY_DKIM_KEY
|
||||
TF_VAR_alexpires_me_scaleway_dkim_value=$ALEXPIRES_ME_SCALEWAY_DKIM_VALUE
|
||||
TF_VAR_a13labs_me_scaleway_dkim_value=$A13LABS_ME_SCALEWAY_DKIM_VALUE
|
||||
TF_VAR_keybase_site_verification=$KEYBASE_SITE_VERIFICATION
|
||||
@@ -0,0 +1,36 @@
|
||||
variable "cloudns_auth_id" {
|
||||
description = "Cloudns Auth ID"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "cloudns_password" {
|
||||
description = "Cloudns Password"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "scaleway_dkim_key" {
|
||||
description = "Scaleway DKIM key"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "alexpires_me_scaleway_dkim_value" {
|
||||
description = "Scaleway DKIM value (alexpires.me)"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "a13labs_me_scaleway_dkim_value" {
|
||||
description = "Scaleway DKIM value (a13labs.me)"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "keybase_site_verification" {
|
||||
description = "Keybase site verification"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
terraform {
|
||||
backend "s3" {
|
||||
bucket = "a13labs.infra.eu"
|
||||
key = "contabo.core.infra.tfstate"
|
||||
region = "eu-west-1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
resource "contabo_instance" "vps_1" {
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
output "instances" {
|
||||
value = [
|
||||
{
|
||||
cpu_cores = contabo_instance.vps_1.cpu_cores
|
||||
disk_mb = contabo_instance.vps_1.disk_mb
|
||||
id = contabo_instance.vps_1.id
|
||||
image_id = contabo_instance.vps_1.image_id
|
||||
ip_config = contabo_instance.vps_1.ip_config
|
||||
mac_address = contabo_instance.vps_1.mac_address
|
||||
name = contabo_instance.vps_1.name
|
||||
os_type = contabo_instance.vps_1.os_type
|
||||
ram_mb = contabo_instance.vps_1.ram_mb
|
||||
v_host_id = contabo_instance.vps_1.v_host_id
|
||||
},
|
||||
]
|
||||
description = "VPS instances details"
|
||||
sensitive = true
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
terraform {
|
||||
required_version = "~>1.8"
|
||||
required_providers {
|
||||
contabo = {
|
||||
source = "contabo/contabo"
|
||||
version = ">= 0.1.31"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "contabo" {
|
||||
oauth2_client_id = var.contabo_client_id
|
||||
oauth2_client_secret = var.contabo_client_secret
|
||||
oauth2_user = var.contabo_api_user
|
||||
oauth2_pass = var.contabo_api_password
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY
|
||||
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_KEY
|
||||
TF_VAR_contabo_client_id=$CONTABO_CLIENT_ID
|
||||
TF_VAR_contabo_client_secret=$CONTABO_CLIENT_SECRET
|
||||
TF_VAR_contabo_api_password=$CONTABO_API_PASSWORD
|
||||
TF_VAR_contabo_api_user=$CONTABO_USER_NAME
|
||||
@@ -0,0 +1,23 @@
|
||||
variable "contabo_client_id" {
|
||||
description = "Contabo Client ID"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "contabo_client_secret" {
|
||||
description = "Contabo Client Secret"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "contabo_api_password" {
|
||||
description = "Contabo API Password"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "contabo_api_user" {
|
||||
description = "Contabo API User"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
../../repository.vault
|
||||
@@ -1,150 +0,0 @@
|
||||
resource "cloudns_dns_record" "alexpires_me_microk8s" {
|
||||
name = local.contabo_instance.name
|
||||
zone = local.alexpires_me_zone
|
||||
type = "A"
|
||||
value = local.contabo_instance.ip
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_code" {
|
||||
name = "code"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "CNAME"
|
||||
value = "${cloudns_dns_record.alexpires_me_microk8s.name}.${local.alexpires_me_zone}"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_cloud" {
|
||||
name = "cloud"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "CNAME"
|
||||
value = "${cloudns_dns_record.alexpires_me_microk8s.name}.${local.alexpires_me_zone}"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_tv" {
|
||||
name = "tv"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "CNAME"
|
||||
value = "${cloudns_dns_record.alexpires_me_microk8s.name}.${local.alexpires_me_zone}"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_blog" {
|
||||
name = "blog"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "CNAME"
|
||||
value = "${cloudns_dns_record.alexpires_me_microk8s.name}.${local.alexpires_me_zone}"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_www" {
|
||||
name = "www"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "CNAME"
|
||||
value = "${cloudns_dns_record.alexpires_me_microk8s.name}.${local.alexpires_me_zone}"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_rustdesk" {
|
||||
name = "rustdesk"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "CNAME"
|
||||
value = "${cloudns_dns_record.alexpires_me_microk8s.name}.${local.alexpires_me_zone}"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_prod_01" {
|
||||
name = "prod-01"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "CNAME"
|
||||
value = "${cloudns_dns_record.alexpires_me_microk8s.name}.${local.alexpires_me_zone}"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_imaps" {
|
||||
name = "imap"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "CNAME"
|
||||
value = "${cloudns_dns_record.alexpires_me_microk8s.name}.${local.alexpires_me_zone}"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_smtps" {
|
||||
name = "smtp"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "CNAME"
|
||||
value = "${cloudns_dns_record.alexpires_me_microk8s.name}.${local.alexpires_me_zone}"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_root" {
|
||||
name = ""
|
||||
zone = local.alexpires_me_zone
|
||||
type = "A"
|
||||
value = local.contabo_instance.ip
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_spf" {
|
||||
name = ""
|
||||
zone = local.alexpires_me_zone
|
||||
type = "TXT"
|
||||
value = "v=spf1 include:_spf.tem.scaleway.com include:spf.webapps.net ~all"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_dkim" {
|
||||
name = "${var.scaleway_dkim_key}._domainkey"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "TXT"
|
||||
value = "v=DKIM1; h=sha256; k=rsa; p=${var.scaleway_dkim_value}"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_dmarc" {
|
||||
name = "_dmarc"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "TXT"
|
||||
value = "v=DMARC1; p=none; rua=mailto:admin@${local.alexpires_me_zone}"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_mx" {
|
||||
name = ""
|
||||
zone = local.alexpires_me_zone
|
||||
type = "MX"
|
||||
priority = "10"
|
||||
value = "mail-pt.securemail.pro"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_mail" {
|
||||
name = "mail"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "CNAME"
|
||||
value = "mail-pt.securemail.pro"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_mail_smtp_srv" {
|
||||
name = "_smtp._tcp"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "SRV"
|
||||
priority = 0
|
||||
weight = 1
|
||||
port = 465
|
||||
value = "smtp.${local.alexpires_me_zone}"
|
||||
ttl = "3600"
|
||||
}
|
||||
|
||||
resource "cloudns_dns_record" "alexpires_me_mail_imap_srv" {
|
||||
name = "_imap._tcp"
|
||||
zone = local.alexpires_me_zone
|
||||
type = "SRV"
|
||||
priority = 0
|
||||
weight = 1
|
||||
port = 993
|
||||
value = "imap.${local.alexpires_me_zone}"
|
||||
ttl = "3600"
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
terraform {
|
||||
backend "s3" {
|
||||
bucket = "a13labs.infra"
|
||||
key = "a13labs-iac.tfstate"
|
||||
region = "us-east-1"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
locals {
|
||||
instance_ips = [
|
||||
"${local.contabo_instance.ip}/32",
|
||||
]
|
||||
alexpires_me_zone = "alexpires.me"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
# Contabo is down for now, so we can't use it for now
|
||||
# data "contabo_instance" "microk8s" {
|
||||
# id = "201912751"
|
||||
# }
|
||||
|
||||
locals {
|
||||
contabo_instance = {
|
||||
id = "201912751"
|
||||
name = "vmi1912751" # data.contabo_instance.microk8s.name
|
||||
hostname = "microk8s"
|
||||
ip = "147.78.131.194" # data.contabo_instance.microk8s.ip_config[0].v4[0].ip
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
|
||||
terraform {
|
||||
required_version = "~>1.8"
|
||||
required_providers {
|
||||
scaleway = {
|
||||
source = "scaleway/scaleway"
|
||||
version = "~>2.13"
|
||||
}
|
||||
# Contabo provider is not working for now, so we can't use it
|
||||
# contabo = {
|
||||
# source = "contabo/contabo"
|
||||
# version = "0.1.26"
|
||||
# }
|
||||
cloudns = {
|
||||
source = "ClouDNS/cloudns"
|
||||
version = "~>1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "cloudns" {
|
||||
auth_id = var.cloudns_auth_id
|
||||
password = var.cloudns_password
|
||||
}
|
||||
|
||||
provider "scaleway" {
|
||||
zone = "fr-par-2"
|
||||
region = "fr-par"
|
||||
access_key = var.scaleway_access_key
|
||||
secret_key = var.scaleway_secret_key
|
||||
organization_id = var.scaleway_organization_id
|
||||
}
|
||||
|
||||
|
||||
# Configure your Contabo API credentials
|
||||
# provider "contabo" {
|
||||
# oauth2_client_id = var.contabo_client_id
|
||||
# oauth2_client_secret = var.contabo_client_secret
|
||||
# oauth2_user = var.contabo_api_user
|
||||
# oauth2_pass = var.contabo_api_password
|
||||
# }
|
||||
@@ -1,94 +0,0 @@
|
||||
variable "scaleway_access_key" {
|
||||
description = "Scaleway Access key"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "scaleway_secret_key" {
|
||||
description = "Scaleway Secret key"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "scaleway_project_id" {
|
||||
description = "Scaleway Project Id"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "scaleway_organization_id" {
|
||||
description = "Scaleway Organization Id"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "scaleway_user_id" {
|
||||
description = "Scaleway User Id"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
# variable "contabo_client_id" {
|
||||
# description = "Contabo Client ID"
|
||||
# type = string
|
||||
# sensitive = true
|
||||
# }
|
||||
|
||||
# variable "contabo_client_secret" {
|
||||
# description = "Contabo Client Secret"
|
||||
# type = string
|
||||
# sensitive = true
|
||||
# }
|
||||
|
||||
# variable "contabo_api_password" {
|
||||
# description = "Contabo API Password"
|
||||
# type = string
|
||||
# sensitive = true
|
||||
# }
|
||||
|
||||
# variable "contabo_api_user" {
|
||||
# description = "Contabo API User"
|
||||
# type = string
|
||||
# }
|
||||
|
||||
variable "encryption_key" {
|
||||
description = "Encryption key for sensitive data"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "bucket_suffix" {
|
||||
description = "Suffix for bucket names"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "system_id" {
|
||||
description = "System ID"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "cloudns_auth_id" {
|
||||
description = "Cloudns Auth ID"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "cloudns_password" {
|
||||
description = "Cloudns Password"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "scaleway_dkim_key" {
|
||||
description = "Scaleway DKIM key"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "scaleway_dkim_value" {
|
||||
description = "Scaleway DKIM value"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
module "websites" {
|
||||
source = "../modules/apps/nginx"
|
||||
persistent_folder = local.persistent_folder
|
||||
websites = local.websites
|
||||
}
|
||||
|
||||
module "rustdesk" {
|
||||
source = "../modules/apps/rustdesk"
|
||||
|
||||
persistent_folder = local.persistent_folder
|
||||
fqdn = local.rustdesk_fqdn
|
||||
public_key = var.rustdesk_public_key
|
||||
private_key = var.rustdesk_private_key
|
||||
}
|
||||
|
||||
module "m3uproxy" {
|
||||
source = "../modules/apps/m3uproxy"
|
||||
|
||||
persistent_folder = local.persistent_folder
|
||||
tag = local.m3uproxy_version
|
||||
fqdn = local.m3uproxy_fqdn
|
||||
|
||||
# Secret and password for M3UProxy
|
||||
secret = var.m3uproxy_secret
|
||||
admin_password = var.m3uproxy_admin_password
|
||||
|
||||
# GeoIP settings
|
||||
maxmind_account_id = var.maxmind_account_id
|
||||
maxmind_license_key = var.maxmind_license_key
|
||||
geoip_cron_schedule = local.geoip_cron_schedule
|
||||
geoip_editions = local.geoip_editions
|
||||
|
||||
# Wireguard settings (VPN)
|
||||
wireguard_private_key = var.wireguard_private_key
|
||||
wireguard_public_key = var.wireguard_public_key
|
||||
}
|
||||
|
||||
module "mail" {
|
||||
source = "../modules/apps/mail"
|
||||
|
||||
persistent_folder = local.persistent_folder
|
||||
|
||||
primary_domain = local.primary_domain
|
||||
email_accounts = local.email_accounts
|
||||
|
||||
relay_smtp_host = local.scaleway_smtp_host
|
||||
relay_smtp_port = 465
|
||||
relay_smtp_username = var.scaleway_project_id
|
||||
relay_smtp_password = scaleway_iam_api_key.mail_app_api.secret_key
|
||||
|
||||
fetch_emails_schedule = local.fetch_emails_schedule
|
||||
|
||||
mail_crypt_private_key = var.mail_crypt_private_key
|
||||
mail_crypt_public_key = var.mail_crypt_public_key
|
||||
|
||||
ca_pem = var.root_ca_pem
|
||||
}
|
||||
|
||||
module "gitea" {
|
||||
source = "../modules/apps/gitea"
|
||||
|
||||
persistent_folder = local.persistent_folder
|
||||
database_folder = local.database_folder
|
||||
|
||||
backup_folder = local.gitea_backup_path
|
||||
backup_retention_days = local.local_backup_retention_days
|
||||
backup_cron_schedule = local.gitea_sql_backup_cron_schedule
|
||||
|
||||
db_root_password = var.mysql_root_password
|
||||
|
||||
tag = local.gitea_version
|
||||
fqdn = local.gitea_fqdn
|
||||
|
||||
app_config = {
|
||||
app_name = "A13Labs git repository"
|
||||
domain = local.gitea_fqdn
|
||||
lfs_jwt_secret = var.gitea_lfs_jwt_secret
|
||||
db_passwd = var.gitea_mysql_password
|
||||
jwt_secret = var.gitea_jwt_secret
|
||||
mail_from = "gitea@${local.primary_domain}"
|
||||
no_reply_address = "no-reply@${local.primary_domain}"
|
||||
smtp_user = var.scaleway_project_id
|
||||
db_password = var.gitea_mysql_password
|
||||
smtp_host = local.scaleway_smtp_host
|
||||
smtp_port = local.scaleway_smtp_port
|
||||
smtp_user = var.scaleway_project_id
|
||||
smtp_passwd = scaleway_iam_api_key.mail_app_api.secret_key
|
||||
secret_key = var.gitea_secret_key
|
||||
internal_token = var.gitea_internal_token
|
||||
disable_ssh = false
|
||||
ssh_port = 22
|
||||
disable_registration = true
|
||||
}
|
||||
}
|
||||
|
||||
module "sftpgo" {
|
||||
source = "../modules/apps/sftpgo"
|
||||
|
||||
persistent_folder = local.persistent_folder
|
||||
backup_folder = local.sftpgo_backup_path
|
||||
|
||||
admin_username = "admin"
|
||||
admin_password = var.sftpgo_admin_password
|
||||
|
||||
tag = local.sftpgo_version
|
||||
fqdn = local.sftpgo_fqdn
|
||||
|
||||
smtp_host = local.scaleway_smtp_host
|
||||
smtp_port = local.scaleway_smtp_port
|
||||
smtp_username = var.scaleway_project_id
|
||||
smtp_password = scaleway_iam_api_key.mail_app_api.secret_key
|
||||
from_email = "sftpgo@${local.primary_domain}"
|
||||
|
||||
access_key = scaleway_iam_api_key.sftpgo_app_api.access_key
|
||||
secret_key = scaleway_iam_api_key.sftpgo_app_api.secret_key
|
||||
}
|
||||
|
||||
module "trivy" {
|
||||
source = "../modules/utils/trivy"
|
||||
|
||||
persistent_folder = local.persistent_folder
|
||||
cron_schedule = local.trivy_cronjob_schedule
|
||||
|
||||
smtp_host = local.scaleway_smtp_host
|
||||
smtp_port = local.scaleway_smtp_port
|
||||
smtp_username = var.scaleway_project_id
|
||||
smtp_password = scaleway_iam_api_key.mail_app_api.secret_key
|
||||
from_email = "trivy@${local.primary_domain}"
|
||||
to_email = "c.alexandre.pires@${local.primary_domain}"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
terraform {
|
||||
backend "s3" {
|
||||
bucket = "a13labs.infra"
|
||||
key = "alexpires.me-k8sapps.tfstate"
|
||||
region = "us-east-1"
|
||||
bucket = "a13labs.infra.eu"
|
||||
key = "k8sapps.core.infra.tfstate"
|
||||
region = "eu-west-1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
module "mail_backup" {
|
||||
|
||||
source = "../modules/utils/scw_rclone"
|
||||
|
||||
namespace = module.mail.namespace
|
||||
app_name = module.mail.app_name
|
||||
|
||||
scaleway_organization_id = var.scaleway_organization_id
|
||||
scaleway_project_id = var.scaleway_organization_id
|
||||
access_key = scaleway_iam_api_key.backup_app_api.access_key
|
||||
secret_key = scaleway_iam_api_key.backup_app_api.secret_key
|
||||
bucket_name = scaleway_object_bucket.backup.name
|
||||
|
||||
retention_days = local.local_backup_retention_days
|
||||
cron_schedule = local.mail_files_backup_cron_schedule
|
||||
|
||||
source_folder = module.mail.path
|
||||
target_folder = local.mail_backup_path
|
||||
}
|
||||
|
||||
module "gitea_backup" {
|
||||
source = "../modules/utils/scw_rclone"
|
||||
|
||||
namespace = module.gitea.namespace
|
||||
app_name = module.gitea.app_name
|
||||
|
||||
scaleway_organization_id = var.scaleway_organization_id
|
||||
scaleway_project_id = var.scaleway_organization_id
|
||||
access_key = scaleway_iam_api_key.backup_app_api.access_key
|
||||
secret_key = scaleway_iam_api_key.backup_app_api.secret_key
|
||||
bucket_name = scaleway_object_bucket.backup.name
|
||||
|
||||
retention_days = local.local_backup_retention_days
|
||||
cron_schedule = local.gitea_files_backup_cron_schedule
|
||||
|
||||
source_folder = module.gitea.path
|
||||
target_folder = local.gitea_backup_path
|
||||
}
|
||||
|
||||
module "sftpgo_backup" {
|
||||
|
||||
source = "../modules/utils/scw_rclone"
|
||||
|
||||
namespace = module.sftpgo.namespace
|
||||
app_name = module.sftpgo.app_name
|
||||
|
||||
scaleway_organization_id = var.scaleway_organization_id
|
||||
scaleway_project_id = var.scaleway_organization_id
|
||||
access_key = scaleway_iam_api_key.backup_app_api.access_key
|
||||
secret_key = scaleway_iam_api_key.backup_app_api.secret_key
|
||||
bucket_name = scaleway_object_bucket.backup.name
|
||||
|
||||
retention_days = local.local_backup_retention_days
|
||||
cron_schedule = local.sftpgo_files_backup_cron_schedule
|
||||
|
||||
source_folder = module.sftpgo.path
|
||||
target_folder = local.sftpgo_backup_path
|
||||
}
|
||||
@@ -30,16 +30,6 @@ resource "scaleway_object_bucket" "backup" {
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle_rule {
|
||||
id = "nextcloud-clean"
|
||||
prefix = "nextcloud-backup/"
|
||||
enabled = true
|
||||
|
||||
expiration {
|
||||
days = local.cloud_backup_retention_days
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle_rule {
|
||||
id = "mail-clean"
|
||||
prefix = "mail-backup/"
|
||||
@@ -81,20 +71,25 @@ resource "scaleway_object_bucket_policy" "backup" {
|
||||
Resource = [
|
||||
scaleway_object_bucket.backup.name,
|
||||
"${scaleway_object_bucket.backup.name}/*",
|
||||
]
|
||||
],
|
||||
Condition = {
|
||||
IpAddress = {
|
||||
"aws:SourceIp" = local.instance_ips
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
resource "scaleway_object_bucket" "nextcloud" {
|
||||
name = "a13labs-nextcloud-${random_string.bucket_suffix.result}"
|
||||
resource "scaleway_object_bucket" "sftpgo" {
|
||||
name = "a13labs-sftpgo-${random_string.bucket_suffix.result}"
|
||||
project_id = var.scaleway_project_id
|
||||
region = "fr-par"
|
||||
}
|
||||
|
||||
resource "scaleway_object_bucket_policy" "nextcloud" {
|
||||
bucket = scaleway_object_bucket.nextcloud.name
|
||||
resource "scaleway_object_bucket_policy" "sftpgo" {
|
||||
bucket = scaleway_object_bucket.sftpgo.name
|
||||
policy = jsonencode({
|
||||
Version = "2023-04-17",
|
||||
Id = "AllowAccess",
|
||||
@@ -108,8 +103,8 @@ resource "scaleway_object_bucket_policy" "nextcloud" {
|
||||
SCW = "user_id:${var.scaleway_user_id}"
|
||||
}
|
||||
Resource = [
|
||||
scaleway_object_bucket.nextcloud.name,
|
||||
"${scaleway_object_bucket.nextcloud.name}/*",
|
||||
scaleway_object_bucket.sftpgo.name,
|
||||
"${scaleway_object_bucket.sftpgo.name}/*",
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -118,54 +113,17 @@ resource "scaleway_object_bucket_policy" "nextcloud" {
|
||||
"s3:*",
|
||||
]
|
||||
Principal = {
|
||||
SCW = "application_id:${scaleway_iam_application.nextcloud_app.id}"
|
||||
SCW = "application_id:${scaleway_iam_application.sftpgo_app.id}"
|
||||
}
|
||||
Resource = [
|
||||
scaleway_object_bucket.nextcloud.name,
|
||||
"${scaleway_object_bucket.nextcloud.name}/*",
|
||||
]
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
resource "scaleway_object_bucket" "dovecot" {
|
||||
name = "a13labs-dovecot-${random_string.bucket_suffix.result}"
|
||||
project_id = var.scaleway_project_id
|
||||
region = "fr-par"
|
||||
}
|
||||
|
||||
resource "scaleway_object_bucket_policy" "dovecot" {
|
||||
bucket = scaleway_object_bucket.dovecot.name
|
||||
policy = jsonencode({
|
||||
Version = "2023-04-17",
|
||||
Id = "AllowAccess",
|
||||
Statement = [
|
||||
{
|
||||
Effect = "Allow"
|
||||
Action = [
|
||||
"s3:*",
|
||||
]
|
||||
Principal = {
|
||||
SCW = "user_id:${var.scaleway_user_id}"
|
||||
}
|
||||
Resource = [
|
||||
scaleway_object_bucket.dovecot.name,
|
||||
"${scaleway_object_bucket.dovecot.name}/*",
|
||||
]
|
||||
},
|
||||
{
|
||||
Effect = "Allow"
|
||||
Action = [
|
||||
"s3:*",
|
||||
]
|
||||
Principal = {
|
||||
SCW = "application_id:${scaleway_iam_application.dovecot_app.id}"
|
||||
}
|
||||
Resource = [
|
||||
scaleway_object_bucket.dovecot.name,
|
||||
"${scaleway_object_bucket.dovecot.name}/*",
|
||||
]
|
||||
scaleway_object_bucket.sftpgo.name,
|
||||
"${scaleway_object_bucket.sftpgo.name}/*",
|
||||
],
|
||||
Condition = {
|
||||
IpAddress = {
|
||||
"aws:SourceIp" = local.instance_ips
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
+79
-42
@@ -1,38 +1,35 @@
|
||||
locals {
|
||||
|
||||
domain_name = "alexpires.me"
|
||||
# general
|
||||
# storage
|
||||
persistent_folder = "/mnt/microk8s_persistent"
|
||||
database_folder = "/var/lib"
|
||||
|
||||
# apps
|
||||
wordpress_version = "6.7.2"
|
||||
wordpress_fqdns = ["blog.${local.domain_name}", "www.${local.domain_name}", "${local.domain_name}"]
|
||||
wordpress_sql_backup_cron_schedule = "0 2 * * *"
|
||||
wordpress_files_backup_cron_schedule = "10 2 * * *"
|
||||
# domains
|
||||
primary_domain = "alexpires.me"
|
||||
websites = {
|
||||
"alexpires.me" = {
|
||||
domain_name = "alexpires.me"
|
||||
fqdn = ["blog.alexpires.me", "www.alexpires.me", "alexpires.me"]
|
||||
tls = true
|
||||
issuer = "internal-ca"
|
||||
custom_snippet = file("${path.module}/resources/alexpires.me.conf")
|
||||
}
|
||||
}
|
||||
|
||||
gitea_version = "1.23.4"
|
||||
gitea_fqdn = "code.${local.domain_name}"
|
||||
gitea_sql_backup_cron_schedule = "20 2 * * *"
|
||||
gitea_files_backup_cron_schedule = "30 2 * * *"
|
||||
# gitea
|
||||
gitea_version = "1.23.7"
|
||||
gitea_fqdn = "code.${local.primary_domain}"
|
||||
|
||||
nextcloud_version = "30.0.0-apache"
|
||||
nextcloud_fqdn = "cloud.${local.domain_name}"
|
||||
nextcloud_sql_backup_cron_schedule = "40 2 * * *"
|
||||
nextcloud_files_backup_cron_schedule = "50 2 * * *"
|
||||
|
||||
# monitoring
|
||||
influxdb_version = "1.8-alpine"
|
||||
kapacitor_version = "1.6-alpine"
|
||||
fluent_bit_version = "3.1"
|
||||
telegraf_version = "1.32-alpine"
|
||||
chronograf_version = "1.9-alpine"
|
||||
# sftpgo
|
||||
sftpgo_version = "2.6.x"
|
||||
sftpgo_fqdn = "webdav.${local.primary_domain}"
|
||||
|
||||
# m3uproxy
|
||||
m3uproxy_version = "latest"
|
||||
wireguard_version = "1.0.20210914-r4-ls54"
|
||||
squid_version = "6.1-23.10_edge"
|
||||
m3uproxy_fqdn = "tv.${local.domain_name}"
|
||||
geoip_image = "maxmindinc/geoipupdate"
|
||||
geoip_version = "latest"
|
||||
m3uproxy_version = "latest"
|
||||
m3uproxy_fqdn = "tv.${local.primary_domain}"
|
||||
|
||||
# geoip
|
||||
geoip_cron_schedule = "0 0 * * *"
|
||||
geoip_editions = [
|
||||
"GeoLite2-Country",
|
||||
@@ -40,29 +37,69 @@ locals {
|
||||
"GeoLite2-ASN"
|
||||
]
|
||||
|
||||
# rustdesk
|
||||
rustdesk_version = "latest"
|
||||
rustdesk_fqdn = "rustdesk.${local.domain_name}"
|
||||
rustdesk_fqdn = "rustdesk.${local.primary_domain}"
|
||||
|
||||
# trivy
|
||||
trivy_cronjob_schedule = "0 1 1/15 * *"
|
||||
|
||||
# backup
|
||||
local_backup_retention_days = 2
|
||||
cloud_backup_retention_days = 3
|
||||
local_backup_retention_days = 2
|
||||
cloud_backup_retention_days = 3
|
||||
mail_backup_path = "${local.persistent_folder}/backup.mail"
|
||||
gitea_backup_path = "${local.persistent_folder}/backup.gitea"
|
||||
sftpgo_backup_path = "${local.persistent_folder}/backup.sftpgo"
|
||||
gitea_sql_backup_cron_schedule = "20 2 * * *"
|
||||
gitea_files_backup_cron_schedule = "30 2 * * *"
|
||||
sftpgo_files_backup_cron_schedule = "50 2 * * *"
|
||||
mail_files_backup_cron_schedule = "0 3 * * *"
|
||||
|
||||
# notification
|
||||
scaleway_smtp_host = "smtp.tem.scw.cloud"
|
||||
scaleway_smtp_port = 587
|
||||
|
||||
# mail settings
|
||||
getmail_version = "v0.0.1-6.19.07"
|
||||
fetch_emails_schedule = "*/2 * * * *"
|
||||
mail_files_backup_cron_schedule = "0 3 * * *"
|
||||
# email settings
|
||||
fetch_emails_schedule = "*/2 * * * *"
|
||||
scaleway_smtp_host = "smtp.tem.scw.cloud"
|
||||
scaleway_smtp_port = 587
|
||||
email_accounts = [
|
||||
{
|
||||
domain = "alexpires.me"
|
||||
recipient = "c.alexandre.pires"
|
||||
receive = {
|
||||
type = "imap"
|
||||
server = "mail-pt.securemail.pro"
|
||||
port = 993
|
||||
}
|
||||
send = {
|
||||
server = "smtp-pt.securemail.pro"
|
||||
port = 465
|
||||
}
|
||||
username = var.alexpires_me_email_username
|
||||
password = var.alexpires_me_email_password
|
||||
mailboxes = ["INBOX", "Sent", "Drafts", "Trash", "Spam"]
|
||||
}
|
||||
]
|
||||
|
||||
instance_ips = [
|
||||
"${local.vps_1.ip}/32",
|
||||
]
|
||||
|
||||
vps_1 = {
|
||||
id = data.terraform_remote_state.contabo.outputs.instances[0].id
|
||||
name = data.terraform_remote_state.contabo.outputs.instances[0].name
|
||||
ip = data.terraform_remote_state.contabo.outputs.instances[0].ip_config[0].v4[0].ip
|
||||
}
|
||||
|
||||
# storage
|
||||
persistent_folder = "/mnt/microk8s_persistent"
|
||||
database_folder = "/var/lib"
|
||||
}
|
||||
|
||||
data "scaleway_account_project" "default" {
|
||||
project_id = var.scaleway_project_id
|
||||
organization_id = var.scaleway_organization_id
|
||||
}
|
||||
|
||||
data "terraform_remote_state" "contabo" {
|
||||
backend = "s3"
|
||||
config = {
|
||||
bucket = "a13labs.infra.eu"
|
||||
key = "contabo.core.infra.tfstate"
|
||||
region = "eu-west-1"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ resource "kubernetes_config_map" "nextcloud_apache_config" {
|
||||
# Setup MariaDB database
|
||||
#
|
||||
module "nextcloud_database" {
|
||||
source = "./modules/k8s_mariadb"
|
||||
source = "../modules/db/mariadb"
|
||||
|
||||
namespace = kubernetes_namespace.nextcloud.metadata[0].name
|
||||
app_name = "nextcloud"
|
||||
@@ -169,29 +169,6 @@ module "nextcloud_database" {
|
||||
backup_folder = local.nextcloud_backup_path
|
||||
}
|
||||
|
||||
#
|
||||
# Setup rsync backup job to scaleway bucket
|
||||
#
|
||||
module "nextcloud_backup" {
|
||||
|
||||
source = "./modules/scw_backup_job"
|
||||
|
||||
namespace = kubernetes_namespace.nextcloud.metadata[0].name
|
||||
app_name = "nextcloud"
|
||||
|
||||
scaleway_organization_id = var.scaleway_organization_id
|
||||
scaleway_project_id = var.scaleway_organization_id
|
||||
access_key = scaleway_iam_api_key.backup_app_api.access_key
|
||||
secret_key = scaleway_iam_api_key.backup_app_api.secret_key
|
||||
bucket_name = scaleway_object_bucket.backup.name
|
||||
|
||||
retention_days = local.local_backup_retention_days
|
||||
cron_schedule = local.nextcloud_files_backup_cron_schedule
|
||||
|
||||
source_folder = local.nextcloud_path
|
||||
target_folder = local.nextcloud_backup_path
|
||||
}
|
||||
|
||||
#
|
||||
# Nextcloud service, ingress, deployment and file backup job
|
||||
#
|
||||
@@ -0,0 +1,46 @@
|
||||
server {
|
||||
listen 8080;
|
||||
server_name localhost;
|
||||
root /tmp/site;
|
||||
|
||||
resolver kube-dns.kube-system.svc.cluster.local valid=10s;
|
||||
|
||||
gzip on;
|
||||
gzip_comp_level 9;
|
||||
gzip_types
|
||||
text/html
|
||||
text/plain
|
||||
text/css
|
||||
text/js
|
||||
text/xml
|
||||
text/javascript
|
||||
application/javascript
|
||||
application/json
|
||||
application/xml
|
||||
application/rss+xml
|
||||
image/svg+xml;
|
||||
|
||||
location ^~ /storage {
|
||||
proxy_pass http://http.sftpgo.svc.cluster.local:8080/storage;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
}
|
||||
|
||||
location / {
|
||||
index index.html index.htm;
|
||||
}
|
||||
|
||||
location ~* ^/([^/]+) {
|
||||
index index.html index.htm;
|
||||
error_page 404 = @error;
|
||||
}
|
||||
|
||||
error_page 404 /404.html;
|
||||
location @error {
|
||||
try_files /$1/404.html /404.html =404;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user