0

我正在处理的一个用例使用 Jira 来收集有关用户的信息,即:用户名和必须将用户添加到的 github 团队

然后启动 Terraform 脚本以将该用户添加到指定的 GitHub 团队。虽然这可以按预期工作,但因为我使用的是通过一组用户及其角色的单个资源声明,如下所示:

###
# Resource to define each user's membership in the org
###
resource "github_membership" "github_member" {
  for_each = var.github_memberships
  username = each.value.username
  role     = each.value.role
}


###
# Resource to define each team in the org
###
resource "github_team" "team" {
  for_each = toset(var.github_teams)
  name     = each.value

  lifecycle {
    ignore_changes = [description, privacy]
  }
}


###
# Resource to define a user's membership in a team
###
resource "github_team_membership" "team_membership" {
  for_each = [some unique value i create using locals]
  team_id  = github_team.team[each.value["team_name"]].id
  username = github_membership.github_member[each.value["username"]].username
  role     = each.value["role"]
}

我需要维护一个变量列表,如下所示:

##
# Membership here refers to simply belonging to GitHub as part of org, not any team
###
variable "github_memberships" {
  type = map(object({username: string, role: string}))
  default = {
    "username_1" = {
      username = "username_1",
      role     = "member"
    },
    "username_2" = {
      username = "username_2",
      role     = "member"
    },
    "username_3" = {
      username = "username_3",
      role     = "member"
    },
    "username_4" = {
      username = "username_4",
      role     = "member"
    }
  }
}

###
# List of teams in the org
###
variable "github_teams" {
  type    = list(string)
  default = ["test_team"]
}

variable "github_team_memberships" {
  type = map(object({members: list(object({username: string, role: string}))}))
  default = {
    "test_team" = {
      members = [{username = "username_1", role = "maintainer"}, {username = "username_2", role = "member"}]
    }
  }
}

现在如果要向 test_team 添加一个新用户:

module "GitHubAccessRequest" {
  source = "./child_modules/GitHub_Team_Assigner_Child"
  requested_username = "username_3"
  requested_teams    = ["test_team"]
  requested_role     = "member"
}

TF 会添加 username_3,但是下次我们使用 username_4 时,由于 username_3 没有像 username_1 和 username_2 一样手动添加到变量 github_team_memberships 中,TF 会尝试删除 username_3 并添加 username_4。

这是否意味着没有办法自动化这个过程?每次提交工单并运行 TF 时,开发人员需要手动更新此变量 github_team_memberships 以保持跟踪?这对于小型团队来说可能是可行的,但对于大型组织来说可能会变得非常麻烦。

4

1 回答 1

1

Terraform 是一种将静态对象持久化为状态的声明性语言。

因此,它并不真正适合想要一次性申请以创建新资源的用例。代码必须始终反映 Terraform 管理的内容。

目前,这里有一些解决方案来解决这个问题:

缩小 Terraform 范围

仅将 Terraform 用于静态资源(仅以 GitHub Teams 为例)。所有动态的(团队成员)都通过一个小工具直接使用 GitHub API 进行管理。创建工单后,该工具会以编程方式启动,以添加或删除团队成员。

它具有自动化流程的优势,同时删除了 Terraform 作为工单创建和团队成员分配之间的中间工具。

自动生成 Terraform 代码

编写一个工具,根据票证的要求更新 Terraform 代码,然后运行 ​​Terraform 代码。

这样做的好处是,对于一个简单的用例,它可以通过一个小脚本以快速获胜的策略来实现。

使用 Terraform CDK

尽管它还很年轻,并且没有作为生产就绪工具进行销售(就像 Terraform 在达到 1.0 之前很长一段时间),但从长远来看,Terraform CDK可能是最好的解决方案。

长话短说(套用他们的自述文件),它允许人们以编程方式定义 Terraform 构造,而无需自己编写 Terraform 文件。将其视为 Terraform 文件的 SDK。

于 2021-11-18T05:12:44.860 回答