1
0

More than 3 years have passed since last update.

Gitのサブモジュール機能とTerraformのモジュール機能で実現するCI/CDパイプラインの量産(Lambda編)

Last updated at Posted at 2020-07-23

はじめに

Terraformのモジュール機能は最初はありがたみを感じられなかったので使わなかったものの、CI/CDパイプラインをいろいろと量産するようになってくると、いちいち過去のtfファイルを流用しようとして「どれが最新だったっけ……」と悩むようになったので、そろそろリポジトリ管理をするべきなのでは、と考えていた。

そんな折、Gitのサブモジュール機能を知って「これってもしかして組み合わせれば「おれの考えた最強量産型CI/CDパイプラインができるのでは?」と思い、作ってみた。

全体構成

今回は以下のような構成だ。

terraform-mainmodule-lambdapipeline
├── .gitmodules
├── main.tf
└── modules
    ├── 01_variables.tf
    ├── 02_iam.tf
    ├── 03_s3.tf
    ├── 04_cloudwatchlogs.tf
    ├── 05_codepipeline.tf
    └── 06_cloudformation_parameter.json

modules配下を、以下のようにサブモジュールとして登録している。

[submodule "modules"]
        path = modules
        url = https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/terraform-submodule-lambdapipeline

サブモジュールの構成は、↑の通りではあるが、ちゃんと書くと以下のようになる。

terraform-submodule-lambdapipeline
├── 01_variables.tf
├── 02_iam.tf
├── 03_s3.tf
├── 04_cloudwatchlogs.tf
├── 05_codepipeline.tf
└── 06_cloudformation_parameter.json

ポイント

ポイントといっても、あまり大したことはない。

メインモジュール側には、以下のようにprovidermoduleの定義をしている。
量産するときに変更したい項目を、moduleの引数として定義しているくらいだ。

main.tf
######################################################################
# Provider                                                           #
######################################################################
provider "aws" {
  region = "ap-northeast-1"
}

######################################################################
# Variables                                                          #
######################################################################
variable "prefix" {
  default = "LambdaPipeline"
}

######################################################################
# Module                                                             #
######################################################################
module "lambda_pipeline" {
  source = "./modules"

  ####################################################################
  # IAM                                                              #
  ####################################################################
  codebuild_role_name      = "${var.prefix}-CodeBuildRole"
  codepipeline_role_name   = "${var.prefix}-CodePipelineRole"
  cloudformation_role_name = "${var.prefix}-CloudFormationRole"

  ####################################################################
  # S3 Bucket for CodePipeline Artifact                              #
  ####################################################################
  bucket_name = lower("${var.prefix}-artifact-bucket")

  ####################################################################
  # CloudWatch Logs                                                  #
  ####################################################################
  codebuild_logstream_name = "${var.prefix}-CodeBuildLogStream"

  ####################################################################
  # CodeCommit                                                       #
  ####################################################################
  repository_name = lower("${var.prefix}")

  ####################################################################
  # CodeBuild                                                        #
  ####################################################################
  buildspec_file_name = "buildspec.yml"
  build_project_name = "${var.prefix}-BuildProject"

  ####################################################################
  # CodePipeline                                                     #
  ####################################################################
  pipeline_name = "${var.prefix}-Pipeline"

  ####################################################################
  # SAM                                                              #
  ####################################################################
  stack_name                           = "${var.prefix}-SAMStack"
  cf_param_lambda_function_name        = "${var.prefix}-Function"
  cf_param_lambda_execution_role_name  = "${var.prefix}-LambdaExecutionRole"
}

また、moduleで使う変数は、サブモジュール側でも変数宣言しておく必要があるため、01_variables.tfは以下のように書いておく。区分をmain.tfと合わせておくと分かりやすいだろう。

01_variables.tf
######################################################################
# IAM                                                                #
######################################################################
variable "codebuild_role_name"      {}
variable "codepipeline_role_name"   {}
variable "cloudformation_role_name" {}

######################################################################
# S3 Bucket for CodePipeline Artifact                                #
######################################################################
variable "bucket_name" {}

######################################################################
# CloudWatch Logs                                                    #
######################################################################
variable "codebuild_logstream_name" {}

######################################################################
# CodeCommit                                                         #
######################################################################
variable "repository_name" {}

######################################################################
# CodeBuild                                                          #
######################################################################
variable "buildspec_file_name" {}
variable "build_project_name"  {}

######################################################################
# CodePipeline                                                       #
######################################################################
variable "pipeline_name" {}

######################################################################
# SAM                                                                #
######################################################################
variable "stack_name"                          {}
variable "cf_param_lambda_function_name"       {}
variable "cf_param_lambda_execution_role_name" {}

パイプラインの内容

ここはこれまでも何度か書いてきたパイプラインなので、あまり改めて語るところはない。
過去の記事とほぼ変わらない内容である。
「ほぼ」と書いたのは、過去の記事では変数をlocalsで作っていたが、今回はモジュール化している都合上variablesにする必要があるため、すべて${local.hogehoge}という記述から${var.hogehoge}に変更したくらいだ。

作ったモジュールのメンテナンスについて

さて、これでパイプラインはモジュール化できて好きなように量産可能になったが、パイプライン単位にカスタマイズ要素が発生したらどうしたら良いのだろう?

サブモジュール側に、パイプラインの特性に合わせた条件分岐やマップを追加していくと、このサブモジュール自体がモノリシックに育っていってしまう可能性があるだろう。
しかし、だからといってカスタマイズする都度、サブモジュールからdetachして個別のモジュールとしてメイン側に取り込んでいってしまうと、今後このサブモジュールをバージョンアップするときに対象から外れてしまう。
AWSでモノを作る以上、ずっと同じ型を使い続けるというのはナンセンスだろう。

モジュール化のプラクティスは理解できたが、これをどうやって見通し良くメンテナンスしていくかは答えがでていない……。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0