Skip to content
Open
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
38 changes: 31 additions & 7 deletions nullplatform/code_repository/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@

## Description

Configures a nullplatform_provider_config resource for GitHub, GitLab, or Azure DevOps git provider integration within the Nullplatform platform
Configures a nullplatform_provider_config resource for GitHub, GitLab, Azure DevOps, or Bitbucket git provider integration within the Nullplatform platform

## Architecture

The module uses local values to evaluate which git provider is selected and conditionally creates a single nullplatform_provider_config resource based on the provider type. For GitLab, it creates a resource of type 'gitlab-configuration' with group_path, access_token, and installation_url attributes, extracting the parent NRN via regex. For GitHub, it creates a 'github-configuration' resource with organization and installation_id, and for Azure DevOps it creates an 'azure-devops-configuration' resource with project, access_token, and agent_pool, both stripping the namespace suffix from the NRN using replace(). All three resource variants share the nrn and dimensions inputs.
The module uses local values to evaluate which git provider is selected and conditionally creates a single nullplatform_provider_config resource based on the provider type. For GitLab, it creates a resource of type 'gitlab-configuration' with group_path, access_token, and installation_url attributes, extracting the parent NRN via regex. For GitHub, it creates a 'github-configuration' resource with organization and installation_id; for Azure DevOps it creates an 'azure-devops-configuration' resource with project, access_token, and agent_pool; and for Bitbucket it creates a 'bitbucket-configuration' resource with workspace, project_key, email, api_token, installation_url, and flavor under setup plus collaborators under access. All variants strip the namespace suffix from the NRN using replace() (GitLab via regex) and share the nrn and dimensions inputs.

## Features

- Creates a nullplatform_provider_config resource for GitLab with group path, access token, and installation URL
- Creates a nullplatform_provider_config resource for GitHub with organization name and App installation ID
- Creates a nullplatform_provider_config resource for Azure DevOps with project name, access token, and agent pool
- Creates a nullplatform_provider_config resource for Bitbucket with workspace, project key, email, API token (sensitive), installation URL, flavor, and collaborators
- Supports dimensional segmentation of provider configs via a dimensions map input
- Validates that all provider-specific required variables are supplied when the corresponding git_provider value is selected

