Compare commits
14 Commits
17cddb7532
...
aef54ab6fe
Author | SHA1 | Date | |
---|---|---|---|
aef54ab6fe | |||
9c03773378 | |||
ce9b851217 | |||
7a8ff6341a | |||
19c2032afa | |||
331752707d | |||
4d9f46876e | |||
bbfa3b4592 | |||
f5c4d15272 | |||
99d716c62b | |||
d31e79430b | |||
8611f1d266 | |||
74a01b5b05 | |||
78ca31f154 |
6
.cz.toml
Normal file
6
.cz.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[tool.commitizen]
|
||||
name = "cz_conventional_commits"
|
||||
version_provider = "scm"
|
||||
update_changelog_on_bump = true
|
||||
major_version_zero = true
|
||||
tag_format = "v$version"
|
26
.gitea/workflows/development.yml
Normal file
26
.gitea/workflows/development.yml
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
name: development
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
commit-check:
|
||||
name: Check commit compliance
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install commitizen
|
||||
run: pip3 install commitizen
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
- name: Verify commit message compliance
|
||||
run: |
|
||||
echo "cz check --message '${{ github.event.head_commit.message }}'"
|
||||
cz check --message "${{ github.event.head_commit.message }}"
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
128
.gitea/workflows/pull-request-open.yml
Normal file
128
.gitea/workflows/pull-request-open.yml
Normal file
@ -0,0 +1,128 @@
|
||||
---
|
||||
name: pull-requests-open
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
commit-history-check:
|
||||
name: Check commit compliance
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install commitizen
|
||||
run: pip3 install commitizen
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
- run: git log origin/${{ github.event.pull_request.base.ref }}..
|
||||
|
||||
- name: Verify commit message compliance
|
||||
run: |
|
||||
echo "cz check --rev-range origin/${{ gitea.event.pull_request.base.ref }}.."
|
||||
cz check --rev-range origin/${{ gitea.event.pull_request.base.ref }}..
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
pre-commit-check:
|
||||
name: Check pre-commit status
|
||||
runs-on: ubuntu-latest
|
||||
needs: commit-history-check
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install pre-commit
|
||||
run: pip3 install pre-commit
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
- name: Install pre-commit dependencies
|
||||
run: |
|
||||
# terraform-docs
|
||||
curl -sSLo /tmp/terraform-docs.tar.gz \
|
||||
https://terraform-docs.io/dl/${TERRAFORM_DOCS_VERSION}/terraform-docs-${TERRAFORM_DOCS_VERSION}-$(uname)-amd64.tar.gz
|
||||
tar -xzf /tmp/terraform-docs.tar.gz -C /tmp
|
||||
chmod +x /tmp/terraform-docs
|
||||
mv /tmp/terraform-docs /usr/local/bin/terraform-docs
|
||||
rm -rf /tmp/*
|
||||
|
||||
# opentofu
|
||||
curl --proto '=https' --tlsv1.2 -fsSL https://get.opentofu.org/install-opentofu.sh \
|
||||
-o install-opentofu.sh
|
||||
chmod +x install-opentofu.sh
|
||||
./install-opentofu.sh --install-method standalone --opentofu-version $OPENTOFU_VERSION
|
||||
rm -f install-opentofu.sh
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
env:
|
||||
OPENTOFU_VERSION: 1.8.0
|
||||
TERRAFORM_DOCS_VERSION: v0.18.0
|
||||
|
||||
- name: Verify pre-commit status
|
||||
run: pre-commit run --all
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
end-to-end-tests:
|
||||
name: Run E2E tofu tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: pre-commit-check
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install required packages
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
sudo apt update
|
||||
sudo apt install -y curl jq
|
||||
|
||||
curl https://vault.ednz.fr/v1/ednz-root-ca/ca -o /tmp/ednz_ca
|
||||
openssl x509 -inform DER -in /tmp/ednz_ca -out /usr/local/share/ca-certificates/ednz_ca.crt -outform pem
|
||||
update-ca-certificates
|
||||
|
||||
- name: Install OpenTofu
|
||||
uses: opentofu/setup-opentofu@v1
|
||||
with:
|
||||
tofu_version: 1.8.2
|
||||
|
||||
- name: Get secrets from vault
|
||||
id: import-secrets
|
||||
uses: hashicorp/vault-action@v3
|
||||
with:
|
||||
url: "https://vault.ednz.fr"
|
||||
method: approle
|
||||
roleId: ${{ secrets.VAULT_APPROLE_ID }}
|
||||
secretId: ${{ secrets.VAULT_APPROLE_SECRET_ID }}
|
||||
secrets: |
|
||||
kv/data/cicd/vault/infrabuilder approle_id | VAULT_INFRABUILDER_APPROLE_ID ;
|
||||
kv/data/cicd/vault/infrabuilder approle_secret_id | VAULT_INFRABUILDER_APPROLE_SECRET_ID ;
|
||||
|
||||
- name: Get required credentials
|
||||
id: tofu-auth
|
||||
run: |
|
||||
VAULT_TOKEN=$(curl --silent --request POST --data '{"role_id": "${{ steps.import-secrets.outputs.VAULT_INFRABUILDER_APPROLE_ID }}","secret_id": "${{ steps.import-secrets.outputs.VAULT_INFRABUILDER_APPROLE_SECRET_ID }}"}' https://vault.ednz.fr/v1/auth/approle/login | jq -r .auth.client_token)
|
||||
echo "vault_token=$VAULT_TOKEN" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Tofu init
|
||||
run: tofu init
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
- name: Tofu test
|
||||
run: tofu test
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
env:
|
||||
VAULT_TOKEN: ${{ steps.tofu-auth.outputs.vault_token }}
|
54
.gitea/workflows/release.yml
Normal file
54
.gitea/workflows/release.yml
Normal file
@ -0,0 +1,54 @@
|
||||
---
|
||||
name: build-deploy
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
do-release:
|
||||
if: "!startsWith(github.event.head_commit.message, 'bump:')"
|
||||
runs-on: ubuntu-latest
|
||||
name: Bump version and create changelog with commitizen
|
||||
steps:
|
||||
- name: Get secrets from vault
|
||||
id: import-secrets
|
||||
uses: hashicorp/vault-action@v3
|
||||
with:
|
||||
url: "https://vault.ednz.fr"
|
||||
method: approle
|
||||
roleId: ${{ secrets.VAULT_APPROLE_ID }}
|
||||
secretId: ${{ secrets.VAULT_APPROLE_SECRET_ID }}
|
||||
secrets: |
|
||||
kv/data/applications/gitea/users/actions username | GITEA_ACTIONS_USERNAME ;
|
||||
kv/data/applications/gitea/users/actions token_write | GITEA_ACTIONS_TOKEN ;
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ steps.import-secrets.outputs.GITEA_ACTIONS_TOKEN }}
|
||||
|
||||
- name: Install commitizen
|
||||
run: pip3 install commitizen
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
- name: Configure git credentials
|
||||
uses: oleksiyrudenko/gha-git-credentials@v2
|
||||
with:
|
||||
global: true
|
||||
name: "Gitea-Actions Bot"
|
||||
email: "gitea-actions@ednz.fr"
|
||||
actor: ${{ steps.import-secrets.outputs.GITEA_ACTIONS_USERNAME }}
|
||||
token: ${{ steps.import-secrets.outputs.GITEA_ACTIONS_TOKEN }}
|
||||
|
||||
- name: Do release
|
||||
run: cz -nr 21 bump --yes
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
- name: Push release
|
||||
run: git push && git push --tags
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
# Local .terraform directories
|
||||
**/.terraform/*
|
||||
|
||||
# .tfstate files
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
|
||||
# Crash log files
|
||||
crash.log
|
||||
|
||||
# Exclude all .tfvars files, which are likely to contain sentitive data, such as
|
||||
# password, private keys, and other secrets. These should not be part of version
|
||||
# control as they are data points which are potentially sensitive and subject
|
||||
# to change depending on the environment.
|
||||
#
|
||||
#*.tfvars
|
||||
|
||||
# Ignore override files as they are usually used to override resources locally and so
|
||||
# are not checked in
|
||||
override.tf
|
||||
override.tf.json
|
||||
*_override.tf
|
||||
*_override.tf.json
|
||||
|
||||
# Include override files you do wish to add to version control using negated pattern
|
||||
#
|
||||
# !example_override.tf
|
||||
|
||||
# Ignore CLI configuration files
|
||||
.terraformrc
|
||||
terraform.rc
|
||||
|
||||
# Credentials files
|
||||
credentials.auto.tfvars
|
||||
|
||||
# Local plan files
|
||||
plan.out
|
||||
**temp.txt
|
@ -1,19 +1,28 @@
|
||||
repos:
|
||||
- repo: https://github.com/antonbabenko/pre-commit-terraform
|
||||
rev: v1.86.0
|
||||
- repo: https://github.com/tofuutils/pre-commit-opentofu
|
||||
rev: v1.0.2
|
||||
hooks:
|
||||
- id: terraform_fmt
|
||||
- id: terraform_docs
|
||||
- id: tofu_fmt
|
||||
- id: tofu_docs
|
||||
args:
|
||||
- "--hook-config=--path-to-file=README.md"
|
||||
- "--hook-config=--add-to-existing-file=true"
|
||||
- "--hook-config=--create-file-if-not-exist=true"
|
||||
- "--hook-config=--use-standard-markers=true"
|
||||
- "--args=--escape=false"
|
||||
- "--args=--lockfile=false"
|
||||
- "--args=--indent 3"
|
||||
- "--args=--show all"
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.5.0
|
||||
rev: v4.6.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- repo: https://github.com/commitizen-tools/commitizen
|
||||
rev: v3.29.0
|
||||
hooks:
|
||||
- id: commitizen
|
||||
- id: commitizen-branch
|
||||
stages:
|
||||
- post-commit
|
||||
- push
|
||||
|
41
.terraform.lock.hcl
Normal file
41
.terraform.lock.hcl
Normal file
@ -0,0 +1,41 @@
|
||||
# This file is maintained automatically by "tofu init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.opentofu.org/hashicorp/vault" {
|
||||
version = "4.4.0"
|
||||
hashes = [
|
||||
"h1:s0t6P9ZfUQnHLxtUcnpPWpME68KwO/OxZqHAKSIvOoo=",
|
||||
"zh:0309ea8f81386e17ab13c06c5991ca959708c55c815b0cfba2bbcd865e0d606e",
|
||||
"zh:40e56199ccd266bffa216e8ebbcdc2e29b6ef5145b39377be766e763cac759c8",
|
||||
"zh:6fad1f073bd2e53e34736e000f98db581137e153ac80bbb5c4f1a1e38b46a1d2",
|
||||
"zh:74564fd4759decccf7f3c952aa2feba1012f103a66ec354aa3b3292a2f1b2412",
|
||||
"zh:7aae012c1a43e6e5dae6f608ec0f08cdb3f95fa121a32e413fe7ee37cb99947f",
|
||||
"zh:7c83f508e164844b1dd9bafe9de0fe60c7be7b55a02e704a6e2f50cff38b7d96",
|
||||
"zh:873a42322b68d9fba4a38217b97ee04a1eb617e811d7f9954016f5c3eb6cb0bc",
|
||||
"zh:9db2b13472cf91a5f18f0a7c6ae532277c05b0980d87f492341426b981679f7b",
|
||||
"zh:ac1cbd2926265db80efe3f1814bed82901f7d8a7d4e5b1e22592e1eef234b1c7",
|
||||
"zh:f465a955cc96f640e7426a648ba672c169a4a2959bad6146fe61583d67642561",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.opentofu.org/terraform-provider-openstack/openstack" {
|
||||
version = "2.1.0"
|
||||
constraints = ">= 1.54.0, ~> 2.1.0"
|
||||
hashes = [
|
||||
"h1:2TcmfEzBOGQPALErrXTaL6v+k/WAL40adao4izRYmdw=",
|
||||
"zh:113661750398bf21c8fe36aade9fb6f5eb82b5bcd3bcd30bd37ac805d83398f4",
|
||||
"zh:1b3c26347b9cd61e413ee93c2f422cc3278a77f55fd3516eaabb3e2a85f65281",
|
||||
"zh:1b751bbf1e4152829a643b532fd3f5967a2e89a41fac381257e0b41665be3306",
|
||||
"zh:1b967bbfd9b344419c0e0df0c3a15fcbd731e91f19a18955a55aace8d9ec039a",
|
||||
"zh:1bc0fc7c0a21e568db043b654501ce668ba19bf7628d37a7d2aaa512fd6e5aeb",
|
||||
"zh:425cbf61757d4b503e7bf0f409ea59835ca3afbd2432d56ad552c2e5d234a572",
|
||||
"zh:67d4f059cb4d73bf6c060313ec32962c4e5bd8dc7be2542a6f2098ab32575cd9",
|
||||
"zh:7fe841ac5b68a4f52fb3cf45070828f3845de44746679d434e4349f3c23e3ef2",
|
||||
"zh:ac1ed4c6ef0b6a3410568a05d3f9933d184497f065988503c43da0b2f0786ab2",
|
||||
"zh:c5c0d14c86fabd9ab6a5d555e6a8d511942665fb5fa948dd452b0d1934068344",
|
||||
"zh:c9ae5c210192275185d6823566a9421983e8e64c2665a4cae00b92dd0706bd19",
|
||||
"zh:ee9865ccc053e7f345e532654fb628d1cf1e81cd2e929643c1691bebffcf7b98",
|
||||
"zh:f3416d2f666095e740522c4964e436470bb9ec17bd53aaae8169ad93297d07bd",
|
||||
"zh:fbca85457dd49e17168989d64f7cfc4a519d55ef4e00e89cea2859e87ad87f83",
|
||||
]
|
||||
}
|
20
LICENSE
Normal file
20
LICENSE
Normal file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bertrand Lanson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
29
README.md
29
README.md
@ -1,8 +1,13 @@
|
||||
# terraform-openstack-lz
|
||||
# terraform-openstack-landing-zone
|
||||
|
||||
Terraform module to deploy a completely customizable OpenStack
|
||||
Terraform/OpenTofu module to deploy a completely customizable OpenStack network architecture.
|
||||
|
||||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
![Terraform Badge](https://img.shields.io/badge/Terraform-844FBA?logo=terraform&logoColor=fff&style=for-the-badge)
|
||||
![OpenTofu Badge](https://img.shields.io/badge/OpenTofu-FFDA18?logo=opentofu&logoColor=000&style=for-the-badge)
|
||||
![OpenStack Badge](https://img.shields.io/badge/OpenStack-ED1944?logo=openstack&logoColor=fff&style=for-the-badge)
|
||||
|
||||
|
||||
<!-- BEGIN_TF_DOCS -->
|
||||
### Requirements
|
||||
|
||||
| Name | Version |
|
||||
@ -43,20 +48,25 @@ No modules.
|
||||
| [openstack_networking_subnet_v2.backend](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_subnet_v2) | resource |
|
||||
| [openstack_networking_subnet_v2.database](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_subnet_v2) | resource |
|
||||
| [openstack_networking_subnet_v2.frontend](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_subnet_v2) | resource |
|
||||
| [openstack_networking_subnetpool_v2.this](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_subnetpool_v2) | resource |
|
||||
| [openstack_networking_subnetpool_v2.apps](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_subnetpool_v2) | resource |
|
||||
| [openstack_networking_subnetpool_v2.database](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_subnetpool_v2) | resource |
|
||||
| [openstack_identity_project_v3.this](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/data-sources/identity_project_v3) | data source |
|
||||
|
||||
### Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| <a name="input_application_subnetpool_cidr_blocks"></a> [application_subnetpool_cidr_blocks](#input_application_subnetpool_cidr_blocks) | The CIDR blocks for the application subnet pool | `list(string)` | <pre>[<br> "192.168.0.0/21"<br>]</pre> | no |
|
||||
| <a name="input_application_subnetpool_id"></a> [application_subnetpool_id](#input_application_subnetpool_id) | The id of the subnetpool to create the public (first 2 tier) networks from.<br>Since this module can route private subnets to the backbone, it needs to make sure it's not creating overlapping subnets. | `string` | `null` | no |
|
||||
| <a name="input_architecture_tiers"></a> [architecture_tiers](#input_architecture_tiers) | The type of architecture.<br>Can be either 0, 1, 2 or 3.<br>Tier 0 will not create any subnets or networks.<br>Tier 1 will only create a single frontend subnet.<br>Tier 2 will create a frontend and backend subnet.<br>Tier 3 will create a frontend, backend and database subnet. | `number` | `1` | no |
|
||||
| <a name="input_attach_to_external"></a> [attach_to_external](#input_attach_to_external) | Whether the frontend subnet should be routed or not to the external LAN.<br>This options implies that you have sufficient permissions to configure static route on the backbone infrastructure.<br>This will create an static route entry in the route table of the backbone router, in order to make your project available from the outside. | `bool` | `false` | no |
|
||||
| <a name="input_attach_to_external"></a> [attach_to_external](#input_attach_to_external) | Whether to attach the router to an external network.<br>This will add a gateway interface to the router, and possibly consume a public IP address which might be billed by your cloud provider. | `bool` | `false` | no |
|
||||
| <a name="input_backend_subnet_prefix_len"></a> [backend_subnet_prefix_len](#input_backend_subnet_prefix_len) | The prefix length of the backend subnet. Must be between 20 and 32. | `number` | `24` | no |
|
||||
| <a name="input_create_application_subnetpool"></a> [create_application_subnetpool](#input_create_application_subnetpool) | Whether the module should create an application subnet pool for this project, or use an existing one. | `bool` | `true` | no |
|
||||
| <a name="input_create_database_subnetpool"></a> [create_database_subnetpool](#input_create_database_subnetpool) | Whether the module should create a database subnet pool for this project, or use an existing one. | `bool` | `true` | no |
|
||||
| <a name="input_create_default_secgroups"></a> [create_default_secgroups](#input_create_default_secgroups) | Whether to create default security groups or not.<br>Depending on your choice of architecture tiering, will create security groups so that each tier can connect to the one below.<br>Security groups for the database tier will be created for mariadb, postgresql and redis.<br>A default security group allowing ssh connection will also be created. | `bool` | `false` | no |
|
||||
| <a name="input_create_subnetpool"></a> [create_subnetpool](#input_create_subnetpool) | Whether the module should create a subnet pool for this project, or use an existing one. | `bool` | `true` | no |
|
||||
| <a name="input_database_secgroup_strict"></a> [database_secgroup_strict](#input_database_secgroup_strict) | Defines whether the security groups for the database network should be strict.<br>In strict mode, egress is only allowed to the backend network. | `bool` | `false` | no |
|
||||
| <a name="input_database_subnet_prefix_len"></a> [database_subnet_prefix_len](#input_database_subnet_prefix_len) | The prefix length of the database subnet. Must be between 24 and 32. | `number` | `24` | no |
|
||||
| <a name="input_database_subnetpool_cidr_blocks"></a> [database_subnetpool_cidr_blocks](#input_database_subnetpool_cidr_blocks) | The CIDR blocks for the database subnet pool | `list(string)` | <pre>[<br> "192.168.8.0/23"<br>]</pre> | no |
|
||||
| <a name="input_database_subnetpool_id"></a> [database_subnetpool_id](#input_database_subnetpool_id) | The id of the subnetpool to create the databse network from.<br>Since this module can route private subnets to the backbone, it needs to make sure it's not creating overlapping subnets. | `string` | `null` | no |
|
||||
| <a name="input_external_network_id"></a> [external_network_id](#input_external_network_id) | The id of the external network to connect the frontend router to. | `string` | `null` | no |
|
||||
| <a name="input_frontend_subnet_prefix_len"></a> [frontend_subnet_prefix_len](#input_frontend_subnet_prefix_len) | The prefix length of the frontend subnet. Must be between 20 and 32. | `number` | `24` | no |
|
||||
@ -64,22 +74,21 @@ No modules.
|
||||
| <a name="input_project_name"></a> [project_name](#input_project_name) | The name of the project | `string` | n/a | yes |
|
||||
| <a name="input_project_tags"></a> [project_tags](#input_project_tags) | The tags to append to this project | `list(string)` | `[]` | no |
|
||||
| <a name="input_public_nameservers"></a> [public_nameservers](#input_public_nameservers) | A list of public DNS servers to upstreams requests to in your subnets.<br>This is not necessary if your openstack deployment already has configured default upstreams for neutron. | `list(string)` | `[]` | no |
|
||||
| <a name="input_public_subnetpool_id"></a> [public_subnetpool_id](#input_public_subnetpool_id) | The id of the subnetpool to create the public (first 2 tier) networks from.<br>Since this module can route private subnets to the backbone, it needs to make sure it's not creating overlapping subnets. | `string` | `null` | no |
|
||||
| <a name="input_subnetpool_cidr_blocks"></a> [subnetpool_cidr_blocks](#input_subnetpool_cidr_blocks) | The CIDR block for the subnet pool | `list(string)` | <pre>[<br> "192.168.0.0/21"<br>]</pre> | no |
|
||||
|
||||
### Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| <a name="output_apps_subnetpool"></a> [apps_subnetpool](#output_apps_subnetpool) | The application subnetpool object (as a list), if created |
|
||||
| <a name="output_backend_network"></a> [backend_network](#output_backend_network) | The backend network object (as a list), if created |
|
||||
| <a name="output_backend_secgroups"></a> [backend_secgroups](#output_backend_secgroups) | The backend security group objects (as a list), if created |
|
||||
| <a name="output_backend_subnet"></a> [backend_subnet](#output_backend_subnet) | The backend subnet object (as a list), if created |
|
||||
| <a name="output_database_network"></a> [database_network](#output_database_network) | The database network object (as a list), if created |
|
||||
| <a name="output_database_secgroups"></a> [database_secgroups](#output_database_secgroups) | The database security group objects (as a list), if created |
|
||||
| <a name="output_database_subnet"></a> [database_subnet](#output_database_subnet) | The database subnet object (as a list), if created |
|
||||
| <a name="output_database_subnetpool"></a> [database_subnetpool](#output_database_subnetpool) | The database subnetpool object (as a list), if created |
|
||||
| <a name="output_frontend_network"></a> [frontend_network](#output_frontend_network) | The frontend network object (as a list), if created |
|
||||
| <a name="output_frontend_secgroups"></a> [frontend_secgroups](#output_frontend_secgroups) | The frontend security group objects (as a list), if created |
|
||||
| <a name="output_frontend_subnet"></a> [frontend_subnet](#output_frontend_subnet) | The frontend subnet object (as a list), if created |
|
||||
| <a name="output_router"></a> [router](#output_router) | The entire router object (as a list), if created |
|
||||
| <a name="output_subnetpool"></a> [subnetpool](#output_subnetpool) | The subnetpool object (as a list), if created |
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
<!-- END_TF_DOCS -->
|
||||
|
46
main.tf
46
main.tf
@ -11,6 +11,10 @@ terraform {
|
||||
}
|
||||
}
|
||||
|
||||
locals {
|
||||
resource_prefix = lower(var.project_name)
|
||||
}
|
||||
|
||||
#! data sources
|
||||
data "openstack_identity_project_v3" "this" {
|
||||
name = var.project_name
|
||||
@ -18,18 +22,26 @@ data "openstack_identity_project_v3" "this" {
|
||||
}
|
||||
|
||||
#! subnetpools
|
||||
resource "openstack_networking_subnetpool_v2" "this" {
|
||||
count = var.create_subnetpool ? 1 : 0
|
||||
name = "${var.project_name}-subnetpool"
|
||||
resource "openstack_networking_subnetpool_v2" "apps" {
|
||||
count = var.create_application_subnetpool ? 1 : 0
|
||||
name = "${local.resource_prefix}-application-subnetpool"
|
||||
is_default = false
|
||||
ip_version = 4
|
||||
prefixes = var.subnetpool_cidr_blocks
|
||||
prefixes = var.application_subnetpool_cidr_blocks
|
||||
}
|
||||
|
||||
resource "openstack_networking_subnetpool_v2" "database" {
|
||||
count = var.create_database_subnetpool ? 1 : 0
|
||||
name = "${local.resource_prefix}-database-subnetpool"
|
||||
is_default = false
|
||||
ip_version = 4
|
||||
prefixes = var.database_subnetpool_cidr_blocks
|
||||
}
|
||||
|
||||
#! networks & subnets
|
||||
resource "openstack_networking_network_v2" "frontend" {
|
||||
count = var.architecture_tiers > 0 ? 1 : 0
|
||||
name = "${var.project_name}-frontend-network"
|
||||
name = "${local.resource_prefix}-frontend-network"
|
||||
description = "Terraform managed."
|
||||
tenant_id = data.openstack_identity_project_v3.this.id
|
||||
shared = false
|
||||
@ -39,7 +51,7 @@ resource "openstack_networking_network_v2" "frontend" {
|
||||
|
||||
resource "openstack_networking_network_v2" "backend" {
|
||||
count = var.architecture_tiers > 1 ? 1 : 0
|
||||
name = "${var.project_name}-backend-network"
|
||||
name = "${local.resource_prefix}-backend-network"
|
||||
description = "Terraform managed."
|
||||
tenant_id = data.openstack_identity_project_v3.this.id
|
||||
shared = false
|
||||
@ -49,7 +61,7 @@ resource "openstack_networking_network_v2" "backend" {
|
||||
|
||||
resource "openstack_networking_network_v2" "database" {
|
||||
count = var.architecture_tiers == 3 ? 1 : 0
|
||||
name = "${var.project_name}-database-network"
|
||||
name = "${local.resource_prefix}-database-network"
|
||||
description = "Terraform managed."
|
||||
tenant_id = data.openstack_identity_project_v3.this.id
|
||||
shared = false
|
||||
@ -59,44 +71,44 @@ resource "openstack_networking_network_v2" "database" {
|
||||
|
||||
resource "openstack_networking_subnet_v2" "frontend" {
|
||||
count = var.architecture_tiers > 0 ? 1 : 0
|
||||
name = "${var.project_name}-frontend-subnet-${count.index + 1}"
|
||||
name = "${local.resource_prefix}-frontend-subnet-${count.index + 1}"
|
||||
description = "Terraform managed."
|
||||
tenant_id = data.openstack_identity_project_v3.this.id
|
||||
network_id = openstack_networking_network_v2.frontend[0].id
|
||||
prefix_length = var.frontend_subnet_prefix_len
|
||||
ip_version = 4
|
||||
subnetpool_id = var.create_subnetpool ? openstack_networking_subnetpool_v2.this[0].id : var.public_subnetpool_id
|
||||
subnetpool_id = var.create_application_subnetpool ? openstack_networking_subnetpool_v2.apps[0].id : var.application_subnetpool_id
|
||||
dns_nameservers = var.public_nameservers
|
||||
}
|
||||
|
||||
resource "openstack_networking_subnet_v2" "backend" {
|
||||
count = var.architecture_tiers > 1 ? 1 : 0
|
||||
name = "${var.project_name}-backend-subnet-${count.index + 1}"
|
||||
name = "${local.resource_prefix}-backend-subnet-${count.index + 1}"
|
||||
description = "Terraform managed."
|
||||
tenant_id = data.openstack_identity_project_v3.this.id
|
||||
network_id = openstack_networking_network_v2.backend[0].id
|
||||
prefix_length = var.backend_subnet_prefix_len
|
||||
ip_version = 4
|
||||
subnetpool_id = var.create_subnetpool ? openstack_networking_subnetpool_v2.this[0].id : var.public_subnetpool_id
|
||||
subnetpool_id = var.create_application_subnetpool ? openstack_networking_subnetpool_v2.apps[0].id : var.application_subnetpool_id
|
||||
dns_nameservers = var.public_nameservers
|
||||
}
|
||||
|
||||
resource "openstack_networking_subnet_v2" "database" {
|
||||
count = var.architecture_tiers == 3 ? 1 : 0
|
||||
name = "${var.project_name}-database-subnet-${count.index + 1}"
|
||||
name = "${local.resource_prefix}-database-subnet-${count.index + 1}"
|
||||
description = "Terraform managed."
|
||||
tenant_id = data.openstack_identity_project_v3.this.id
|
||||
network_id = openstack_networking_network_v2.database[0].id
|
||||
prefix_length = var.database_subnet_prefix_len
|
||||
ip_version = 4
|
||||
subnetpool_id = var.create_subnetpool ? openstack_networking_subnetpool_v2.this[0].id : var.database_subnetpool_id
|
||||
subnetpool_id = var.create_application_subnetpool ? openstack_networking_subnetpool_v2.database[0].id : var.database_subnetpool_id
|
||||
dns_nameservers = var.public_nameservers
|
||||
}
|
||||
|
||||
#! router
|
||||
resource "openstack_networking_router_v2" "this" {
|
||||
count = var.architecture_tiers > 0 ? 1 : 0
|
||||
name = "${var.project_name}-main-${count.index + 1}"
|
||||
name = "${local.resource_prefix}-main-${count.index + 1}"
|
||||
description = "Terraform managed."
|
||||
tenant_id = data.openstack_identity_project_v3.this.id
|
||||
external_network_id = var.attach_to_external ? var.external_network_id : null
|
||||
@ -128,7 +140,7 @@ resource "openstack_networking_secgroup_v2" "frontend" {
|
||||
var.create_default_secgroups
|
||||
) ? 1 : 0
|
||||
|
||||
name = "${var.project_name}-frontend-secgroup"
|
||||
name = "${local.resource_prefix}-frontend-secgroup"
|
||||
description = "Terraform managed."
|
||||
tenant_id = data.openstack_identity_project_v3.this.id
|
||||
delete_default_rules = true
|
||||
@ -163,7 +175,7 @@ resource "openstack_networking_secgroup_v2" "backend" {
|
||||
var.architecture_tiers > 1 &&
|
||||
var.create_default_secgroups
|
||||
) ? 1 : 0
|
||||
name = "${var.project_name}-backend-secgroup"
|
||||
name = "${local.resource_prefix}-backend-secgroup"
|
||||
description = "Terraform managed."
|
||||
tenant_id = data.openstack_identity_project_v3.this.id
|
||||
delete_default_rules = true
|
||||
@ -198,7 +210,7 @@ resource "openstack_networking_secgroup_v2" "database" {
|
||||
var.architecture_tiers == 3 &&
|
||||
var.create_default_secgroups
|
||||
) ? length(local.db_secgroups) : 0
|
||||
name = "${var.project_name}-database-${local.db_secgroups[count.index].type}-secgroup"
|
||||
name = "${local.resource_prefix}-database-${local.db_secgroups[count.index].type}-secgroup"
|
||||
description = "Terraform managed."
|
||||
tenant_id = data.openstack_identity_project_v3.this.id
|
||||
delete_default_rules = true
|
||||
|
13
outputs.tf
13
outputs.tf
@ -1,7 +1,14 @@
|
||||
output "subnetpool" {
|
||||
value = length(openstack_networking_subnetpool_v2.this) > 0 ? openstack_networking_subnetpool_v2.this.* : null
|
||||
output "apps_subnetpool" {
|
||||
value = length(openstack_networking_subnetpool_v2.apps) > 0 ? openstack_networking_subnetpool_v2.apps.* : null
|
||||
sensitive = false
|
||||
description = "The subnetpool object (as a list), if created"
|
||||
description = "The application subnetpool object (as a list), if created"
|
||||
depends_on = []
|
||||
}
|
||||
|
||||
output "database_subnetpool" {
|
||||
value = length(openstack_networking_subnetpool_v2.database) > 0 ? openstack_networking_subnetpool_v2.database.* : null
|
||||
sensitive = false
|
||||
description = "The database subnetpool object (as a list), if created"
|
||||
depends_on = []
|
||||
}
|
||||
|
||||
|
41
tests/module/.terraform.lock.hcl
Normal file
41
tests/module/.terraform.lock.hcl
Normal file
@ -0,0 +1,41 @@
|
||||
# This file is maintained automatically by "tofu init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.opentofu.org/hashicorp/vault" {
|
||||
version = "4.4.0"
|
||||
hashes = [
|
||||
"h1:s0t6P9ZfUQnHLxtUcnpPWpME68KwO/OxZqHAKSIvOoo=",
|
||||
"zh:0309ea8f81386e17ab13c06c5991ca959708c55c815b0cfba2bbcd865e0d606e",
|
||||
"zh:40e56199ccd266bffa216e8ebbcdc2e29b6ef5145b39377be766e763cac759c8",
|
||||
"zh:6fad1f073bd2e53e34736e000f98db581137e153ac80bbb5c4f1a1e38b46a1d2",
|
||||
"zh:74564fd4759decccf7f3c952aa2feba1012f103a66ec354aa3b3292a2f1b2412",
|
||||
"zh:7aae012c1a43e6e5dae6f608ec0f08cdb3f95fa121a32e413fe7ee37cb99947f",
|
||||
"zh:7c83f508e164844b1dd9bafe9de0fe60c7be7b55a02e704a6e2f50cff38b7d96",
|
||||
"zh:873a42322b68d9fba4a38217b97ee04a1eb617e811d7f9954016f5c3eb6cb0bc",
|
||||
"zh:9db2b13472cf91a5f18f0a7c6ae532277c05b0980d87f492341426b981679f7b",
|
||||
"zh:ac1cbd2926265db80efe3f1814bed82901f7d8a7d4e5b1e22592e1eef234b1c7",
|
||||
"zh:f465a955cc96f640e7426a648ba672c169a4a2959bad6146fe61583d67642561",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.opentofu.org/terraform-provider-openstack/openstack" {
|
||||
version = "2.1.0"
|
||||
constraints = ">= 1.54.0, ~> 2.1.0"
|
||||
hashes = [
|
||||
"h1:2TcmfEzBOGQPALErrXTaL6v+k/WAL40adao4izRYmdw=",
|
||||
"zh:113661750398bf21c8fe36aade9fb6f5eb82b5bcd3bcd30bd37ac805d83398f4",
|
||||
"zh:1b3c26347b9cd61e413ee93c2f422cc3278a77f55fd3516eaabb3e2a85f65281",
|
||||
"zh:1b751bbf1e4152829a643b532fd3f5967a2e89a41fac381257e0b41665be3306",
|
||||
"zh:1b967bbfd9b344419c0e0df0c3a15fcbd731e91f19a18955a55aace8d9ec039a",
|
||||
"zh:1bc0fc7c0a21e568db043b654501ce668ba19bf7628d37a7d2aaa512fd6e5aeb",
|
||||
"zh:425cbf61757d4b503e7bf0f409ea59835ca3afbd2432d56ad552c2e5d234a572",
|
||||
"zh:67d4f059cb4d73bf6c060313ec32962c4e5bd8dc7be2542a6f2098ab32575cd9",
|
||||
"zh:7fe841ac5b68a4f52fb3cf45070828f3845de44746679d434e4349f3c23e3ef2",
|
||||
"zh:ac1ed4c6ef0b6a3410568a05d3f9933d184497f065988503c43da0b2f0786ab2",
|
||||
"zh:c5c0d14c86fabd9ab6a5d555e6a8d511942665fb5fa948dd452b0d1934068344",
|
||||
"zh:c9ae5c210192275185d6823566a9421983e8e64c2665a4cae00b92dd0706bd19",
|
||||
"zh:ee9865ccc053e7f345e532654fb628d1cf1e81cd2e929643c1691bebffcf7b98",
|
||||
"zh:f3416d2f666095e740522c4964e436470bb9ec17bd53aaae8169ad93297d07bd",
|
||||
"zh:fbca85457dd49e17168989d64f7cfc4a519d55ef4e00e89cea2859e87ad87f83",
|
||||
]
|
||||
}
|
57
tests/module/README.md
Normal file
57
tests/module/README.md
Normal file
@ -0,0 +1,57 @@
|
||||
# module
|
||||
|
||||
<!-- BEGIN_TF_DOCS -->
|
||||
### Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="requirement_terraform"></a> [terraform](#requirement_terraform) | >= 1.0.0 |
|
||||
| <a name="requirement_openstack"></a> [openstack](#requirement_openstack) | ~> 2.1.0 |
|
||||
|
||||
### Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="provider_openstack"></a> [openstack](#provider_openstack) | ~> 2.1.0 |
|
||||
| <a name="provider_vault"></a> [vault](#provider_vault) | n/a |
|
||||
|
||||
### Modules
|
||||
|
||||
| Name | Source | Version |
|
||||
|------|--------|---------|
|
||||
| <a name="module_landing_zone"></a> [landing_zone](#module_landing_zone) | ../../ | n/a |
|
||||
|
||||
### Resources
|
||||
|
||||
| Name | Type |
|
||||
|------|------|
|
||||
| [openstack_networking_network_v2.ext_floating](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/data-sources/networking_network_v2) | data source |
|
||||
| [vault_kv_secret_v2.openstack_provider_project_info](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/data-sources/kv_secret_v2) | data source |
|
||||
| [vault_kv_secret_v2.openstack_provider_project_user](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/data-sources/kv_secret_v2) | data source |
|
||||
| [vault_kv_secret_v2.openstack_provider_region](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/data-sources/kv_secret_v2) | data source |
|
||||
|
||||
### Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| <a name="input_application_subnetpool_cidr_blocks"></a> [application_subnetpool_cidr_blocks](#input_application_subnetpool_cidr_blocks) | The CIDR blocks for the application subnet pool | `list(string)` | <pre>[<br> "192.168.0.0/21"<br>]</pre> | no |
|
||||
| <a name="input_application_subnetpool_id"></a> [application_subnetpool_id](#input_application_subnetpool_id) | The id of the subnetpool to create the public (first 2 tier) networks from.<br>Since this module can route private subnets to the backbone, it needs to make sure it's not creating overlapping subnets. | `string` | `null` | no |
|
||||
| <a name="input_architecture_tiers"></a> [architecture_tiers](#input_architecture_tiers) | The type of architecture.<br>Can be either 0, 1, 2 or 3.<br>Tier 0 will not create any subnets or networks.<br>Tier 1 will only create a single frontend subnet.<br>Tier 2 will create a frontend and backend subnet.<br>Tier 3 will create a frontend, backend and database subnet. | `number` | `1` | no |
|
||||
| <a name="input_attach_to_external"></a> [attach_to_external](#input_attach_to_external) | Whether to attach the router to an external network.<br>This will add a gateway interface to the router, and possibly consume a public IP address which might be billed by your cloud provider. | `bool` | `false` | no |
|
||||
| <a name="input_backend_subnet_prefix_len"></a> [backend_subnet_prefix_len](#input_backend_subnet_prefix_len) | The prefix length of the backend subnet. Must be between 20 and 32. | `number` | `24` | no |
|
||||
| <a name="input_create_application_subnetpool"></a> [create_application_subnetpool](#input_create_application_subnetpool) | Whether the module should create an application subnet pool for this project, or use an existing one. | `bool` | `true` | no |
|
||||
| <a name="input_create_database_subnetpool"></a> [create_database_subnetpool](#input_create_database_subnetpool) | Whether the module should create a database subnet pool for this project, or use an existing one. | `bool` | `true` | no |
|
||||
| <a name="input_create_default_secgroups"></a> [create_default_secgroups](#input_create_default_secgroups) | Whether to create default security groups or not.<br>Depending on your choice of architecture tiering, will create security groups so that each tier can connect to the one below.<br>Security groups for the database tier will be created for mariadb, postgresql and redis.<br>A default security group allowing ssh connection will also be created. | `bool` | `false` | no |
|
||||
| <a name="input_database_secgroup_strict"></a> [database_secgroup_strict](#input_database_secgroup_strict) | Defines whether the security groups for the database network should be strict.<br>In strict mode, egress is only allowed to the backend network. | `bool` | `false` | no |
|
||||
| <a name="input_database_subnet_prefix_len"></a> [database_subnet_prefix_len](#input_database_subnet_prefix_len) | The prefix length of the database subnet. Must be between 24 and 32. | `number` | `24` | no |
|
||||
| <a name="input_database_subnetpool_cidr_blocks"></a> [database_subnetpool_cidr_blocks](#input_database_subnetpool_cidr_blocks) | The CIDR blocks for the database subnet pool | `list(string)` | <pre>[<br> "192.168.8.0/23"<br>]</pre> | no |
|
||||
| <a name="input_database_subnetpool_id"></a> [database_subnetpool_id](#input_database_subnetpool_id) | The id of the subnetpool to create the databse network from.<br>Since this module can route private subnets to the backbone, it needs to make sure it's not creating overlapping subnets. | `string` | `null` | no |
|
||||
| <a name="input_frontend_subnet_prefix_len"></a> [frontend_subnet_prefix_len](#input_frontend_subnet_prefix_len) | The prefix length of the frontend subnet. Must be between 20 and 32. | `number` | `24` | no |
|
||||
| <a name="input_project_domain"></a> [project_domain](#input_project_domain) | The domain where this project will be created | `string` | `"default"` | no |
|
||||
| <a name="input_project_tags"></a> [project_tags](#input_project_tags) | The tags to append to this project | `list(string)` | `[]` | no |
|
||||
| <a name="input_public_nameservers"></a> [public_nameservers](#input_public_nameservers) | A list of public DNS servers to upstreams requests to in your subnets.<br>This is not necessary if your openstack deployment already has configured default upstreams for neutron. | `list(string)` | `[]` | no |
|
||||
|
||||
### Outputs
|
||||
|
||||
No outputs.
|
||||
<!-- END_TF_DOCS -->
|
18
tests/module/locals.tf
Normal file
18
tests/module/locals.tf
Normal file
@ -0,0 +1,18 @@
|
||||
locals {
|
||||
project_name = data.vault_kv_secret_v2.openstack_provider_project_info.data["tenant_name"]
|
||||
project_domain = var.project_domain
|
||||
project_tags = var.project_tags
|
||||
architecture_tiers = var.architecture_tiers
|
||||
create_application_subnetpool = var.create_application_subnetpool
|
||||
application_subnetpool_cidr_blocks = var.application_subnetpool_cidr_blocks
|
||||
create_database_subnetpool = var.create_database_subnetpool
|
||||
database_subnetpool_cidr_blocks = var.database_subnetpool_cidr_blocks
|
||||
frontend_subnet_prefix_len = var.frontend_subnet_prefix_len
|
||||
backend_subnet_prefix_len = var.backend_subnet_prefix_len
|
||||
database_subnet_prefix_len = var.database_subnet_prefix_len
|
||||
public_nameservers = var.public_nameservers
|
||||
create_default_secgroups = var.create_default_secgroups
|
||||
database_secgroup_strict = var.database_secgroup_strict
|
||||
attach_to_external = var.attach_to_external
|
||||
external_network_id = data.openstack_networking_network_v2.ext_floating.id
|
||||
}
|
67
tests/module/main.tf
Normal file
67
tests/module/main.tf
Normal file
@ -0,0 +1,67 @@
|
||||
terraform {
|
||||
required_version = ">= 1.0.0"
|
||||
required_providers {
|
||||
vault = {
|
||||
source = "hashicorp/vault"
|
||||
}
|
||||
openstack = {
|
||||
source = "terraform-provider-openstack/openstack"
|
||||
version = "~> 2.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "vault" {
|
||||
address = "https://active.vault.service.consul:8200"
|
||||
skip_tls_verify = true
|
||||
}
|
||||
|
||||
provider "openstack" {
|
||||
auth_url = data.vault_kv_secret_v2.openstack_provider_region.data["auth_url"]
|
||||
region = data.vault_kv_secret_v2.openstack_provider_region.data["region_name"]
|
||||
tenant_name = data.vault_kv_secret_v2.openstack_provider_project_info.data["tenant_name"]
|
||||
application_credential_id = data.vault_kv_secret_v2.openstack_provider_project_user.data["application_credential_id"]
|
||||
application_credential_secret = data.vault_kv_secret_v2.openstack_provider_project_user.data["application_credential_secret"]
|
||||
}
|
||||
|
||||
data "vault_kv_secret_v2" "openstack_provider_region" {
|
||||
mount = "kv"
|
||||
name = "infrastructure/openstack/regions/dc3_a"
|
||||
}
|
||||
|
||||
data "vault_kv_secret_v2" "openstack_provider_project_user" {
|
||||
mount = "kv"
|
||||
name = "infrastructure/openstack/projects/pcp_dawxdax/users/tofu"
|
||||
}
|
||||
|
||||
data "vault_kv_secret_v2" "openstack_provider_project_info" {
|
||||
mount = "kv"
|
||||
name = "infrastructure/openstack/projects/pcp_dawxdax/info"
|
||||
}
|
||||
|
||||
data "openstack_networking_network_v2" "ext_floating" {
|
||||
name = "ext-floating1"
|
||||
}
|
||||
|
||||
module "landing_zone" {
|
||||
source = "../../"
|
||||
|
||||
project_name = local.project_name
|
||||
project_domain = local.project_domain
|
||||
project_tags = local.project_tags
|
||||
|
||||
architecture_tiers = local.architecture_tiers
|
||||
create_application_subnetpool = local.create_application_subnetpool
|
||||
application_subnetpool_cidr_blocks = local.application_subnetpool_cidr_blocks
|
||||
create_database_subnetpool = local.create_database_subnetpool
|
||||
database_subnetpool_cidr_blocks = local.database_subnetpool_cidr_blocks
|
||||
frontend_subnet_prefix_len = local.frontend_subnet_prefix_len
|
||||
backend_subnet_prefix_len = local.backend_subnet_prefix_len
|
||||
database_subnet_prefix_len = local.database_subnet_prefix_len
|
||||
public_nameservers = local.public_nameservers
|
||||
|
||||
create_default_secgroups = local.create_default_secgroups
|
||||
|
||||
attach_to_external = local.attach_to_external
|
||||
external_network_id = local.external_network_id
|
||||
}
|
169
tests/module/variables.tf
Normal file
169
tests/module/variables.tf
Normal file
@ -0,0 +1,169 @@
|
||||
#! global variables
|
||||
variable "project_domain" {
|
||||
type = string
|
||||
description = "The domain where this project will be created"
|
||||
default = "default"
|
||||
}
|
||||
|
||||
variable "project_tags" {
|
||||
type = list(string)
|
||||
description = "The tags to append to this project"
|
||||
default = []
|
||||
}
|
||||
|
||||
#! architecture tiering variables
|
||||
variable "architecture_tiers" {
|
||||
type = number
|
||||
description = <<-EOT
|
||||
The type of architecture.
|
||||
Can be either 0, 1, 2 or 3.
|
||||
Tier 0 will not create any subnets or networks.
|
||||
Tier 1 will only create a single frontend subnet.
|
||||
Tier 2 will create a frontend and backend subnet.
|
||||
Tier 3 will create a frontend, backend and database subnet.
|
||||
EOT
|
||||
default = 1
|
||||
validation {
|
||||
condition = (
|
||||
var.architecture_tiers > 0 &&
|
||||
var.architecture_tiers <= 3
|
||||
)
|
||||
error_message = "The architecture_tiers must be between 0 and 3."
|
||||
}
|
||||
}
|
||||
|
||||
#! subnetpools creation
|
||||
variable "create_application_subnetpool" {
|
||||
type = bool
|
||||
description = "Whether the module should create an application subnet pool for this project, or use an existing one."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "application_subnetpool_cidr_blocks" {
|
||||
type = list(string)
|
||||
description = "The CIDR blocks for the application subnet pool"
|
||||
default = ["192.168.0.0/21"]
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for i in var.application_subnetpool_cidr_blocks : can(cidrhost(i, 0))
|
||||
])
|
||||
error_message = "The application_subnetpool_cidr_blocks must be a valid IPv4 CIDR"
|
||||
}
|
||||
}
|
||||
|
||||
variable "create_database_subnetpool" {
|
||||
type = bool
|
||||
description = "Whether the module should create a database subnet pool for this project, or use an existing one."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "database_subnetpool_cidr_blocks" {
|
||||
type = list(string)
|
||||
description = "The CIDR blocks for the database subnet pool"
|
||||
default = ["192.168.8.0/23"]
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for i in var.database_subnetpool_cidr_blocks : can(cidrhost(i, 0))
|
||||
])
|
||||
error_message = "The database_subnetpool_cidr_blocks must be a valid IPv4 CIDR"
|
||||
}
|
||||
}
|
||||
|
||||
#! networking variables
|
||||
variable "frontend_subnet_prefix_len" {
|
||||
type = number
|
||||
description = "The prefix length of the frontend subnet. Must be between 20 and 32."
|
||||
default = 24
|
||||
validation {
|
||||
condition = (
|
||||
var.frontend_subnet_prefix_len >= 20 &&
|
||||
var.frontend_subnet_prefix_len <= 32
|
||||
)
|
||||
error_message = "The prefix length must be between 20 and 32."
|
||||
}
|
||||
}
|
||||
|
||||
variable "backend_subnet_prefix_len" {
|
||||
type = number
|
||||
description = "The prefix length of the backend subnet. Must be between 20 and 32."
|
||||
default = 24
|
||||
validation {
|
||||
condition = (
|
||||
var.backend_subnet_prefix_len >= 20 &&
|
||||
var.backend_subnet_prefix_len <= 32
|
||||
)
|
||||
error_message = "The prefix length must be between 20 and 32."
|
||||
}
|
||||
}
|
||||
|
||||
variable "database_subnet_prefix_len" {
|
||||
type = number
|
||||
description = "The prefix length of the database subnet. Must be between 24 and 32."
|
||||
default = 24
|
||||
validation {
|
||||
condition = (
|
||||
var.database_subnet_prefix_len >= 24 &&
|
||||
var.database_subnet_prefix_len <= 32
|
||||
)
|
||||
error_message = "The prefix length must be between 24 and 32."
|
||||
}
|
||||
}
|
||||
|
||||
variable "public_nameservers" {
|
||||
type = list(string)
|
||||
description = <<-EOT
|
||||
A list of public DNS servers to upstreams requests to in your subnets.
|
||||
This is not necessary if your openstack deployment already has configured default upstreams for neutron.
|
||||
EOT
|
||||
default = []
|
||||
}
|
||||
|
||||
#! security variables
|
||||
variable "create_default_secgroups" {
|
||||
type = bool
|
||||
description = <<-EOT
|
||||
Whether to create default security groups or not.
|
||||
Depending on your choice of architecture tiering, will create security groups so that each tier can connect to the one below.
|
||||
Security groups for the database tier will be created for mariadb, postgresql and redis.
|
||||
A default security group allowing ssh connection will also be created.
|
||||
EOT
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "database_secgroup_strict" {
|
||||
type = bool
|
||||
description = <<-EOT
|
||||
Defines whether the security groups for the database network should be strict.
|
||||
In strict mode, egress is only allowed to the backend network.
|
||||
EOT
|
||||
default = false
|
||||
}
|
||||
|
||||
#! subnetpool variables & validation
|
||||
variable "application_subnetpool_id" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The id of the subnetpool to create the public (first 2 tier) networks from.
|
||||
Since this module can route private subnets to the backbone, it needs to make sure it's not creating overlapping subnets.
|
||||
EOT
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "database_subnetpool_id" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The id of the subnetpool to create the databse network from.
|
||||
Since this module can route private subnets to the backbone, it needs to make sure it's not creating overlapping subnets.
|
||||
EOT
|
||||
default = null
|
||||
}
|
||||
|
||||
#! public network attachement variables
|
||||
variable "attach_to_external" {
|
||||
type = bool
|
||||
description = <<-EOT
|
||||
Whether to attach the router to an external network.
|
||||
This will add a gateway interface to the router, and possibly consume a public IP address which might be billed by your cloud provider.
|
||||
EOT
|
||||
default = false
|
||||
}
|
59
tests/one_tier.tftest.hcl
Normal file
59
tests/one_tier.tftest.hcl
Normal file
@ -0,0 +1,59 @@
|
||||
run "two_tier" {
|
||||
module {
|
||||
source = "./tests/module"
|
||||
}
|
||||
|
||||
variables {
|
||||
project_domain = "default"
|
||||
project_tags = ["cloud", "test", "tofu"]
|
||||
architecture_tiers = 1
|
||||
create_application_subnetpool = true
|
||||
application_subnetpool_cidr_blocks = ["10.10.128.0/17"]
|
||||
create_database_subnetpool = false
|
||||
frontend_subnet_prefix_len = 24
|
||||
public_nameservers = ["9.9.9.9", "9.9.9.10"]
|
||||
create_default_secgroups = true
|
||||
database_secgroup_strict = false
|
||||
attach_to_external = true
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = alltrue([for i in module.landing_zone.apps_subnetpool[0].prefixes : can(cidrhost(i, 0))])
|
||||
error_message = "The application subnetpool does not seem correct"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = module.landing_zone.database_subnetpool == null
|
||||
error_message = "The database subnetpool is not null"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", module.landing_zone.frontend_network[0].id))
|
||||
error_message = "The frontend network was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = module.landing_zone.backend_network == null
|
||||
error_message = "The backend network is not null"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = module.landing_zone.database_network == null
|
||||
error_message = "The database network is not null"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", module.landing_zone.frontend_subnet[0].id))
|
||||
error_message = "The frontend subnet was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = module.landing_zone.backend_subnet == null
|
||||
error_message = "The backend subnet is not null"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = module.landing_zone.database_subnet == null
|
||||
error_message = "The database subnet is not null"
|
||||
}
|
||||
}
|
62
tests/three_tier.tftest.hcl
Normal file
62
tests/three_tier.tftest.hcl
Normal file
@ -0,0 +1,62 @@
|
||||
run "three_tier" {
|
||||
module {
|
||||
source = "./tests/module"
|
||||
}
|
||||
|
||||
variables {
|
||||
project_domain = "default"
|
||||
project_tags = ["cloud", "test", "tofu"]
|
||||
architecture_tiers = 3
|
||||
create_application_subnetpool = true
|
||||
application_subnetpool_cidr_blocks = ["10.10.128.0/17"]
|
||||
create_database_subnetpool = true
|
||||
database_subnetpool_cidr_blocks = ["192.168.0.0/16"]
|
||||
frontend_subnet_prefix_len = 24
|
||||
backend_subnet_prefix_len = 24
|
||||
database_subnet_prefix_len = 24
|
||||
public_nameservers = ["9.9.9.9", "9.9.9.10"]
|
||||
create_default_secgroups = true
|
||||
database_secgroup_strict = false
|
||||
attach_to_external = true
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = alltrue([for i in module.landing_zone.apps_subnetpool[0].prefixes : can(cidrhost(i, 0))])
|
||||
error_message = "The application subnetpool was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = alltrue([for i in module.landing_zone.database_subnetpool[0].prefixes : can(cidrhost(i, 0))])
|
||||
error_message = "The database subnetpool was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", module.landing_zone.frontend_network[0].id))
|
||||
error_message = "The frontend network was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", module.landing_zone.backend_network[0].id))
|
||||
error_message = "The backend network was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", module.landing_zone.database_network[0].id))
|
||||
error_message = "The database network was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", module.landing_zone.frontend_subnet[0].id))
|
||||
error_message = "The frontend subnet was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", module.landing_zone.backend_subnet[0].id))
|
||||
error_message = "The backend subnet was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", module.landing_zone.database_subnet[0].id))
|
||||
error_message = "The database subnet was not created successfully"
|
||||
}
|
||||
}
|
60
tests/two_tier.tftest.hcl
Normal file
60
tests/two_tier.tftest.hcl
Normal file
@ -0,0 +1,60 @@
|
||||
run "two_tier" {
|
||||
module {
|
||||
source = "./tests/module"
|
||||
}
|
||||
|
||||
variables {
|
||||
project_domain = "default"
|
||||
project_tags = ["cloud", "test", "tofu"]
|
||||
architecture_tiers = 2
|
||||
create_application_subnetpool = true
|
||||
application_subnetpool_cidr_blocks = ["10.10.128.0/17"]
|
||||
create_database_subnetpool = false
|
||||
frontend_subnet_prefix_len = 24
|
||||
backend_subnet_prefix_len = 24
|
||||
public_nameservers = ["9.9.9.9", "9.9.9.10"]
|
||||
create_default_secgroups = true
|
||||
database_secgroup_strict = false
|
||||
attach_to_external = true
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = alltrue([for i in module.landing_zone.apps_subnetpool[0].prefixes : can(cidrhost(i, 0))])
|
||||
error_message = "The application subnetpool does not seem correct"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = module.landing_zone.database_subnetpool == null
|
||||
error_message = "The database subnetpool is not null"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", module.landing_zone.frontend_network[0].id))
|
||||
error_message = "The frontend network was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", module.landing_zone.backend_network[0].id))
|
||||
error_message = "The backend network was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = module.landing_zone.database_network == null
|
||||
error_message = "The database network is not null"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", module.landing_zone.frontend_subnet[0].id))
|
||||
error_message = "The frontend subnet was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", module.landing_zone.backend_subnet[0].id))
|
||||
error_message = "The backend subnet was not created successfully"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = module.landing_zone.database_subnet == null
|
||||
error_message = "The database subnet is not null"
|
||||
}
|
||||
}
|
47
variables.tf
47
variables.tf
@ -41,22 +41,40 @@ variable "architecture_tiers" {
|
||||
}
|
||||
}
|
||||
|
||||
#! subnetpool creation
|
||||
variable "create_subnetpool" {
|
||||
#! subnetpools creation
|
||||
variable "create_application_subnetpool" {
|
||||
type = bool
|
||||
description = "Whether the module should create a subnet pool for this project, or use an existing one."
|
||||
description = "Whether the module should create an application subnet pool for this project, or use an existing one."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "subnetpool_cidr_blocks" {
|
||||
variable "application_subnetpool_cidr_blocks" {
|
||||
type = list(string)
|
||||
description = "The CIDR block for the subnet pool"
|
||||
description = "The CIDR blocks for the application subnet pool"
|
||||
default = ["192.168.0.0/21"]
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for i in var.subnetpool_cidr_blocks : can(cidrhost(i, 0))
|
||||
for i in var.application_subnetpool_cidr_blocks : can(cidrhost(i, 0))
|
||||
])
|
||||
error_message = "The subnetpool_cidr_blocks must be a valid IPv4 CIDR"
|
||||
error_message = "The application_subnetpool_cidr_blocks must be a valid IPv4 CIDR"
|
||||
}
|
||||
}
|
||||
|
||||
variable "create_database_subnetpool" {
|
||||
type = bool
|
||||
description = "Whether the module should create a database subnet pool for this project, or use an existing one."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "database_subnetpool_cidr_blocks" {
|
||||
type = list(string)
|
||||
description = "The CIDR blocks for the database subnet pool"
|
||||
default = ["192.168.8.0/23"]
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for i in var.database_subnetpool_cidr_blocks : can(cidrhost(i, 0))
|
||||
])
|
||||
error_message = "The database_subnetpool_cidr_blocks must be a valid IPv4 CIDR"
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,7 +170,7 @@ locals {
|
||||
}
|
||||
|
||||
#! subnetpool variables & validation
|
||||
variable "public_subnetpool_id" {
|
||||
variable "application_subnetpool_id" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The id of the subnetpool to create the public (first 2 tier) networks from.
|
||||
@ -171,14 +189,14 @@ variable "database_subnetpool_id" {
|
||||
}
|
||||
|
||||
locals {
|
||||
validate_public_subnetpool_ids = (
|
||||
validate_application_subnetpool_ids = (
|
||||
var.architecture_tiers > 0 &&
|
||||
var.create_subnetpool == false &&
|
||||
var.public_subnetpool_id == null
|
||||
var.create_application_subnetpool == false &&
|
||||
var.application_subnetpool_id == null
|
||||
) ? tobool("You have to either create or specify an existing subnetpool to create the public subnets from") : true
|
||||
validate_database_subnetpool_ids = (
|
||||
var.architecture_tiers > 2 &&
|
||||
var.create_subnetpool == false &&
|
||||
var.create_database_subnetpool == false &&
|
||||
var.database_subnetpool_id == null
|
||||
) ? tobool("You have to either create or specify an existing subnetpool to create the database subnets from") : true
|
||||
}
|
||||
@ -187,9 +205,8 @@ locals {
|
||||
variable "attach_to_external" {
|
||||
type = bool
|
||||
description = <<-EOT
|
||||
Whether the frontend subnet should be routed or not to the external LAN.
|
||||
This options implies that you have sufficient permissions to configure static route on the backbone infrastructure.
|
||||
This will create an static route entry in the route table of the backbone router, in order to make your project available from the outside.
|
||||
Whether to attach the router to an external network.
|
||||
This will add a gateway interface to the router, and possibly consume a public IP address which might be billed by your cloud provider.
|
||||
EOT
|
||||
default = false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user