diff --git a/README.md b/README.md index 93378dc..7c59935 100644 --- a/README.md +++ b/README.md @@ -1 +1,51 @@ -# terraform module \ No newline at end of file +## Requirements + +| Name | Version | +|------|---------| +| [gitlab](#requirement\_gitlab) | 18.0.0 | + +## Providers + +| Name | Version | +|------|---------| +| [gitlab](#provider\_gitlab) | 18.0.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [gitlab_group.group](https://registry.terraform.io/providers/gitlabhq/gitlab/18.0.0/docs/resources/group) | resource | +| [gitlab_group_badge.badge](https://registry.terraform.io/providers/gitlabhq/gitlab/18.0.0/docs/resources/group_badge) | resource | +| [gitlab_group_label.label](https://registry.terraform.io/providers/gitlabhq/gitlab/18.0.0/docs/resources/group_label) | resource | +| [gitlab_group_ldap_link.link_gitlab_group_with_ad_group](https://registry.terraform.io/providers/gitlabhq/gitlab/18.0.0/docs/resources/group_ldap_link) | resource | +| [gitlab_group_variable.variable](https://registry.terraform.io/providers/gitlabhq/gitlab/18.0.0/docs/resources/group_variable) | resource | +| [gitlab_group.parent](https://registry.terraform.io/providers/gitlabhq/gitlab/18.0.0/docs/data-sources/group) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [allowed\_avatar\_types\_json](#input\_allowed\_avatar\_types\_json) | Path to allowed avatar types json | `string` | `""` | no | +| [avatar](#input\_avatar) | Type of the icon for the group (default: from type) | `string` | `""` | no | +| [avatars\_dir](#input\_avatars\_dir) | Avatars directory png files | `string` | `""` | no | +| [badges](#input\_badges) | n/a |
map(object({
link_url = string
image_url = string
}))
| `{}` | no | +| [default\_branch](#input\_default\_branch) | The group's default branch | `string` | `"main"` | no | +| [description](#input\_description) | Description of the gitlab group | `string` | n/a | yes | +| [labels](#input\_labels) | n/a |
map(object({
description = string
color = string
}))
| `{}` | no | +| [name](#input\_name) | Name of the gitlab group | `string` | n/a | yes | +| [parent\_group](#input\_parent\_group) | Gitlab parent group | `string` | n/a | yes | +| [permissions](#input\_permissions) | Group permission mapping |
map(object({
permission = string
}))
| `{}` | no | +| [variables](#input\_variables) | n/a |
map(object({
value = string
description = optional(string)
protected = optional(bool)
masked = optional(bool)
environment_scope = optional(string)
}))
| `{}` | no | +| [visibility](#input\_visibility) | The group's visibility | `string` | `"private"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [full\_path](#output\_full\_path) | Full path in gitlab for created group | +| [group\_name](#output\_group\_name) | Name of created group | +| [id](#output\_id) | ID of created group | diff --git a/data.tf b/data.tf index 0ad8665..1935c05 100644 --- a/data.tf +++ b/data.tf @@ -1 +1,4 @@ -//Data +data "gitlab_group" "parent" { + count = var.parent_group != "" ? 1 : 0 + full_path = var.parent_group +} \ No newline at end of file diff --git a/data/allowed_icon_types.json b/data/allowed_icon_types.json new file mode 100644 index 0000000..a4cfbe0 --- /dev/null +++ b/data/allowed_icon_types.json @@ -0,0 +1,14 @@ +[ + "", + "ansible", + "archived", + "containers", + "devops", + "golang", + "gitlab", + "infrastructure", + "packer", + "python", + "terraform", + "typescript" +] \ No newline at end of file diff --git a/locals.tf b/locals.tf index 69083a6..b97be0a 100644 --- a/locals.tf +++ b/locals.tf @@ -1,3 +1,18 @@ -//Locals locals { + avatars_dir = var.avatars_dir == "" ? "${path.root}/images" : var.avatars_dir + + allowed_avatar_types_json = var.allowed_avatar_types_json == "" ? "${path.root}/data/allowed_avatar_group_types.json" : var.allowed_avatar_types_json + allowed_avatar_types = jsondecode(file("${local.allowed_avatar_types_json}")) + + # Define the allowed project types as a map + avatar = try(file("${local.avatars_dir}/${var.avatar}.png"), null) == null ? "${local.avatars_dir}/${var.avatar}.png" : null + + permissions_list = { + for key, var in var.permissions : key => merge( + { + group = key, + permission = var.permission + } + ) + } } diff --git a/main.tf b/main.tf index 882e72a..66ca79c 100644 --- a/main.tf +++ b/main.tf @@ -1 +1,51 @@ -//Main resources +resource "gitlab_group" "group" { + name = var.name + path = var.name + description = var.description + parent_id = var.parent_group != "" ? data.gitlab_group.parent[0].id : null + default_branch = var.default_branch + avatar = local.avatar == null ? null : "${local.avatar}" + avatar_hash = local.avatar == null ? null : filesha256("${local.avatar}") +} + +resource "gitlab_group_label" "label" { + for_each = var.labels + + group = gitlab_group.group.id + name = each.key + description = each.value.description + color = each.value.color +} + +resource "gitlab_group_badge" "badge" { + for_each = var.badges + + group = gitlab_group.group.id + name = each.key + link_url = each.value.link_url + image_url = each.value.image_url +} + +resource "gitlab_group_variable" "variable" { + for_each = var.variables + + group = gitlab_group.group.id + key = each.key + value = each.value.value + description = each.value.description + protected = each.value.protected + masked = each.value.masked + environment_scope = each.value.environment_scope +} + +resource "gitlab_group_ldap_link" "link_gitlab_group_with_ad_group" { + for_each = local.permissions_list + + group = gitlab_group.group.full_path + cn = each.value.group + group_access = each.value.permission + ldap_provider = "ldapmain" +} + + + diff --git a/output.tf b/output.tf index c608d5f..4a80a12 100644 --- a/output.tf +++ b/output.tf @@ -1,3 +1,14 @@ -output "example" { - //value = some_resource.example +output "full_path" { + description = "Full path in gitlab for created group" + value = gitlab_group.group.full_path +} + +output "id" { + description = "ID of created group" + value = gitlab_group.group.id +} + +output "group_name" { + description = "Name of created group" + value = gitlab_group.group.name } diff --git a/provider.tf b/provider.tf index f21e096..927c934 100644 --- a/provider.tf +++ b/provider.tf @@ -1,5 +1,8 @@ terraform { required_providers { - //Provider name + gitlab = { + source = "gitlabhq/gitlab" + version = "18.0.0" + } } } diff --git a/variable.tf b/variable.tf index f8598a8..6b30977 100644 --- a/variable.tf +++ b/variable.tf @@ -1,9 +1,105 @@ variable "name" { type = string - description = "name" + description = "Name of the gitlab group" } variable "description" { type = string - description = "description" + description = "Description of the gitlab group" +} + +variable "parent_group" { + type = string + description = "Gitlab parent group" +} + +variable "visibility" { + type = string + default = "private" + description = "The group's visibility" + + validation { + condition = contains([ + "private", + "internal", + "public" + ], var.visibility) + error_message = "Unsupported group visibility" + } +} + +variable "default_branch" { + type = string + default = "main" + description = "The group's default branch" +} + +variable "allowed_avatar_types_json" { + type = string + default = "" + description = "Path to allowed avatar types json" +} + + +variable "avatar" { + type = string + description = "Type of the icon for the group (default: from type)" + default = "" + + validation { + condition = contains(local.allowed_avatar_types, var.avatar) + error_message = "Unsupported group type" + } +} + +variable "labels" { + type = map(object({ + description = string + color = string + })) + default = {} +} + +variable "badges" { + type = map(object({ + link_url = string + image_url = string + })) + default = {} +} + +variable "variables" { + type = map(object({ + value = string + description = optional(string) + protected = optional(bool) + masked = optional(bool) + environment_scope = optional(string) + })) + default = {} +} + +variable "permissions" { + type = map(object({ + permission = string + })) + + validation { + condition = alltrue([for k, v in var.permissions : + v.permission == "owner" || + v.permission == "maintainer" || + v.permission == "developer" || + v.permission == "reporter" || + v.permission == "guest" + ]) + error_message = "Each permission must be one of the following values: owner, maintainer, developer, reporter, guest" + } + description = "Group permission mapping" + default = {} +} + +variable "avatars_dir" { + description = "Avatars directory png files" + type = string + default = "" }