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     = ""
 }