diff --git a/.terraform-version b/.terraform-version new file mode 100644 index 0000000..8decb92 --- /dev/null +++ b/.terraform-version @@ -0,0 +1 @@ +1.8.5 diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index 0be7c85..d3f733d 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -4,6 +4,7 @@ provider "registry.terraform.io/hashicorp/local" { version = "2.5.1" hashes = [ + "h1:/GAVA/xheGQcbOZEq0qxANOg+KVLCA7Wv8qluxhTjhU=", "h1:tjcGlQAFA0kmQ4vKkIPPUC4it1UYxLbg4YvHOWRAJHA=", "zh:0af29ce2b7b5712319bf6424cb58d13b852bf9a777011a545fac99c7fdcdf561", "zh:126063ea0d79dad1f68fa4e4d556793c0108ce278034f101d1dbbb2463924561", @@ -25,6 +26,7 @@ provider "registry.terraform.io/integrations/github" { constraints = "~> 6.0" hashes = [ "h1:rY+q+OhJm90R900HvO05YNH7Tl0EOnbCLAoG+5niLX8=", + "h1:uDerb9YJo3vAO+wKw+Z064InX5aXom+nKLDry2eGf14=", "zh:172aa5141c525174f38504a0d2e69d0d16c0a0b941191b7170fe6ae4d7282e30", "zh:1a098b731fa658c808b591d030cc17cc7dfca1bf001c3c32e596f8c1bf980e9f", "zh:245d6a1c7e632d8ae4bdd2da2516610c50051e81505cf420a140aa5fa076ea90", diff --git a/github.tf b/github.tf deleted file mode 100644 index 406f0f2..0000000 --- a/github.tf +++ /dev/null @@ -1,180 +0,0 @@ -terraform { - required_providers { - github = { - source = "integrations/github" - version = "~> 6.0" - } - } -} -variable "github_token" { - type = string - description = "GitHub token" -} -variable "discord_webhook_url" { - description = "The Discord webhook URL to send notifications" - type = string -} - -# Configure the GitHub Provider -provider "github" { - token = var.github_token - owner = "DevKor-github" -} - -data "local_file" "users" { - filename = "${path.module}/users.json" -} - -data "local_file" "teams" { - filename = "${path.module}/teams.json" -} - -data "local_file" "repos" { - filename = "${path.module}/repos.json" -} - -data "local_file" "repo_permissions" { - filename = "${path.module}/repo_permissions.json" -} - -locals { - users = jsondecode(data.local_file.users.content) - teams = jsondecode(data.local_file.teams.content) - repos = jsondecode(data.local_file.repos.content) - repo_permissions = jsondecode(data.local_file.repo_permissions.content) -} - - - -resource "github_organization_settings" "org_settings" { - billing_email = "devkor.apply@gmail.com" - company = "DevKor" - blog = "https://devkor.club" - email = "devkor.apply@gmail.com" - location = "Seoul, Korea" - name = "DevKor" - description = "고려대학교 SW 프로덕트 학회 DevKor Github Organization" - has_organization_projects = true - has_repository_projects = true - members_can_create_repositories = false - members_can_create_private_pages = false - - advanced_security_enabled_for_new_repositories = true - dependabot_alerts_enabled_for_new_repositories = true - dependabot_security_updates_enabled_for_new_repositories = true - dependency_graph_enabled_for_new_repositories = true - secret_scanning_enabled_for_new_repositories = true - secret_scanning_push_protection_enabled_for_new_repositories = true -} - - -# user 초대 -resource "github_membership" "user" { - for_each = { for user in local.users : user.user => user } - - username = each.value.user - role = each.value.role -} - -# team 생성 -resource "github_team" "team" { - for_each = { for team in local.teams : team.name => team } - - name = each.key - description = "DevKor ${each.key} team" - privacy = "closed" -} - -# 팀별 2 repositories 생성 -resource "github_repository" "repo" { - for_each = { for repo in local.repos : repo.name => repo } - - - name = each.key - description = "DevKor ${each.key} repository" - visibility = "public" - has_projects = true - has_wiki = true - has_downloads = true - has_issues = true - has_discussions = true - - topics = ["devkor"] - license_template = "MIT" - - archive_on_destroy = true - vulnerability_alerts = true - - security_and_analysis { - secret_scanning { - status = "enabled" - } - secret_scanning_push_protection { - status = "enabled" - } - } - -} -# team - repo permission -resource "github_team_repository" "team_repos" { - for_each = { for permission in local.repo_permissions : "${permission.team}:${permission.repo}" => permission } - team_id = github_team.team[each.value.team].id - repository = each.value.repo - permission = each.value.permission -} - - -resource "github_branch" "main" { - for_each = { for repo in local.repos : repo.name => repo } - - repository = each.value.name - branch = "main" -} - -resource "github_branch_default" "default"{ - for_each = { for repo in local.repos : repo.name => repo } - - repository = each.value.name - branch = "main" -} - -# main branch must have Reviews -resource "github_repository_ruleset" "review_ruleset" { - name = "require_reviews" - target = "branch" - for_each = { for repo in local.repos : repo.name => repo } - - repository = each.value.name - enforcement = "active" - - conditions { - ref_name { - include = [ "~DEFAULT_BRANCH"] - exclude = [] - } - } - - rules { - pull_request { - required_approving_review_count = 1 - require_last_push_approval = true - } - - } -} - - -# PR -> discord webhook -resource "github_repository_webhook" "discord_pr_webhook" { - for_each = { for repo in local.repos : repo.name => repo } - - repository = each.value.name - - configuration { - url = var.discord_webhook_url - content_type = "json" - insecure_ssl = false - } - - events = ["pull_request", "pull_request_review", "pull_request_review_comment"] -} \ No newline at end of file diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..991ab59 --- /dev/null +++ b/main.tf @@ -0,0 +1,140 @@ +terraform { + required_providers { + github = { + source = "integrations/github" + version = "~> 6.0" + } + } +} + +# Configure the GitHub Provider +provider "github" { + token = var.github_token + owner = "DevKor-github" +} + +locals { + members = setsubtract(flatten(var.teams[*].users), var.admins) + repos = flatten(var.teams[*].repos) + repo_team_mapping = flatten( + [ + for team in var.teams : + [for repo in team.repos : { key : repo, value : team.name }] + ] + ) + repo_discord_webhook_url_mapping = flatten( + [ + for team in var.teams : + [for repo in team.repos : { key : "${team.name}_${repo}", value : { repo : repo, webhook : team.discord_webhook_url } }] + ] + ) +} + +resource "github_membership" "members" { + for_each = { for member in local.members : member => {} } + + username = each.key + role = "member" +} + +resource "github_team" "teams" { + for_each = { for team in var.teams : team.name => {} } + + name = each.key + description = "DevKor ${each.key} team" + privacy = "closed" +} + +resource "github_repository" "repo" { + for_each = { for repo in local.repos : repo => {} } + + + name = each.key + description = "DevKor ${each.key} repository" + visibility = "public" + has_projects = true + has_wiki = true + has_downloads = true + has_issues = true + has_discussions = true + + topics = ["devkor"] + license_template = "MIT" + + archive_on_destroy = true + vulnerability_alerts = true + + security_and_analysis { + secret_scanning { + status = "enabled" + } + secret_scanning_push_protection { + status = "enabled" + } + } + +} +# team - repo permission +resource "github_team_repository" "team_repos" { + for_each = { for mapping in local.repo_team_mapping : mapping.key => mapping.value } + team_id = github_team.teams[each.value].id + repository = github_repository.repo[each.key].name + permission = "admin" +} + + +resource "github_branch" "main" { + for_each = { for repo in local.repos : repo => {} } + + repository = github_repository.repo[each.key].name + branch = "main" +} + +resource "github_branch_default" "default" { + for_each = { for repo in local.repos : repo => {} } + + repository = github_repository.repo[each.key].name + branch = "main" +} + +# main branch must have Reviews +resource "github_repository_ruleset" "review_ruleset" { + for_each = { for repo in local.repos : repo => {} } + + name = "require_reviews" + target = "branch" + + repository = github_repository.repo[each.key].name + enforcement = "active" + + conditions { + ref_name { + include = ["~DEFAULT_BRANCH"] + exclude = [] + } + } + + rules { + pull_request { + required_approving_review_count = 1 + require_last_push_approval = true + } + + } +} + + +# PR -> discord webhook +resource "github_repository_webhook" "discord_pr_webhook" { + for_each = { for mapping in local.repo_discord_webhook_url_mapping : mapping.key => mapping.value } + + repository = github_repository.repo[each.value.repo].name + + configuration { + url = each.value.webhook + content_type = "json" + insecure_ssl = false + } + + events = ["pull_request", "pull_request_review", "pull_request_review_comment"] +} diff --git a/org.tf b/org.tf new file mode 100644 index 0000000..6e72733 --- /dev/null +++ b/org.tf @@ -0,0 +1,27 @@ +resource "github_organization_settings" "org_settings" { + billing_email = "devkor.apply@gmail.com" + company = "DevKor" + blog = "https://devkor.club" + email = "devkor.apply@gmail.com" + location = "Seoul, Korea" + name = "DevKor" + description = "고려대학교 SW 프로덕트 학회 DevKor Github Organization" + has_organization_projects = true + has_repository_projects = true + members_can_create_repositories = false + members_can_create_private_pages = false + + advanced_security_enabled_for_new_repositories = true + dependabot_alerts_enabled_for_new_repositories = true + dependabot_security_updates_enabled_for_new_repositories = true + dependency_graph_enabled_for_new_repositories = true + secret_scanning_enabled_for_new_repositories = true + secret_scanning_push_protection_enabled_for_new_repositories = true +} + +resource "github_membership" "admins" { + for_each = { for admin in var.admins : admin => {} } + + username = each.key + role = "admin" +} diff --git a/repo_permissions.json b/repo_permissions.json deleted file mode 100644 index 6c6a2dc..0000000 --- a/repo_permissions.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "repo": "kudog-frontend", - "team": "kudog", - "permission": "admin" - }, - { - "repo": "kudog-backend", - "team": "kudog", - "permission": "admin" - } -] diff --git a/repos.json b/repos.json deleted file mode 100644 index a5e898b..0000000 --- a/repos.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "name": "kudog-backend" - }, - { - "name": "kudog-frontend" - } -] diff --git a/teams.json b/teams.json deleted file mode 100644 index 75b695b..0000000 --- a/teams.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "name": "kudog" - }, - { - "name": "kukey" - } -] diff --git a/terraform.tfvars b/terraform.tfvars new file mode 100644 index 0000000..b84d73a --- /dev/null +++ b/terraform.tfvars @@ -0,0 +1,18 @@ +teams = [ + { + name = "kudog" + users = [ + "overthestream", + "overthestream2", + ] + repos = [ + "kudog-frontend", + "kudog-backend", + ] + discord_webhook_url = "https://example.com" + } +] + +admins = [ + "overthestream", +] diff --git a/users.json b/users.json deleted file mode 100644 index 1a708ab..0000000 --- a/users.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "user": "overthestream", - "role": "admin", - "team": "kudog" - }, - { - "user": "overthestream2", - "role": "admin", - "team": "kudog" - } -] diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..18f0eca --- /dev/null +++ b/variables.tf @@ -0,0 +1,18 @@ +variable "github_token" { + type = string + description = "GitHub token" + sensitive = true +} + +variable "teams" { + type = list(object({ + name = string + users = list(string) + repos = list(string) + discord_webhook_url = string + })) +} + +variable "admins" { + type = list(string) +}