Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added semantic release to the CI pipeline. #21

Merged
merged 15 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<!-- markdownlint-disable MD041 -->
<!-- Use the following icons: Checked βœ… / Unchecked: πŸ”² -->
<!-- To cross through text ~~surround it in double tildes like this~~ -->
<!-- Use the following icons: Checked βœ… / Unchecked: πŸ”² -->

## Description

Please provide a brief summary of the changes made in this pull request.

## Type of change

Please check the relevant options, or cross through options which are not applicable to this change:
Please check the relevant options:

πŸ”² New feature (a change which adds functionality)
πŸ”² Bug fix (a change which fixes an issue)
Expand All @@ -20,12 +19,13 @@ Please check the relevant options, or cross through options which are not applic

## Checklist

Please check the relevant options, or cross through options which are not applicable to this change:
Please check the relevant options:

πŸ”² My code aligns with the style of this project
πŸ”² I have added comments in hard to understand areas
πŸ”² I have added tests that prove my change works
πŸ”² I have updated the documentation
πŸ”² If merging into main, I'm aware that the PR should be squash merged with [a commit message that adheres to the semantic release format](https://github.com/semantic-release/semantic-release/tree/master?tab=readme-ov-file#commit-message-format)

## Additional Information

Expand Down
29 changes: 27 additions & 2 deletions .github/workflows/ci-pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Install Terraform
uses: hashicorp/setup-terraform@v2
Expand Down Expand Up @@ -65,7 +65,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Install Terraform
uses: hashicorp/setup-terraform@v2
Expand Down Expand Up @@ -107,3 +107,28 @@ jobs:

- name: Run Trivy Scan
run: trivy filesystem --security-checks vuln,config --exit-code 1 --severity HIGH,CRITICAL --ignore-unfixed .

publishing:
name: Publish Release
runs-on: ubuntu-latest
needs: [build-verification, static-code-analysis]

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false # Disable default GITHUB_TOKEN persistence

- name: Create Semantic Release
uses: cycjimmy/[email protected]
id: semantic-release
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}

- name: Output Release Details
if: steps.semantic-release.outputs.new_release_published == 'true'
run: |
echo ${{ steps.semantic-release.outputs.new_release_version }}
echo ${{ steps.semantic-release.outputs.new_release_major_version }}
echo ${{ steps.semantic-release.outputs.new_release_minor_version }}
echo ${{ steps.semantic-release.outputs.new_release_patch_version }}
16 changes: 16 additions & 0 deletions .releaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"branches": [
"main"
],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/github"
],
"releaseRules": [
{ "breaking": true, "release": "major" },
{ "revert": true, "release": "patch" },
{ "type": "feat", "release": "minor" },
{ "message": "**", "release": "patch" }
]
}
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ The solution consists of a configurable Terraform module which deploys the follo
* Backup vault
* Backup policies
* Backup instances for the following resources:
* Blob storage
* Managed disks
* PostgreSQL flexible server
* Blob storage
* Managed disks
* PostgreSQL flexible server
* Integration of diagnostic settings with Azure Monitor

The resources created by the module reside in their own resource group.
Expand All @@ -23,6 +23,8 @@ See the following key docs for more information:
* [Design](./docs/design.md)
* [Usage](./docs/usage.md)
* [Developer Guide](./docs/developer-guide.md)
* [Security Guide](./docs/security-guide.md)
* [Pipelines](./docs/pipelines.md)

## Repository Structure

Expand Down Expand Up @@ -72,6 +74,12 @@ docker-compose -f ./docs/docker-compose.yml up