Expand Down Expand Up @@ -56,6 +57,21 @@ module "code_repository" {
}
```

### Usage with Bitbucket Integration

```hcl
module "code_repository" {
source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/code_repository?ref=v6.6.0"

git_provider = "bitbucket"
bitbucket_workspace = "your-bitbucket-workspace" # Required when git_provider = "bitbucket"
bitbucket_project_key = "your-bitbucket-project-key" # Required when git_provider = "bitbucket"
bitbucket_email = "bot@your-org.com" # Required when git_provider = "bitbucket"
bitbucket_api_token = "your-bitbucket-api-token" # Required when git_provider = "bitbucket" (sensitive)
nrn = "your-nrn"
}
```

## Using Outputs

```hcl
Expand All @@ -69,32 +85,40 @@ resource "example_resource" "this" {
## Requirements

| Name | Version |
|------|---------|
| ---- | ------- |
| <a name="requirement_nullplatform"></a> [nullplatform](#requirement\_nullplatform) | ~> 0.0.86 |

## Providers

| Name | Version |
|------|---------|
| ---- | ------- |
| <a name="provider_nullplatform"></a> [nullplatform](#provider\_nullplatform) | 0.0.95 |

## Resources

| Name | Type |
|------|------|
| ---- | ---- |
| [nullplatform_provider_config.azure](https://registry.terraform.io/providers/nullplatform/nullplatform/latest/docs/resources/provider_config) | resource |
| [nullplatform_provider_config.bitbucket](https://registry.terraform.io/providers/nullplatform/nullplatform/latest/docs/resources/provider_config) | resource |
| [nullplatform_provider_config.github](https://registry.terraform.io/providers/nullplatform/nullplatform/latest/docs/resources/provider_config) | resource |
| [nullplatform_provider_config.gitlab](https://registry.terraform.io/providers/nullplatform/nullplatform/latest/docs/resources/provider_config) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| ---- | ----------- | ---- | ------- | :------: |
| <a name="input_azure_access_token"></a> [azure\_access\_token](#input\_azure\_access\_token) | Azure devops personal access token | `string` | `null` | no |
| <a name="input_azure_agent_pool"></a> [azure\_agent\_pool](#input\_azure\_agent\_pool) | Azure devops CI agent pool | `string` | `"Default"` | no |
| <a name="input_azure_project"></a> [azure\_project](#input\_azure\_project) | Azure devops project name | `string` | `null` | no |
| <a name="input_bitbucket_api_token"></a> [bitbucket\_api\_token](#input\_bitbucket\_api\_token) | Bitbucket API token used to authenticate against the Bitbucket API. | `string` | `null` | no |
| <a name="input_bitbucket_collaborators"></a> [bitbucket\_collaborators](#input\_bitbucket\_collaborators) | Collaborators to grant repository access to. Each entry has an id, a role and a type. | <pre>list(object({<br/> id = string<br/> role = string<br/> type = string<br/> }))</pre> | `[]` | no |
| <a name="input_bitbucket_email"></a> [bitbucket\_email](#input\_bitbucket\_email) | Email of the Bitbucket account used together with the API token for authentication. | `string` | `null` | no |
| <a name="input_bitbucket_flavor"></a> [bitbucket\_flavor](#input\_bitbucket\_flavor) | Bitbucket flavor. Only 'cloud' is supported at this time; the field exists so Data Center can be added later without reworking callers. | `string` | `"cloud"` | no |
| <a name="input_bitbucket_installation_url"></a> [bitbucket\_installation\_url](#input\_bitbucket\_installation\_url) | Base URL for the Bitbucket integration. Defaults to Bitbucket Cloud. | `string` | `"https://bitbucket.org"` | no |
| <a name="input_bitbucket_project_key"></a> [bitbucket\_project\_key](#input\_bitbucket\_project\_key) | Bitbucket project key under which repositories are created. | `string` | `null` | no |
| <a name="input_bitbucket_workspace"></a> [bitbucket\_workspace](#input\_bitbucket\_workspace) | Bitbucket workspace that owns the repositories. | `string` | `null` | no |
| <a name="input_dimensions"></a> [dimensions](#input\_dimensions) | Dimensions to segment the nullplatform provider config (e.g. by region, environment) | `map(string)` | `{}` | no |
| <a name="input_git_provider"></a> [git\_provider](#input\_git\_provider) | Git provider to use (GitHub or GitLab). | `string` | n/a | yes |
| <a name="input_git_provider"></a> [git\_provider](#input\_git\_provider) | Git provider to use (GitHub, GitLab, Azure DevOps or Bitbucket). | `string` | n/a | yes |
| <a name="input_github_installation_id"></a> [github\_installation\_id](#input\_github\_installation\_id) | GitHub App installation ID for the organization. | `string` | `null` | no |
| <a name="input_github_organization"></a> [github\_organization](#input\_github\_organization) | GitHub organization name for repository creation. | `string` | `null` | no |
| <a name="input_gitlab_access_token"></a> [gitlab\_access\_token](#input\_gitlab\_access\_token) | Access token for authenticating with the Git provider API. | `string` | `null` | no |
Expand Down
7 changes: 4 additions & 3 deletions nullplatform/code_repository/locals.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
locals {
is_gitlab = lower(var.git_provider) == "gitlab"
is_github = lower(var.git_provider) == "github"
is_azure = lower(var.git_provider) == "azure"
is_gitlab = lower(var.git_provider) == "gitlab"
is_github = lower(var.git_provider) == "github"
is_azure = lower(var.git_provider) == "azure"
is_bitbucket = lower(var.git_provider) == "bitbucket"
}
22 changes: 22 additions & 0 deletions nullplatform/code_repository/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,25 @@ resource "nullplatform_provider_config" "azure" {
}
)
}

/* If the git_provider variable has the value bitbucket, create this resource */
resource "nullplatform_provider_config" "bitbucket" {
count = local.is_bitbucket ? 1 : 0
nrn = replace(var.nrn, ":namespace=.*$", "")
type = "bitbucket-configuration"
dimensions = var.dimensions
attributes = jsonencode({
"setup" : {
"workspace" : var.bitbucket_workspace,
"project_key" : var.bitbucket_project_key,
"email" : var.bitbucket_email,
"api_token" : var.bitbucket_api_token,
"installation_url" : var.bitbucket_installation_url,
"flavor" : var.bitbucket_flavor
},
"access" : {
"collaborators" : var.bitbucket_collaborators
},
}
)
}
39 changes: 39 additions & 0 deletions nullplatform/code_repository/tests/code_repository.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,45 @@ run "gitlab_provider_config" {
}
}

run "bitbucket_provider_config" {
command = plan

variables {
git_provider = "bitbucket"
nrn = "organization=myorg:account=myaccount"
np_api_key = "test-api-key"
bitbucket_workspace = "myworkspace"
bitbucket_project_key = "MYPROJ"
bitbucket_email = "bot@example.com"
bitbucket_api_token = "atlassian-api-token"
}

assert {
condition = nullplatform_provider_config.bitbucket[0].type == "bitbucket-configuration"
error_message = "Bitbucket provider config type should be 'bitbucket-configuration'"
}

assert {
condition = strcontains(nullplatform_provider_config.bitbucket[0].attributes, "myworkspace")
error_message = "Attributes should contain the workspace"
}

assert {
condition = strcontains(nullplatform_provider_config.bitbucket[0].attributes, "MYPROJ")
error_message = "Attributes should contain the project key"
}

assert {
condition = strcontains(nullplatform_provider_config.bitbucket[0].attributes, "https://bitbucket.org")
error_message = "Attributes should default the installation URL to Bitbucket Cloud"
}

assert {
condition = length(nullplatform_provider_config.github) == 0 && length(nullplatform_provider_config.gitlab) == 0
error_message = "Only the Bitbucket provider should be created for bitbucket"
}
}

run "gitlab_strips_namespace_from_nrn" {
command = plan

Expand Down
70 changes: 67 additions & 3 deletions nullplatform/code_repository/variables.tf
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
variable "git_provider" {
description = "Git provider to use (GitHub or GitLab)."
description = "Git provider to use (GitHub, GitLab, Azure DevOps or Bitbucket)."
type = string
validation {
condition = contains(["github", "gitlab"], var.git_provider)
error_message = "git_provider must be either 'github' or 'gitlab'."
condition = contains(["github", "gitlab", "azure", "bitbucket"], var.git_provider)
error_message = "git_provider must be one of 'github', 'gitlab', 'azure' or 'bitbucket'."
}
}

Expand Down Expand Up @@ -111,6 +111,70 @@ variable "azure_agent_pool" {
}
}

# Bitbucket-specific variables
variable "bitbucket_workspace" {
description = "Bitbucket workspace that owns the repositories."
type = string
default = null
validation {
condition = var.git_provider != "bitbucket" || var.bitbucket_workspace != null
error_message = "bitbucket_workspace is required when git_provider is 'bitbucket'."
}
}

variable "bitbucket_project_key" {
description = "Bitbucket project key under which repositories are created."
type = string
default = null
validation {
condition = var.git_provider != "bitbucket" || var.bitbucket_project_key != null
error_message = "bitbucket_project_key is required when git_provider is 'bitbucket'."
}
}

variable "bitbucket_email" {
description = "Email of the Bitbucket account used together with the API token for authentication."
type = string
default = null
validation {
condition = var.git_provider != "bitbucket" || var.bitbucket_email != null
error_message = "bitbucket_email is required when git_provider is 'bitbucket'."
}
}

variable "bitbucket_api_token" {
description = "Bitbucket API token used to authenticate against the Bitbucket API."
type = string
sensitive = true
default = null
validation {
condition = var.git_provider != "bitbucket" || var.bitbucket_api_token != null
error_message = "bitbucket_api_token is required when git_provider is 'bitbucket'."
}
}

variable "bitbucket_installation_url" {
description = "Base URL for the Bitbucket integration. Defaults to Bitbucket Cloud."
type = string
default = "https://bitbucket.org"
}

variable "bitbucket_flavor" {
description = "Bitbucket flavor. Only 'cloud' is supported at this time; the field exists so Data Center can be added later without reworking callers."
type = string
default = "cloud"
}

variable "bitbucket_collaborators" {
description = "Collaborators to grant repository access to. Each entry has an id, a role and a type."
type = list(object({
id = string
role = string
type = string
}))
default = []
}


variable "nrn" {
description = "Nullplatform Resource Name (NRN) — unique identifier for resources."
Expand Down
Loading