Infrastructure as CodeのためのGitLabとTerraformの使い方:デモ
このデモでは、Terraformの自動化のために、そしてGitLabを信頼できる唯一の情報源として使い、Infrastructure as Codeをデプロイするための優れたGitOps手順をご紹介します。
複数のチームがすべてのインフラストラクチャとアプリケーションのデプロイコードのために、信頼できる唯一の情報源としてGitリポジトリーを使用している場合、それらのチームは優れたGitOps手順を実行していることになります。インフラストラクチャチームは、Terraformを使って自動化することで、複数のクラウドサービスに共同でコードをデプロイすることができます。この記事では、チームがGitLab内でチームメンバーと協力してKubernetesクラスターを作成する方法を紹介します。
はじめに
このGitOps-Demoグループには、インフラストラクチャチームが実行できる手順を紹介しています。
まず、GitLab内のプロジェクトが存在するグループにログインします。次にREADME.mdファイルを開き、GitOps-Demoグループの基本構造を確認します。いくつかの個別のプロジェクトと、infrastructure(インフラストラクチャ)とapplications(アプリケーション)という2つのサブグループがあります。
Azure、GCP、AWSの各クラウドの個別のリポジトリと、テンプレート用のリポジトリがあります。
同様のファイルは、3つのクラウドリポジトリのすべてに存在します。すべてのファイルはTerraformで書かれており、デプロイプロセスを自動化します。また、gitlab-ci.ymlファイルもリポジトリに保存されており、自動化のための指示を提供します。
バックエンドファイル
HashiCorpのTerraform Cloud Serviceをステートファイルのリモートロケーションとして使用することで、ステートファイルを安全に、かつどのプロセスからでもアクセスできるよう一元管理できます。Terraform Cloudを使用する利点の1つに一度に1つのジョブしか実行できないように状態をロックする機能があり、複数のジョブが競合する変更を行うことを防ぎます。このコードはTerraform Cloudのawsというワークスペース内のgitops-demo
という組織にstateファイルを保存します。 これにより、実行中の状態がクラウドプロバイダーに保持され、チームメンバーであればいつでもアクセスできるようになります。
terraform {
backend "remote" {
hostname = "app.terraform.io"
organization = "gitops-demo"
workspaces {
name = "aws"
}
}
}
EKS.tf file
EKSは、Terraformクラスター用のEKSモジュールを利用する別のTerraformファイルです。 チームは、EKS terraformファイルにサブネットのタイプやノード数などのパラメータを定義することができます。
module "eks" {
source = "terraform-aws-modules/eks/aws"
cluster_name = "gitops-demo-eks"
subnets = "${module.vpc.public_subnets}"
write_kubeconfig = "false"
tags = {
Terraform = "true"
Environment = "dev"
}
vpc_id = "${module.vpc.vpc_id}"
worker_groups = [
{
instance_type = "m4.large"
asg_max_size = 5
tags = [{
key = "Terraform"
value = "true"
propagate_at_launch = true
}]
}
]
}
GitLab管理者の定義
Kubernetesプロバイダーを使って、GitLab管理者ユーザーを作成し、自動的にコードとしてTerraformによって管理されるように設定することが可能です。
クラスターをGitLabに登録する
Kubernetesクラスターが作成できたので、今後さらに多くのコードをクラスターにデプロイできるように、GitLabに登録しましょう。まず最初に、GitLabプロバイダーを使って「AWS cluster」という名前のグループクラスターを作成します。
data "gitlab_group" "gitops-demo-apps" {
full_path = "gitops-demo/apps"
}
provider "gitlab" {
alias = "use-pre-release-plugin"
version = "v2.99.0"
}
resource "gitlab_group_cluster" "aws_cluster" {
provider = "gitlab.use-pre-release-plugin"
group = "${data.gitlab_group.gitops-demo-apps.id}"
name = "${module.eks.cluster_id}"
domain = "eks.gitops-demo.com"
environment_scope = "eks/*"
kubernetes_api_url = "${module.eks.cluster_endpoint}"
kubernetes_token = "${data.kubernetes_secret.gitlab-admin-token.data.token}"
kubernetes_ca_cert = "${trimspace(base64decode(module.eks.cluster_certificate_authority_data))}"
}
このコードには、ドメイン名、環境スコープ、Kubernetes認証情報が含まれています。
これが実行されると、AWSにクラスターが作成され、自動的にgitops-demo/appsグループに登録されます。
Terraformテンプレート
インフラストラクチャグループに戻り、テンプレートフォルダーを開きます。terraform.gitlab-ci.ymlファイルを見ると、CIがどのようにTerraformを使ってインフラストラクチャのコードをクラウドにデプロイするかを確認することができます。CIファイルの中では、validate、plan、apply、destroyといういくつかのステージを確認することができます。HashicorpのTerraformベースイメージを使用して、ユーザーはさまざまなタスクを実行できます。
最初のステップは、Terraformを初期化することです。
before_script:
- terraform --version
- terraform init
- apk add --update curl
- curl -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.13.7/2019-06-11/bin/linux/amd64/kubectl
- install kubectl /usr/local/bin/ && rm kubectl
- curl -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.13.7/2019-06-11/bin/linux/amd64/aws-iam-authenticator
- install aws-iam-authenticator /usr/local/bin/ && rm aws-iam-authenticator
次のステップですべてが正しいことを検証します。
validate:
stage: validate
script:
- terraform validate
- terraform fmt -check=true
only:
- branches
GitOpsのワークフローがうまく機能するためには、変更のマージリクエストを作成することが重要です。
merge review:
stage: plan
script:
- terraform plan -out=$PLAN
- echo \`\`\`diff > plan.txt
- terraform show -no-color ${PLAN} | tee -a plan.txt
- echo \`\`\` >> plan.txt
- sed -i -e 's/ +/+/g' plan.txt
- sed -i -e 's/ ~/~/g' plan.txt
- sed -i -e 's/ -/-/g' plan.txt
- MESSAGE=$(cat plan.txt)
- >-
curl -X POST -g -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}"
--data-urlencode "body=${MESSAGE}"
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/discussions"
artifacts:
name: plan
paths:
- $PLAN
only:
- merge_requests
マージリクエスト
マージリクエスト(MR)は、GitOpsで最も重要なステップです。ここですべての変更をレビューし、変更の影響を確認します。また、MRはコラボレーションツールでもあり、最終的にmainブランチにマージする前に、チームメンバーが変更点について議論したりステークホルダーが変更点を承認したりできる場所でもあります。
マージリクエストは、Infrastructure as Codeを実行するときに何が起こるかを定義します。MRが作成された後、TerraformプランがMRにアップロードされます。すべての変更がレビューおよび承認された後、コードをmainブランチにマージできます。コードの変更がマージされると、すべての変更が本番環境にデプロイされます。