Topics Gitops Infrastructure as CodeのためのGitLabとTerraformの使い方:デモ

Infrastructure as CodeのためのGitLabとTerraformの使い方:デモ


このデモでは、Terraformの自動化のために、そしてGitLabを信頼できる唯一の情報源として使い、Infrastructure as Codeをデプロイするための優れたGitOps手順をご紹介します。

複数のチームがすべてのインフラストラクチャとアプリケーションのデプロイコードのために、信頼できる唯一の情報源としてGitリポジトリーを使用している場合、それらのチームは優れたGitOps手順を実行していることになります。インフラストラクチャチームは、Terraformを使って自動化することで、複数のクラウドサービスに共同でコードをデプロイすることができます。この記事では、チームがGitLab内でチームメンバーと協力してKubernetesクラスターを作成する方法を紹介します。

GitLabでInfrastructure as Codeを有効にする方法を学ぶ

このデモでは、Terraformを用いて自動化し、GitLabを信頼できる唯一の情報源(および CI)として使用してInfrastructure as Codeをデプロイするための効果的なGitOpsの利用方法をご紹介します。

GitLabでInfrastructure as Codeを構築する

はじめに

この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グループに登録されます。

GitLab CIを使ってコードをデプロイする

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ブランチにマージできます。コードの変更がマージされると、すべての変更が本番環境にデプロイされます。

GitOpsとは

実際に体感してみませんか?

統合されたDevSecOpsプラットフォームによってチームで実現できることをご確認ください。