Once the container is running, navigate to [http://localhost:8000](http://localhost:8000).

## Releases

The project uses [Semantic Release](https://github.com/cycjimmy/semantic-release-action) to create and publish releases within the CI pipeline, which relies on [commit message conventions.](https://github.com/semantic-release/semantic-release/tree/master?tab=readme-ov-file#commit-message-format)

[See the following section of the documentation for more information](./docs/developer-guide.md#creating-a-release).

## Contributing

If you want to contribute to the project, raise a PR on GitHub.
Expand Down
109 changes: 0 additions & 109 deletions docs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,115 +36,6 @@ The following diagram illustrates the high level architecture:

1. Some resources such as Azure SQL and Azure Key Vault are not directly supported by Azure **backup vault**, but can be incorporated via a supplementary process that backs up the data to Azure Blob Storage first. In the case of Azure SQL, a typical scenario could be an Azure Logic App that takes a backup of Azure SQL on a regular basis and stores the data in Azure Blob Storage. It is the aspiration of this solution to provide guidance and tooling that teams can adopt to support these scenarios.

## Security Design

The following diagram illustrates the security design of the solution:

![Security Design](assets/security-design.drawio.svg)

See the following links for further details on some concepts relevant to the design:

* [Azure Multi-user Authorisation (MUA) and Resource Guard](https://learn.microsoft.com/en-us/azure/backup/multi-user-authorization-concept)
* [Backup Operator Role](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/storage#backup-operator)
* [Azure Privileged Identity Management (PIM)](https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management)

### Actors

> NOTE: The roles listed below are not an exhaustive list, and are only those which are of relevance to the backup solution.

1. Tenant Admin

The tenant admin, aka the "global administrator", is typically a restricted group of technical specialists and/or senior engineering staff. They have full control over the Azure tenant including all subscriptions and identities.

The actor holds the following roles:

* Tenant Owner
* Tenant RBAC Administrator

The following risks and mitigations should be considered:

| Risks | Mitigations |
|-|-|
| Backup instance tampered with. | Use of PIM for temporary elevated privileges. |
| Backup policy tampered with. | Use of MUA for restricted backup operations. |
| Role based access tampered. | Dedicated admin accounts. |
| No other account able to override a malicious actor. | |

1. Subscription Admin

The subscription admin is typically a restricted group of team leads who are deploying their teams solutions to the subscription. They have full control over the subscription, including the backup vault and the backup resources.

The actor holds the following roles:

* Subscription Owner
* Subscription RBAC Administrator

The following risks and mitigations should be considered:

| Risks | Mitigations |
|-|-|
| Backup instance tampered with.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Use of PIM for temporary elevated privileges. |
| Backup policy tampered with. | Use of MUA for restricted backup operations. |
| Role based access tampered. | |

1. Deployment Service Principal

The deployment service principal is an unattended credential used to deploy the solution from an automated process such as a pipeline or workflow. It has the permission to deploy resources (such as the backup vault) and assign the roles required for the solution to operate.

The actor holds the following roles:

* Subscription Contributor
* Subscription RBAC Administrator limited to the roles required by the deployment

The following risks and mitigations should be considered:

| Risks | Mitigations |
|-|-|
| Backup instance tampered with.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Use of PIM for temporary elevated privileges. |
| Backup policy tampered with. | Use of MUA for restricted backup operations. |
| Role based access tampered. | Secret scanning in pipeline. |
| Poor secret management. | Robust secret management procedures. |

1. Backup Admin

The backup admin is typically a group of team support engineers and/or technical specialists. They have the permission to monitor backup telemetry, and restore backups in order to recover services.

The actor holds the following roles:

* Subscription Backup Operator

1. Backup Monitor

The backup monitor is typically a group of service staff. They have the permission to monitor backup telemetry in order to raise the alarm if any issues are found.

The actor holds the following roles:

* Monitoring Reader

1. Security Admin

The security admin is typically a group of cyber security specialists that are isolated from the other actors, by being in a different tenant or a highly restricted subscription. They have permissions to manage Resource Guard, which provide multi user authorisation to perform restricted operations on the backup vault, such as changing policies or stopping a backup instance.

The actor holds the following roles:

* Subscription Backup MUA Administrator

| Risks | Mitigations |
|-|-|
| Elevated roles note revoked.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Use of PIM for temporary elevated privileges. |
| | Robust and well documented processes. |

**NOTE: MUA without PIM requires a manual revocation of elevated permissions.**

1. Backup Vault Managed Identity

The backup vault managed identity is a "System Assigned" managed identity that performs backup vault operations. It is restricted to just the services defined at deployment, and cannot be compromised at runtime.

The actor holds the following roles:

* Backup Vault Resource Writer
* Reader role on resources that require backup

## Terraform Design

The following diagram illustrates the terraform design:
Expand Down
53 changes: 17 additions & 36 deletions docs/developer-guide.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- markdownlint-disable MD033 -->

# Developer Guide

## Overview
Expand Down Expand Up @@ -90,7 +92,9 @@ Take the following steps to get started in configuring and verifying the infrast
terraform destroy -auto-approve
```

## Integration Tests
## Testing

### Integration Tests

The test suite consists of a number Terraform HCL integration tests that use a mock azurerm provider.

Expand Down Expand Up @@ -120,7 +124,7 @@ Take the following steps to run the test suite:
terraform test
````

## End to End Tests
### End to End Tests

The end to end tests are written in go, and use the [terratest library](https://terratest.gruntwork.io/) and the [Azure SDK for Go](https://github.com/Azure/azure-sdk-for-go/tree/main).

Expand Down Expand Up @@ -172,7 +176,7 @@ To run the tests, take the following steps:
go test -v -timeout 10m
````

### Debugging
#### Debugging

To debug the tests in vscode, add the following configuration to launch settings and run the configuration:

Expand Down Expand Up @@ -201,41 +205,18 @@ To debug the tests in vscode, add the following configuration to launch settings

> For the storage account name, the TF state backend should have been created during the [getting started guide](#getting-started), at which point the storage account will have been created and the name generated.

## CI Pipeline

The CI pipeline builds and verifies the solution and runs a number of static code analysis steps on the code base.

Part of the build verification is end to end testing. This requires the pipeline to login to Azure and deploy an environment on which to execute the tests. In order for the pipeline to login to Azure the following GitHub actions secrets must be created:

* `AZURE_TENANT_ID`
The ID of an Azure tenant which can be used for the end to end test environment.

* `AZURE_SUBSCRIPTION_ID`
The ID of an Azure subscription which can be used for the end to end test environment.

* `AZURE_CLIENT_ID`
The client ID of an Azure service principal / app registration which can be used to authenticate with the end to end test environment.

The app registration must have contributor permissions on the subscription in order to create resources.

* `AZURE_CLIENT_SECRET`
The client secret of an Azure app registration which can be used to authenticate with the end to end test environment.

* `TF_STATE_RESOURCE_GROUP`
The resource group which contains the TF state storage account.
## Creating a Release

* `TF_STATE_STORAGE_ACCOUNT`
The storage account used for TF state.
The CI pipeline workflow uses the [Semantic Release](https://github.com/cycjimmy/semantic-release-action) GitHub action to create semantic version number (e.g. 1.0.0 / major.minor.patch), add a tag to the repository, and publish a release to GitHub. See the `./releaserc` file at the repo root to view the configuration that has been applied.

* `TF_STATE_STORAGE_COMTAINER`
The storage container used for TF state.
Semantic Release relies on commit message conventions, therefore any merge into `main` should squash merged with a commit message that [adheres to the semantic release formatting rules](https://github.com/semantic-release/semantic-release/tree/master?tab=readme-ov-file#commit-message-format).

### Static Code Analysis
**When a PR is merged into `main`, if no commit messages are found that meet the convention then the patch number is incremented by default.**

The following static code analysis checks are executed:
Here are some example commit messages which will result in a version increment:

* [Terraform format](https://developer.hashicorp.com/terraform/cli/commands/fmt)
* [Terraform lint](https://github.com/terraform-linters/tflint)
* [Checkov scan](https://www.checkov.io/)
* [Gitleaks scan](https://github.com/gitleaks/gitleaks)
* [Trivy vulnerability scan](https://github.com/aquasecurity/trivy)
|Commit Message|Type|Example|
|--------------|----|-------|
|fix: Fixed a bug.|Patch|1.1.**10** -> 1.1.**11**|
|feat: Added a feature.|Minor|1.**1**.10 -> 1.**2**.0|
|feat: Changed a feature. <br>BREAKING CHANGE: This change breaks things.|Major|**1**.1.10 -> **2**.0.0|
3 changes: 2 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The following technologies have been used:
* [Azure](<https://azure.microsoft.com/en-gb/>)
* [Azure CLI](https://learn.microsoft.com/en-us/cli/azure)
* [Terraform](https://developer.hashicorp.com/terraform)
* [Go (used for end-to-end testing)](https://go.dev/dl/)
* [MkDocs](https://www.mkdocs.org/) and the [Squidfunk MkDocs Material UI theme](https://squidfunk.github.io/mkdocs-material/)
* [Go (for end-to-end testing)](https://go.dev/dl/)
* [Terratest](https://terratest.gruntwork.io/)
* [Azure SDK for Go](https://github.com/Azure/azure-sdk-for-go)
Loading
Loading