diff --git a/.editorconfig b/.editorconfig index 3febdbe..90a1b97 100644 --- a/.editorconfig +++ b/.editorconfig @@ -19,6 +19,9 @@ trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false +[CNAME] +insert_final_newline = false + [*.cs] dotnet_sort_system_directives_first = true # Avoid "this." and "Me." if not necessary @@ -149,6 +152,3 @@ csharp_space_between_square_brackets = false csharp_prefer_braces = true:silent csharp_preserve_single_line_blocks = true csharp_preserve_single_line_statements = true - -[CNAME] -insert_final_newline = false diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4bb6fb4..3144060 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -112,6 +112,12 @@ docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material Open [localhost:8000](http://localhost:8000/). +You can also use hot reload to view changes without having to restart the container: + +```bash +docker run --rm -it -p 8000:8000 -v "${PWD}:/docs" squidfunk/mkdocs-material serve --dev-addr=0.0.0.0:8000 --livereload --dirtyreload --watch docs --watch mkdocs.yml +``` + ## Understand the application lifecycle automation GitHub Actions are triggered to automate the integration and delivery of the application: diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..421a572 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,8 @@ +# Architecture + +**Terraform Backend MongoDB** makes the link between Terraform and MongoDB, two industry standards. +It's an integration, not a new application. + +## High-level view + +![High level schema](assets/images/high-level.png) diff --git a/docs/assets/images/high-level.png b/docs/assets/images/high-level.png index cc647dc..4eaf891 100644 Binary files a/docs/assets/images/high-level.png and b/docs/assets/images/high-level.png differ diff --git a/docs/index.md b/docs/index.md index 8023ba1..b961ee3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,15 +1,29 @@ # Welcome -This project provides an HTTP backend for [Terraform](https://www.terraform.io), and [OpenTofu](https://opentofu.org/), to save the state data in a [MongoDB](https://www.mongodb.com/) database. +A simple, standards-compliant HTTP backend for [Terraform](https://www.terraform.io) (and [Terraform](https://www.terraform.io)) that stores state files in MongoDB. -As the state is a JSON content, it just makes sense to use the best-in-class technology to store it! +!!! tip + + Instead of relying on vendor-specific storage or local files, this backend lets you use MongoDB - a mature, horizontally scalable document database - as the storage layer for your Terraform state. + + Since Terraform state is already JSON, MongoDB is a natural and efficient fit. ## Key features -1. Highly available, performant, no vendor lock-in, storage system -2. Secured access to sensitive information, with tenant isolation -3. Integrate real data in your infrastructure management system +- **Full Terraform HTTP backend compliance** - works out-of-the-box with terraform `{ backend "http" }` (and OpenTofu) +- **Leverages MongoDB strengths** - high availability, replication, sharding, and strong performance for JSON documents +- **No vendor lock-in** - you control your MongoDB cluster (self-hosted, Atlas, Cosmos DB, etc.) +- **Fine-grained access control** - per-workspace (tenant) isolation +- **State file encryption at rest** - optional server-side encryption using MongoDB's native encrypted storage engine or client-side encryption +- **Locking support implemented** - Terraform checks and prevents concurrent modifications +- **Minimal dependencies** - simple open-source code, shipped in an image using SUSE BCI for security and performance +- **Audit trail** - all state operations logged with workspace, user/agent, and timestamp -## High-level view +## When to use this backend -![High level schema](assets/images/high-level.png) +- You already run MongoDB in your organization +- You want a highly available, globally distributed state store without adding another vendor +- You need strong RBAC and encryption controls that MongoDB already provides +- You prefer running one binary in Kubernetes or as a Docker container instead of managing S3 +- You want to use the valuable Terraform state information in your infrastructure management system +- You want to simplify the infrastructure automation with a single, highly available source of truth diff --git a/docs/quickstart.md b/docs/quickstart.md index 7a5b170..6901488 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -2,7 +2,7 @@ ## Demo -This is the exhaustive list of steps to use Terraform Backend MongoDB. +This is a complete walkthrough to see Terraform Backend MongoDB in action. -1. Make sure requirements are met: +1. Make sure the following tools are available from the commande line: - - [Terraform](https://developer.hashicorp.com/terraform/install), or [OpenTofu](https://opentofu.org/docs/intro/install/), must be available from the command line. + - [Docker](https://docs.docker.com/engine/install/) + - [Terraform](https://developer.hashicorp.com/terraform/install) -2. Run the application and the database in containers +2. Run the application and the database in containers: === "Docker" @@ -35,9 +38,7 @@ TODO: add other options docker compose up ``` - - -3. Create a user to authenticate calls +3. Create a user to authenticate calls: === "Docker" @@ -46,7 +47,7 @@ TODO: add other options MONGODB_CONTAINERNAME=tfbackmdb-mongodb-1 MONGODB_CONTAINERNETWORK=tfbackmdb_default tfbeadm create-user admin admin123 dummy ``` -4. Update Terraform backend (copy of an already configured simple sample) +4. Write Terraform files from a pre-configured sample: === "Docker" @@ -54,19 +55,19 @@ TODO: add other options curl -O https://raw.githubusercontent.com/devpro/terraform-backend-mongodb/refs/heads/main/samples/local-files/main.tf ``` -5. Initiatize Terraform +5. Prepare the working directory for use with Terraform: ```bash terraform init ``` -6. Apply changes +6. Performs the operations indicated in Terraform project files: ```bash terraform apply ``` -7. Query the state database +7. Query the state database to see the Terraform state information: === "Docker" @@ -75,7 +76,7 @@ TODO: add other options bash -c "mongosh \"mongodb://mongodb:27017/terraform_backend_dev\" --eval 'db.tf_state.find().projection({tenant: 1, name: 1, createdAt: 1, \"value.version\": 1, \"value.resources.type\": 1, \"value.resources.name\": 1})'" ``` -8. Destroy the resources +8. Destroy the resources that were created with Terraform: ```bash terraform destroy diff --git a/docs/setup.md b/docs/setup.md index 2627777..a534ed7 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -4,14 +4,14 @@ ### Database server -Make sure you have access to a MongoDB database (with a connection string containing a user that have admin permissions). +The application needs a MongoDB database that can be hosted in a: -The MongoDB server can run: +- MongoDB Cluster managed by Atlas (easiest solution, free tier available) +- MongoDB Replica Set running from release binaries on one or multiple servers +- MongoDB Replica Set running in containers from MongoDB container image (available on DockerHub) +- Kubernetes cluster using MongoDB Community or Enterprise Kubernetes Operator -- In a MongoDB Cluster managed by Atlas (easiest solution, free tier available) -- In one or multiple servers from release binaries -- In one or multiple containes from MongoDB container image (available on DockerHub) -- In a Kubernetes cluster using MongoDB Community or Enterprise Kubernetes operator +Once the database is available, grab the connection string for a user with admin permissions. !!! tip @@ -21,14 +21,24 @@ The MongoDB server can run: Add indexes for optimal performances: -```bash -curl -O https://raw.githubusercontent.com/devpro/terraform-backend-mongodb/refs/heads/main/scripts/tfbeadm -MONGODB_URI=mongodb://:27017/ tfbeadm create-indexes -``` +=== "Commands" + + ```js + db.tf_state.createIndex({"tenant": 1, "name": 1}) + db.tf_state_lock.createIndex({"tenant": 1, "name": 1}, {unique: true}) + db.user.createIndex({"username": 1}, {unique: true}) + ``` + +=== "Script" + + ```bash + curl -O https://raw.githubusercontent.com/devpro/terraform-backend-mongodb/refs/heads/main/scripts/tfbeadm + MONGODB_URI=mongodb://:27017/ tfbeadm create-indexes + ``` -!!! warning + !!! warning - `mongosh` or `Docker` must be available on the machine running the commands + `mongosh` or `Docker` must be available on the machine running the commands ## Installation diff --git a/docs/usage.md b/docs/usage.md index 9e15c55..8ff19fb 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -3,8 +3,9 @@ ## Tenant authentication API calls are secured through tenant isolation and user authentication, which are stored in the MongoDB database. +User password is encrypted. -Users must be added to the database with this script: +`tfbeadm` script is the easiest way to create the users correctly: ```bash curl -O https://raw.githubusercontent.com/devpro/terraform-backend-mongodb/refs/heads/main/scripts/tfbeadm diff --git a/mkdocs.yml b/mkdocs.yml index e74fbcb..ad4956f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -27,6 +27,7 @@ extra: generator: false nav: - index.md + - architecture.md - quickstart.md - setup.md - usage.md