我希望通过Terraform简化分配Google云平台的ID
想做的事情或构想
-
- 多人数にGCPを好き勝手検証できるような環境を提供したく、その際に必要なIDの払い出しのプロセスを自動化したい
- IaCに興味があったので、terraformを利用してGCPの組織を管理してみて、学びを得たい。
功能 can be paraphrased as “功能性” in Chinese.
-
- 管理者側および利用者側に馴染みのあるインターフェース(Microsoft365のサービス)を提供する(今回は未実装)
- Github actionsを利用してインフラ環境のデプロイを自動化する(今回記事にした内容)
总结
这是以中文原生方式改写后的句子:
条件。
-
- サービスアカウントの権限を借用してterraform経由で プロジェクト作成を実施するため、事前にサービスアカウントに組織レベルの権限を付与する必要あり。
-
- github actionsでサービスアカウントの権限を借用するにあたってアクセスキーを発行しておく必要あり。(OIDC認証を利用したほうがアクセスキーを管理する必要がないが、今回はキーを利用する)
- 企業向けのgithubを利用しているため、github actionsには承認されているものしか利用できない。
1. 在本地电脑上创建项目并将要使用的电子邮件帐户作为成员写入文件中。
2. 将编辑后的文件反映到GitHub上。
3. 触发该操作后,GitHub的虚拟机将启动并执行在GitHub工作流文件中记录的操作。
4. 在这一系列操作中,将安装Terraform,并参考源代码将其部署到GCP上。
这次我遇到的困境/注意事项
-
- 組織レベルの権限を付与する為のコンソール操作がわからず苦労した(結局gloud cli経由で実施、設定後に簡単にコンソール操作可能だったということに気づく。。)
- github actions上で意味がわからないエラーの解消に苦労したり、使用したアクション「google-github-actions/auth@v0」とその後のpush操作でアクセスキーをgithub上にpushしてしまったりした。
1. Terraform是什么?
-
- Infrastructure as a codeとよばれるソースコードを用いてインフラを構築・管理するサービスの一つ。似たようなものにansibleなどもある。
-
- terraformを利用すると、クラウドコンソールからポチポチ構築していく手順をソースコードとして管理できる。
-
- そのため、人手による設定ミスの減らしたり、手順の自動化、他システム構築時にアセットを再利用しやすいといわれている。
-
- 中身の処理的にはtfstateファイルでクラウドの状態が記述されており、ソースコードと状態ファイルの差分をSDKか何かを経由してデプロイしている?(想像)ため、terraformで管理している状態と現実のクラウド構成で差分が生じると、その差分を解消する必要がある。
- tfstateファイルはs3やGCSなどのクラウドストレージで管理することが一般的だが、一旦の試しでgithub上に保存している。
2. “What is GitHub Actions?” is paraphrased in Chinese as “GitHub Actions是什么?”
-
- githubにおけるワークフロー自動化サービスで、何かのイベントをトリガーに定めた作業をリモートの仮想マシンでやってくれる。
- 今回はソースコードを更新したあとに、terraformで「terraform plan」や[terraform apply」コマンドでクラウドをデプロイする作業を自動化したい。
3. 步骤
terraform {
#GCPをデプロイするためのプラグインを定義する
required_providers {
google = {
source = "hashicorp/google"
version = "4.51.0"
}
#一意なプロジェクト名で作成したいため、乱数のプラグインを定義する
random = {
source = "hashicorp/random"
version = "3.5.1"
}
}
}
#GCP用にリージョンを指定したプロバイダーを定義する
provider "google" {
region = "us-central1"
zone = "us-central1-c"
}
-
- 在以下中可以定义要部署的资源。
- 使用resource <资源类型> <本地定义名称>的区块定义要在GCP上部署的服务。
# フォルダ定義
resource "google_folder" "folder" {
#組織を指定
parent = "organizations/XXXXXXX"
#フォルダ名を指定
display_name = var.project_folder
}
# プロジェクト定義
resource "google_project" "project" {
#払い出したいIDの分だけloopするように
count = "${length(local.list_values)}"
name = "${element(element(local.list_values, count.index),0)}"
#一意なプロジェクト名のため、乱数を含めて定義
project_id = "${element(element(local.list_values, count.index),0)}-${random_integer.project_name[count.index].result}"
#どのフォルダの下にプロジェクトを作るかを定義
folder_id = google_folder.folder.id
}
# IAMバインド定義
resource "google_project_iam_binding" "project_iam_binding" {
count = "${length(local.list_values)}"
#どのプロジェクトのどのメンバーに権限を付与するかを記載
project = "${element(google_project.project, count.index).id}"
#付与したいロールを記載
role = "roles/editor"
members = [
"user:${element(element(local.list_values, count.index),1)}",
]
}
编写这些文件并执行下面一系列的命令,即可在GCP上部署资源。
然而,由于每次手动执行terraform都很麻烦,因此尝试使用GitHub Actions进行自动化。
$ terraform init
$ terraform plan
$ terraform apply
- 通过将一个yaml文件放置在./.github/workflows/目录下,可以实现对该yaml文件中所述的一系列命令的执行。
name: ci-tf-deploy
#githubにソースコードを反映させるのをトリガーにjobsに記載のコマンドを実施
on:
push:
branches: master
pull_request:
branches: master
#ここに一連のコマンドを記載
jobs:
terraform:
name: Terraform
runs-on: ubuntu-latest
steps:
#githubにあるソースコードを仮想マシン上にコピーするてきなやつ
- name: Checkout
uses: actions/checkout@v3
#nodeのバージョンを14にしないとエラーで失敗する。なぜ?
- uses: actions/setup-node@v2
with:
node-version: '14'
#githubに保存したgcpの認証鍵情報を参照してサービスアカウントの権限を借用する
- name: 'Authenticate to Google Cloud'
uses: 'google-github-actions/auth@v0'
with:
credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}'
#仮想マシン上でterraform環境構築する
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.0.4
#プロバイダー等インストールする
- name: Init Terraform
run: terraform init
- name: Plan Terraform
run: terraform plan
#GCPサービスをデプロイ
- name: Apply Terraform
run: terraform apply -auto-approve
#更新したtfstateをgithub上にpushする。ほんとはブランチ切ってプルリクするようにしたほうがよい
- name: setup git config
run: git config --global user.email '${{ secrets.MY_GITHUB_EMAIL}}'
- name: setup git config
run: git config --global user.name '${{ secrets.MY_GITHUB_NAME}}'
- name: Git add files to local branch
run: git add .
- name: Git commit
run: git commit -m "payout gcp-id and push updated tfstate to remote repos"
- name: push to Git repos
run: git push
env:
GITHUB_TOKEN: ${{ secrets.MY_GITHUB_TOKEN}}
在这里提一个余事1:
最好在.gitignore文件中添加忽略*cred*的设置。
原因是在github actions中执行’google-github-actions/auth@v0’操作时,会生成一个临时认证密钥文件,如果不在.gitignore中进行处理,可能会导致安全事件,即意外将其推送到github上。
→ 已经有其他人将此问题作为一个issue提出(参见链接https://github.com/google-github-actions/auth/issues/298)。