Skip to content

Commit be7d910

Browse files
authored
Feature/Develop MVP July 2025 (#8)
* Delete automation doc * Cosmetic code changes to Docker sample * Dump version to 1.1.0 * Use SUSE Base container images * Improve README and update action version in GitLab Actions * Update max CVE to 0 in container scan * Update packages * Use ThrowIfNull in RawRequestBodyFormatter CanRead method * Add CI/CD pipelines section in CONTRIBUTING * Update Sonar key in badge * Fix Sonar warning about Dockerfile * Code improvements following update to .NET 8 * Use file scoped namespace * Add HealthCheckResource_Create_ReturnsOk integration test * Add HealthCheckResource_Create_ReturnsOk integration test * Improve BehaviorServiceCollectionExtensions * Add HealthCheckResource_GetNotExisting_ReturnsOk test Replace FluentAssertions with AwesomeAssertions Move files to libraries when not specific to project * Add integration tests and start implementing state lock * Add terraform-local-exec * Finalize tests * Improve test and doc * Small changes * Use StateModel for tests * Add tenant * Update samples * Add test on InvalidModelStateBehavior * Add user repository in db with password encryption and check * Add db scripts in CI * Make script executable
1 parent 6db453e commit be7d910

File tree

68 files changed

+1264
-809
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1264
-809
lines changed

.github/workflows/ci.yaml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,24 @@ jobs:
2424
runs-on: ubuntu-latest
2525
steps:
2626
- name: Checkout repository
27-
uses: actions/checkout@v3
27+
uses: actions/checkout@v4
2828
with:
2929
fetch-depth: 0
3030
- name: Checkout workflow parts
31-
uses: actions/checkout@v3
31+
uses: actions/checkout@v4
3232
with:
3333
repository: devpro/github-workflow-parts
3434
ref: feature/sonar-login-deprecation
3535
path: workflow-parts
3636
- name: Start MongoDB
3737
uses: ./workflow-parts/mongodb/start
38+
- name: Initialize database
39+
run: |
40+
mongosh mongodb://localhost:27017/terraform_backend_dev scripts/mongo-create-index.js
41+
sudo apt-get -y install apache2-utils
42+
./scripts/mongo-create-user.sh admin admin123 dummy
43+
mongosh mongodb://localhost:27017/terraform_backend_dev scripts/add-user.js
44+
shell: bash
3845
- name: Build, lint & test
3946
uses: ./workflow-parts/dotnet/build-lint-test
4047
with:
@@ -61,10 +68,10 @@ jobs:
6168
uses: ./workflow-parts/docker/build-scan
6269
with:
6370
docker_file: 'src/WebApi/Dockerfile'
64-
image_tag: 1.0.${{ github.run_id }}
71+
image_tag: 1.1.${{ github.run_id }}
6572
image_path: 'docker.io/devprofr'
6673
image_name: terraform-backend-mongodb
67-
max_high_cves: 16
68-
max_medium_cves: 11
74+
max_high_cves: 0
75+
max_medium_cves: 0
6976
env:
7077
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/pkg.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- name: Checkout source code
18-
uses: actions/checkout@v3
18+
uses: actions/checkout@v4
1919
- name: Checkout workflow parts
20-
uses: actions/checkout@v3
20+
uses: actions/checkout@v4
2121
with:
2222
repository: devpro/github-workflow-parts
2323
ref: main
@@ -29,7 +29,7 @@ jobs:
2929
container_username: ${{ secrets.DOCKERHUB_USERNAME }}
3030
container_password: ${{ secrets.DOCKERHUB_TOKEN }}
3131
docker_file: 'src/WebApi/Dockerfile'
32-
image_tag: 1.0.${{ github.run_id }}
32+
image_tag: 1.1.${{ github.run_id }}
3333
image_path: 'docker.io/devprofr'
3434
image_name: terraform-backend-mongodb
3535
create_latest: ${{ github.ref_name == 'main' }}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,3 +356,6 @@ appsettings.Development.json
356356
.terraform/
357357
.terraform.lock.hcl
358358
errored.tfstate
359+
360+
# temp script files
361+
scripts/add-user.js

CONTRIBUTING.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Project development guide
2+
3+
## Design
4+
5+
The application is entirely based on open-source, cross-platform (Linux/Windows), highly performant, free, object-oriented technologies: .NET / C#.
6+
7+
### Projects
8+
9+
Project name | Technology | Project type
10+
---------------------------|------------|---------------------------
11+
`Common.AspNetCore` | .NET 8 | Library
12+
`Common.AspNetCore.WebApi` | .NET 8 | Library
13+
`Common.MongoDb` | .NET 8 | Library
14+
`Domain` | .NET 8 | Library
15+
`Infrastructure.MongoDb` | .NET 8 | Library
16+
`WebApi` | ASP.NET 8 | Web application (REST API)
17+
18+
### Packages (NuGet)
19+
20+
Name | Description
21+
-------------------------|-----------------------------
22+
`MongoDB.Bson` | MongoDB BSON
23+
`MongoDB.Driver` | MongoDB .NET Driver
24+
`Swashbuckle.AspNetCore` | OpenAPI / Swagger generation
25+
`System.Text.Json` | JSON support
26+
27+
### Documentation
28+
29+
* [OpenTofu](https://opentofu.org/)
30+
* [MongoDB](https://www.mongodb.com/)
31+
* [Terraform](https://www.terraform.io)
32+
* [HTTP backend](https://developer.hashicorp.com/terraform/language/backend/http)
33+
* [Remote state backend](https://github.com/hashicorp/terraform/tree/main/internal/backend/remote-state).
34+
35+
### References of other implementations
36+
37+
* [GitLab](https://gitlab.com/gitlab-org/manage/import/gitlab/-/blob/master/doc/user/infrastructure/terraform_state.md)
38+
* [lib/api/terraform/state.rb](https://gitlab.com/gitlab-org/manage/import/gitlab/-/blob/master/lib/api/terraform/state.rb)
39+
* HTTP
40+
* [akshay/terraform-http-backend-pass](https://git.coop/akshay/terraform-http-backend-pass)
41+
* [bhoriuchi/terraform-backend-http](https://github.com/bhoriuchi/terraform-backend-http)
42+
* git
43+
* [plumber-cd/terraform-backend-git](https://github.com/plumber-cd/terraform-backend-git)
44+
45+
## Automation
46+
47+
### Build (CI/CD pipelines)
48+
49+
GitHub Actions are triggered to automate the integration and delivery of the application:
50+
51+
- [CI](.github/workflows/ci.yaml)
52+
- [PKG](.github/workflows/pkg.yaml)
53+
54+
GitHub project has been configured, in **General** / **Security** / **Secrets and Variables** / **Actions**:
55+
56+
- DOCKERHUB_TOKEN
57+
- DOCKERHUB_USERNAME
58+
- SONAR_HOST_URL
59+
- SONAR_ORG
60+
- SONAR_PROJECT_KEY
61+
- SONAR_TOKEN
62+
63+
## Procedures
64+
65+
### Run locally the application
66+
67+
Create/have a MongoDB database (example with a local container but you can provision a cluster in MongoDB Atlas):
68+
69+
```bash
70+
# creates a container
71+
docker run --name mongodb -d -p 27017:27017 mongo:8.0
72+
# (optional) adds indexes for optimal performances
73+
docker run --rm --link mongodb \
74+
-v "$(pwd)/scripts":/home/scripts mongo:8.0 \
75+
bash -c "mongosh mongodb://mongodb:27017/terraform_backend_dev /home/scripts/mongo-create-index.js"
76+
# creates one user
77+
./scripts/mongo-create-user.sh admin admin123 dummy
78+
docker run --rm --link mongodb \
79+
-v "$(pwd)/scripts":/home/scripts mongo:8.0 \
80+
bash -c "mongosh mongodb://mongodb:27017/terraform_backend_dev /home/scripts/add-user.js"
81+
```
82+
83+
Run the web API (example with the command line but an IDE like Visual Studio or Rider would be nice to be able to debug):
84+
85+
```bash
86+
dotnet run --project src/WebApi
87+
```
88+
89+
Open Swagger in a browser: [localhost:5293/swagger](http://localhost:5293/swagger).

Devpro.TerraformBackend.sln

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "0 - Solution Items", "0 - S
77
ProjectSection(SolutionItems) = preProject
88
.editorconfig = .editorconfig
99
.gitignore = .gitignore
10-
.gitlab-ci.yml = .gitlab-ci.yml
1110
compose.yaml = compose.yaml
11+
CONTRIBUTING.md = CONTRIBUTING.md
1212
Directory.Build.props = Directory.Build.props
1313
README.md = README.md
1414
EndProjectSection
1515
EndProject
16-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2 - Applications", "2 - Applications", "{6D13F54F-4547-49C7-8136-01BFB4BBEE1E}"
16+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3 - Applications", "3 - Applications", "{6D13F54F-4547-49C7-8136-01BFB4BBEE1E}"
1717
EndProject
18-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1 - Libraries", "1 - Libraries", "{E9839BEC-B050-43E9-8EFD-34659CC92D93}"
18+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2 - Business", "2 - Business", "{E9839BEC-B050-43E9-8EFD-34659CC92D93}"
1919
EndProject
2020
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApi", "src\WebApi\WebApi.csproj", "{5CD7A689-5ADB-4207-972E-6FA881AF1B1C}"
2121
EndProject
@@ -29,29 +29,33 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{3C2E
2929
EndProject
3030
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.AspNetCore", "src\Common.AspNetCore\Common.AspNetCore.csproj", "{F23098F5-355B-46F0-BABE-3D6E23D8EED7}"
3131
EndProject
32-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "terraform-docker", "terraform-docker", "{001CB9EB-2F7E-4288-BA9B-1E01ED43B8FF}"
32+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker-nginx", "docker-nginx", "{001CB9EB-2F7E-4288-BA9B-1E01ED43B8FF}"
3333
ProjectSection(SolutionItems) = preProject
34-
samples\terraform-docker\main.tf = samples\terraform-docker\main.tf
35-
samples\terraform-docker\outputs.tf = samples\terraform-docker\outputs.tf
36-
samples\terraform-docker\providers.tf = samples\terraform-docker\providers.tf
37-
samples\terraform-docker\README.md = samples\terraform-docker\README.md
38-
samples\terraform-docker\variables.tf = samples\terraform-docker\variables.tf
34+
samples\docker-nginx\main.tf = samples\docker-nginx\main.tf
35+
samples\docker-nginx\outputs.tf = samples\docker-nginx\outputs.tf
36+
samples\docker-nginx\providers.tf = samples\docker-nginx\providers.tf
37+
samples\docker-nginx\README.md = samples\docker-nginx\README.md
38+
samples\docker-nginx\variables.tf = samples\docker-nginx\variables.tf
3939
EndProjectSection
4040
EndProject
4141
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{7F01D180-1A34-4377-B4E5-C852D8302CE7}"
4242
ProjectSection(SolutionItems) = preProject
4343
scripts\mongo-create-index.js = scripts\mongo-create-index.js
44-
EndProjectSection
45-
EndProject
46-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{4EC46C35-77AA-4C4E-AEAC-63A2D44C9CA6}"
47-
ProjectSection(SolutionItems) = preProject
48-
docs\automation.md = docs\automation.md
44+
scripts\mongo-create-user.sh = scripts\mongo-create-user.sh
4945
EndProjectSection
5046
EndProject
5147
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApi.IntegrationTests", "test\WebApi.IntegrationTests\WebApi.IntegrationTests.csproj", "{B055FFAF-8261-43B1-866A-12E289D5D7DC}"
5248
EndProject
5349
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.AspNetCore.WebApi", "src\Common.AspNetCore.WebApi\Common.AspNetCore.WebApi.csproj", "{19336002-C959-4E76-B112-861F93CF6423}"
5450
EndProject
51+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1 - Framework", "1 - Framework", "{0C1E6968-B289-4378-84CF-B64E05E643A5}"
52+
EndProject
53+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "local-files", "local-files", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
54+
ProjectSection(SolutionItems) = preProject
55+
samples\local-files\main.tf = samples\local-files\main.tf
56+
samples\local-files\README.md = samples\local-files\README.md
57+
EndProjectSection
58+
EndProject
5559
Global
5660
GlobalSection(SolutionConfigurationPlatforms) = preSolution
5761
Debug|Any CPU = Debug|Any CPU
@@ -94,14 +98,14 @@ Global
9498
{5CD7A689-5ADB-4207-972E-6FA881AF1B1C} = {6D13F54F-4547-49C7-8136-01BFB4BBEE1E}
9599
{A5CAD112-C1E6-442B-BE0E-37C697030636} = {E9839BEC-B050-43E9-8EFD-34659CC92D93}
96100
{0429A41A-2D3A-42D4-8736-5FC0F6F0FF0C} = {E9839BEC-B050-43E9-8EFD-34659CC92D93}
97-
{49BF313A-4ED3-4BD2-9AEE-E44A5ED19C0C} = {E9839BEC-B050-43E9-8EFD-34659CC92D93}
101+
{49BF313A-4ED3-4BD2-9AEE-E44A5ED19C0C} = {0C1E6968-B289-4378-84CF-B64E05E643A5}
98102
{3C2E7F7E-1F8E-49D1-AD56-EC60BEB5299D} = {7B3738E0-6F86-4358-B55C-5AAD42B24F81}
99-
{F23098F5-355B-46F0-BABE-3D6E23D8EED7} = {E9839BEC-B050-43E9-8EFD-34659CC92D93}
103+
{F23098F5-355B-46F0-BABE-3D6E23D8EED7} = {0C1E6968-B289-4378-84CF-B64E05E643A5}
100104
{001CB9EB-2F7E-4288-BA9B-1E01ED43B8FF} = {3C2E7F7E-1F8E-49D1-AD56-EC60BEB5299D}
101105
{7F01D180-1A34-4377-B4E5-C852D8302CE7} = {7B3738E0-6F86-4358-B55C-5AAD42B24F81}
102-
{4EC46C35-77AA-4C4E-AEAC-63A2D44C9CA6} = {7B3738E0-6F86-4358-B55C-5AAD42B24F81}
103106
{B055FFAF-8261-43B1-866A-12E289D5D7DC} = {6D13F54F-4547-49C7-8136-01BFB4BBEE1E}
104-
{19336002-C959-4E76-B112-861F93CF6423} = {E9839BEC-B050-43E9-8EFD-34659CC92D93}
107+
{19336002-C959-4E76-B112-861F93CF6423} = {0C1E6968-B289-4378-84CF-B64E05E643A5}
108+
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {3C2E7F7E-1F8E-49D1-AD56-EC60BEB5299D}
105109
EndGlobalSection
106110
GlobalSection(ExtensibilityGlobals) = postSolution
107111
SolutionGuid = {DC545534-6A10-475B-A0DA-3374CC025D82}

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<PropertyGroup>
77
<!-- edit this value to change the current MAJOR.MINOR.PATCH version -->
8-
<VersionPrefix>1.0.2</VersionPrefix>
8+
<VersionPrefix>1.1.0</VersionPrefix>
99
</PropertyGroup>
1010

1111
<Choose>

README.md

Lines changed: 17 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
1-
# Terraform backend management in MongoDB
1+
# MongoDB HTTP backend for Terraform/OpenTofu state
22

33
[![CI](https://github.com/devpro/terraform-backend-mongodb/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/devpro/terraform-backend-mongodb/actions/workflows/ci.yaml)
44
[![PKG](https://github.com/devpro/terraform-backend-mongodb/actions/workflows/pkg.yaml/badge.svg?branch=main)](https://github.com/devpro/terraform-backend-mongodb/actions/workflows/pkg.yaml)
5-
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=devpro.terraform-backend-mongodb&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=devpro.terraform-backend-mongodb)
5+
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=devpro_terraform-backend-mongodb&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=devpro_terraform-backend-mongodb)
66
[![Docker Image Version](https://img.shields.io/docker/v/devprofr/terraform-backend-mongodb?label=Image&logo=docker)](https://hub.docker.com/r/devprofr/terraform-backend-mongodb)
77

8-
Store [Terraform](https://www.terraform.io) state in [MongoDB](https://www.mongodb.com/), using
9-
[HTTP](https://www.terraform.io/language/settings/backends/http) [backend](https://github.com/hashicorp/terraform/tree/main/internal/backend/remote-state).
8+
Manage Terraform/OpenTofu state through a secured REST API and take advatange of MongoDB greatness!
109

11-
## How to use
10+
The [project development guide](CONTRIBUTING.md) provides the implementation details.
1211

13-
* Create a MongoDB database (you can provision a cluster in MongoDB Atlas)
12+
## Quick start
1413

15-
```bash
16-
# example on a MongoDB container running locally
17-
docker run --name mongodb -d -p 27017:27017 mongo:5.0
18-
```
14+
1. Make sure a you have access to a MongoDB database
15+
16+
2. Configure the application with the MongoDB database connection information
1917

20-
* Run the web API
18+
2. Run the web API
2119

22-
* Update the Terraform file
20+
3. Update the Terraform file
2321

2422
```tf
2523
terraform {
2624
backend "http" {
27-
address = "<webapi_url>/state/<project_name>"
28-
lock_address = "<webapi_url>/state/<project_name>/lock"
29-
unlock_address = "<webapi_url>/state/<project_name>/lock"
25+
address = "<webapi_url>/<tenant>/state/<project_name>"
26+
lock_address = "<webapi_url>/<tenant>/state/<project_name>/lock"
27+
unlock_address = "<webapi_url>/<tenant>/state/<project_name>/lock"
3028
lock_method = "POST"
3129
unlock_method = "DELETE"
3230
username = "<api_username>"
@@ -37,53 +35,9 @@ terraform {
3735
}
3836
```
3937

40-
* Execute usual Terraform command lines
41-
42-
* (Optional) Add MongoDB indexes for optimal performances
43-
44-
```bash
45-
# example on a MongoDB container running locally
46-
docker run --rm --link mongodb \
47-
-v "$(pwd)/scripts":/home/scripts mongo:5.0 \
48-
bash -c "mongo mongodb://mongodb:27017/terraform_backend_dev /home/scripts/mongo-create-index.js"
49-
```
50-
51-
## How to demonstrate
52-
53-
* Run the [terraform-docker sample](samples/terraform-docker/README.md)
54-
55-
## How to contribute
56-
57-
This is a .NET 8 / C# codebase (open-source, cross-platform, free, object-oriented technologies)
58-
59-
### Project structure
60-
61-
Project name | Technology | Project type
62-
------------------------ | ---------- | --------------------------
63-
`Common.AspNetCore` | .NET 8 | Library
64-
`Common.MongoDb` | .NET 8 | Library
65-
`Common.Runtime` | .NET 8 | Library
66-
`Domain` | .NET 8 | Library
67-
`Infrastructure.MongoDb` | .NET 8 | Library
68-
`WebApi` | ASP.NET 8 | Web application (REST API)
69-
70-
### Packages (NuGet)
71-
72-
Name | Description
73-
------------------------ | ----------------------------
74-
`MongoDB.Bson` | MongoDB BSON
75-
`MongoDB.Driver` | MongoDB .NET Driver
76-
`Swashbuckle.AspNetCore` | OpenAPI / Swagger generation
77-
`System.Text.Json` | JSON support
78-
79-
## How to compare
38+
4. Execute usual Terraform command lines
8039

81-
### Samples with other solutions
40+
## Samples
8241

83-
* [GitLab](https://gitlab.com/gitlab-org/manage/import/gitlab/-/blob/master/doc/user/infrastructure/terraform_state.md)
84-
* [lib/api/terraform/state.rb](https://gitlab.com/gitlab-org/manage/import/gitlab/-/blob/master/lib/api/terraform/state.rb)
85-
* HTTP
86-
* [akshay/terraform-http-backend-pass](https://git.coop/akshay/terraform-http-backend-pass)
87-
* [bhoriuchi/terraform-backend-http](https://github.com/bhoriuchi/terraform-backend-http)
88-
* git
89-
* [plumber-cd/terraform-backend-git](https://github.com/plumber-cd/terraform-backend-git)
42+
* [Make local actions on files](samples/local-files/README.md)
43+
* [Run NGINX container with Docker](samples/docker-nginx/README.md)

compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ services:
2020
depends_on:
2121
- mongodb
2222
mongodb:
23-
image: mongo:6.0
23+
image: mongo:8.0
2424
ports:
2525
- "27017:27017"

docs/.gitkeep

Whitespace-only changes.

docs/automation.md

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)