[HCP Terraform 実践 その6] HCP Terraform を Terraform テンプレート化してプロビジョニングした話

## これは何？
HCP Terraform のワークスペース等のリソースをTerraform でプロビジョニングするまでの内容になります。
以前、寄稿した[\[HCP Terraform 実践 その1\] Terraform Cloud 触ってみた](https://qiita.com/atw0_0w/items/6b55f671e1088cbc140e)をTerraform で作成する内容となります。

また、本記事で作成したテンプレートは以下に格納していますので、是非ご覧になっていただければ:pray:。

https://github.com/atsw0q0/terraform-tfe-templates


## HCP Terraform のテンプレートについて
プロバイダー「tfe」を使用して、HCP Terraform のワークスペースなどを作成することができます。

https://registry.terraform.io/browse/providers?category=hashicorp

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872532/a7c30fd1-cede-a613-cb31-42c8ba44463f.png)



HCP Terraform における各リソース部分についての解説は以下の通りです。

### Organizations
Organizationsは`tfe_organization`によって作成することができます。

```hcl:main.tf
resource "tfe_organization" "main" {
  name  = "org_name"
  email = var.org_manager_email
}
```

### Projects

Projectsは`tfe_project`によって作成することができます。

```hcl:main.tf
resource "tfe_project" "aws" {
  organization = tfe_organization.main.name
  name         = "pj-aws"
}
```

### Workspaces

Workspaceは`tfe_workspace`によって作成することができます。
今回はGitHubと連携しているため、`vcs_repo`を設定しmainブランチに対してプルリク/マージがあった場合、トリガーされます。
`github_app_installation_id`の値は、以下のリンクの通り、GitHubと連携するための、APIトークンを指定します。
https://developer.hashicorp.com/terraform/enterprise/users-teams-organizations/users#github-app-oauth-token

```hcl:main.tf
resource "tfe_workspace" "main" {
  name         = "workspace_name"
  organization = tfe_organization.main.name
  project_id   = tfe_project.aws.id
  vcs_repo {
    identifier                 = var.vcs_repository
    branch                     = "main"
    github_app_installation_id = var.github_app_installation_id

  }
}

resource "tfe_workspace_settings" "main" {
  workspace_id = tfe_workspace.main.id
}
```
また、ワークスペース環境変数なども`tfe_variable`で定義できます。

```hcl:main.tf
resource "tfe_variable" "env_tfc_aws_provider_auth" {
  key          = "TFC_AWS_PROVIDER_AUTH"
  value        = "true"
  category     = "env"
  workspace_id = tfe_workspace.main.id

  depends_on = [aws_iam_role.role, tfe_workspace.main]
}

resource "tfe_variable" "env_tfc_aws_run_role_arn" {
  key          = "TFC_AWS_RUN_ROLE_ARN"
  value        = aws_iam_role.role.arn
  category     = "env"
  workspace_id = tfe_workspace.main.id

  depends_on = [aws_iam_role.role, tfe_workspace.main]
}

```


### OIDCプロバイダー & IAMロール (AWSを使用する場合)
HCP Terraform がAWS環境にアクセスするためにはOIDCプロバイダーおよびIAMロールの作成が必要になります。
詳しくは[こちら](https://developer.hashicorp.com/terraform/cloud-docs/workspaces/dynamic-provider-credentials/aws-configuration)を参考に。

テンプレートは以下の通りです。
```hcl:iam.tf
data "aws_caller_identity" "current" {}

resource "aws_iam_openid_connect_provider" "terraform" {
  count = var.is_create_iam_oidc_provider ? 1 : 0
  url   = "https://app.terraform.io"
  client_id_list = [
    "aws.workload.identity",
  ]

  thumbprint_list = [
    "9e99a48a9960b14926bb7f3b02e22da2b0ab7280",
  ]
  tags = {
    PJ  = var.pj_tags.name
    Env = var.pj_tags.env
  }
}


resource "aws_iam_role" "role" {
  name = format("%s-%s-role-hcptfm", var.pj_tags.name, var.pj_tags.env)
  path = "/"
  assume_role_policy = templatefile(
    "./files/iam_trust_relationship.json",
    {
      account_id   = data.aws_caller_identity.current.account_id
      organization = tfe_organization.main.id
      project      = "*" # プロジェクトで制限可能
      workspace    = "*" # ワークスペースで制限可能
    }
  )
  max_session_duration = 3600
  managed_policy_arns = [
    "arn:aws:iam::aws:policy/AdministratorAccess"
  ]
  tags = {
    PJ  = var.pj_tags.name
    Env = var.pj_tags.env
  }
}

```
`aws_iam_openid_connect_provider`については、私の場合は事前に作成済みでしたのでVariablesで作成の制御をしています。

`9e99a48a9960b14926bb7f3b02e22da2b0ab7280`はOIDC プロバイダーで使用されているサムプリントになり、一意の値になります。
サムプリントを更新する必要が発生したら[こちら](https://repost.aws/ja/knowledge-center/eks-error-invalid-identity-token)で確認,更新したりします。

## 最後に
[こちら](https://github.com/atsw0q0/terraform-tfe-templates)のテンプレートですが
[JR中央線 Developers もくもく&LT会 #13](https://chuo.connpass.com/event/329385/) というイベントに参加して、2,3時間ほどで作成しました(テンプレート2.0h, 動作検証0.5h)。

非常に落ち着いた環境で集中して取り組めたので、集中して開発を進めたいなどの方は、こういったもくもく回に参加するのもありなんじゃないかと思います。


またデモもも含めてLT登壇したので是非見ていただければと思います。
<script async class="speakerdeck-embed" data-id="4a3197c0849b45a49b68d8634e919ac3" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>