考虑到需要手动添加变量,如何使 Terraform 自动化?

How does one automate Terraform considering one needs to add to variables manually?

我正在处理的一个用例使用 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 没有像 [=30] 那样手动添加到变量 github_team_memberships =] 和 username_2 是 TF 会尝试删除 username_3 并添加 username_4.

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

Terraform 是一种声明性语言,可将静态对象持久保存到某个状态。

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

目前,这里有一些解决此问题的解决方案:

缩小 Terraform 范围

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

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

自动生成 Terraform 代码

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

这样做的优点是对于简单的用例,可以用一个小脚本实现速赢策略。

使用 Terraform CDK

虽然它还很年轻并且没有作为生产就绪工具销售(就像 Terraform 在达到 1.0 之前已经存在了很长时间),但从长远来看,Terraform CDK 可能是这个需求的最佳答案。

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