Movatterモバイル変換


[0]ホーム

URL:


Skip to content
Menu
Shikoan's ML Blog
機械学習やディープラーニング、アルゴリズムについて書きます
AWS > AWSのCodePipelineでCI/CDを試す
   こしあん
2024-12-14

AWSのCodePipelineでCI/CDを試す

Posted On 2024-12-14
こしあん


402{icon} {views}


GitHubのメインブランチへのプッシュをトリガーとして、Terraformを使用してS3バケットにソースコードを自動的にコピーするAWS CodePipelineを構築しました。Code ConnectionsとCodeStar Connectionsの違いに伴うハマりどころや、GitHubとの連携設定の手順、さらに個人での利用を考慮したCodePipelineとGitHub Actionsの比較について解説します。

はじめに

  • DVAの勉強してたら、AWSのCI/CDができるCodePipelineがやたら出てきたので触ってみた。最初の連携のところが結構ハマる部分が多かった。
  • 作るものは、GitHubへのメインブランチへのPushをトリガーとしてS3バケットにソースコードをコピーするだけのもの。
  • AWSのソース管理サービスにCode Commitがあるが、2024/12現在新規受付を停止しているので、GitHubとの連携で考える
  • GitHubの連携は、Code Connectionsで行い、GitHub上にアプリをデプロイする

注意点

  • Code Connectionsと似たものにCodeStar Connectionsがあるが、こちらではGitHubでは現在連携できないので注意。Terraformのリソース名が異なる。
    • 正:aws_codeconnections_connection
    • 誤:aws_codestarconnections_connection
  • GPTだと古いもの(CodeStar)を出してきてかなりハマったので、要注意

事前準備

GitHub非公開リポジトリを作る。sample-private-repositoryとして、デフォルトブランチはmasterとしてみた。

Terraformのコード

Code PipelineやCode ConnectionsはTerraformでサクッとデプロイする。

※IAMポリシーはガバガバなので、頑張りたければ絞って

variable.tf

# 変数定義variable "github_owner" {  description = "GitHubのオーナー名または組織名"  type        = string  default     = "koshian2"}variable "github_repo" {  description = "GitHubリポジトリ名"  type        = string  default     = "sample-private-repository"}variable "github_branch" {  description = "デプロイに使用するGitHubのブランチ"  type        = string  default     = "master"}variable "s3_bucket_name" {  description = "デプロイ先のS3バケット名"  type        = string  default     = "codepipeline-deploy-destination-bucket"}variable "connection_name" {  description = "Code Connectionsの名前"  type        = string  default     = "MyGitHubConnection"}

main.tf

これでvar.github_repovar.github_branchにPushが入ったときに、指定したバケットに自動的に転送されるようになるが、GitHubとの連携にマネジメントコンソールから初期設定が必要。それを次以降に説明する。

# main.tf# S3バケットの作成resource "aws_s3_bucket" "deploy_bucket" {  bucket        = var.s3_bucket_name  force_destroy = true}# Code Connectionsの作成resource "aws_codeconnections_connection" "github_connection" {  name          = var.connection_name  provider_type = "GitHub"}resource "aws_s3_bucket_versioning" "versioning_deploy" {  bucket = aws_s3_bucket.deploy_bucket.id  versioning_configuration {    status = "Enabled"  }}# IAMロールの作成resource "aws_iam_role" "codepipeline_role" {  name = "codepipeline_service_role"  assume_role_policy = jsonencode({    Version = "2012-10-17",    Statement = [{      Effect = "Allow",      Principal = {        Service = "codepipeline.amazonaws.com"      },      Action = "sts:AssumeRole"    }]  })}# IAMポリシーの作成resource "aws_iam_policy" "codepipeline_policy" {  name        = "codepipeline_policy"  description = "Policy for CodePipeline to access S3 and CodeStar Connections"  policy = jsonencode({    Version = "2012-10-17",    Statement = [      # S3へのアクセス許可      {        Effect = "Allow",        Action = [          "s3:GetObject",          "s3:PutObject",          "s3:ListBucket"        ],        Resource = [          aws_s3_bucket.deploy_bucket.arn,          "${aws_s3_bucket.deploy_bucket.arn}/*"        ]      },      # Code Connectionsへのアクセス許可      {        Effect = "Allow",        Action = [          "codestar-connections:UseConnection"        ],        Resource = aws_codeconnections_connection.github_connection.arn      },      # CodePipelineがAWSサービスにアクセスするための基本的な権限      {        Effect = "Allow",        Action = [          "codebuild:BatchGetBuilds",          "codebuild:StartBuild",          "codestar-connections:UseConnection"        ],        Resource = "*"      }    ]  })}# IAMロールにポリシーをアタッチresource "aws_iam_role_policy_attachment" "codepipeline_policy_attachment" {  role       = aws_iam_role.codepipeline_role.name  policy_arn = aws_iam_policy.codepipeline_policy.arn}# CodePipelineの作成resource "aws_codepipeline" "pipeline" {  name          = "MySimplePipeline"  role_arn      = aws_iam_role.codepipeline_role.arn  pipeline_type = "V2"  artifact_store {    type     = "S3"    location = aws_s3_bucket.deploy_bucket.bucket    encryption_key {      type = "KMS"      # デフォルトのS3管理キーを使用      id = "alias/aws/s3"    }  }  stage {    name = "Source"    action {      name             = "GitHub_Source"      category         = "Source"      owner            = "AWS"      provider         = "CodeStarSourceConnection"      version          = "1"      output_artifacts = ["source_output"]      configuration = {        ConnectionArn    = aws_codeconnections_connection.github_connection.arn        FullRepositoryId = "${var.github_owner}/${var.github_repo}"        BranchName       = var.github_branch      }    }  }  stage {    name = "Deploy"    action {      name            = "S3_Deploy"      category        = "Deploy"      owner           = "AWS"      provider        = "S3"      input_artifacts = ["source_output"]      version         = "1"      configuration = {        BucketName = aws_s3_bucket.deploy_bucket.bucket        Extract    = "true"      }    }  }}

CodePipelineのマネジメントコンソールの設定

初期状態では失敗している

マネジメントコンソールからCodePipeline→パイプラインを見ると、「MySimplePipeline」が失敗しているのがわかる。これはGitHubに接続できていないため。

GitHubに接続する

CodeConnectionsはどこにあるのかというと、CodePipelineの下の「設定」→「接続」部分。ここに「MyGitHubConnection」が保留中になっている。

このあとポップアップが出てくるのでいくつか許可していく。

GitHub側からの確認

「Installed GitHub Apps」に「AWS Connector for GitHub」があれば成功。前のバージョンのCodeStar Connectionsで導入すると、その横の「Authorized Github Apps」にアプリができているが、そちらではこのパイプラインは正常に動作しない。

再度パイプラインを実行

CodePipelineにも戻り「変更をリリースする」などをクリック

今度はパイプラインの実行に成功している。

S3バケットの確認

S3バケットを見ると、ソースコードが同期されているのがわかる。

元のリポジトリに変更を加えてみる

GitHubのブラウザから「test.md」を作り、メインブランチに直でマージする。

するとすぐにCodePipelineが走り、S3バケットに反映されている。バージョニング入れたときのコストは気になるが、ある程度デカくなったらS3のライフサイクルルールを入れろということなのだろう。

CodePipelineの使い所

GitHub Actionsとの比較

CodePipelineの料金はAWSの公式ページより以下の通り

V1 タイプのパイプラインの場合: アクティブなパイプライン(30 日以上存在していて、その月に少なくとも 1 つのコード変更が発生したパイプライン) ごとに1か月あたり 1.00 USD を支払います。その月に新しいコード変更がないパイプラインに対しては、料金は発生しません。アクティブなパイプラインは、1 か月に満たない分に対して按分計算されません。パイプラインは、作成後の最初の 30 日間は無料です。

V2 タイプのパイプラインの場合: アクション実行時間 1 分あたり 0.002 USD を支払います。アクション実行時間は、パイプライン内のアクションが実行開始してからそのアクションが完了状態に達するまで分単位で計算され、最も近い分単位に切り上げられます。手動承認およびカスタムアクションタイプを除くすべてのアクションタイプに対して課金されます。

V1 タイプのパイプラインの場合: 1 か月あたり 1 つの無料のアクティブなパイプライン。
V2 タイプのパイプラインの場合: 1 か月あたり 100 分の無料のアクション実行。無料のアクション実行時間は、アカウント内の V2 パイプラインの数に関係なく、アカウント内のすべての V2 パイプライン間で共有されます。これらは各暦月の初めに自動的にリセットされます。未使用の分が翌月に繰り越されることはありません。

1ヶ月に500分以上CI/CDが走ればV1のほうが安いが、普通に考えるとV2一択だと思われる。上記のTerraformはV2で書いているが、TerraformのデフォルトだとV1でデプロイされてしまうので要注意

一方でGitHub Actionsの無料枠は以下の通り。

プラン Storage 分 (月あたり)
GitHub Free 500 MB 2,000

普通に考えるとGitHub Actionsのほうが無料枠は大きいので、特段大きなストレージが必要とかでなければActionsでいいように思える。

セキュリティの観点から

GitHub Actionsとの大きな違いは、CodePipelineはAWSの閉じた環境で利用できるという点だ。もし公開リポジトリでActionsを走らせてしまうと、ActionsのTerraformのログが見れてしまうことになるので、ここにうっかりセンシティブな値が入ると結構まずいことになる。

「非公開リポジトリならいいでしょ」と思うが、GitHubのリポジトリは必要になって一時的に公開することがあるので、AWSへのデプロイログみたいなのは個人的にあまり公開したくない。そこをAWSと密結合にかつ閉じた環境でできるというのは結構メリットが大きい。

どちらかというとCodePipelineは企業向けというより、個人~少人数向けのような気がする。企業向けならEnterpriseプランでActionsのリッチなVMや、大量の無料枠が使えるし、非公開リポジトリ設定も組織側で結構統制が取れる。しかし、個人だとそこらへん貧弱だったりガバガバになりがちなので、AWSへのデプロイをCI/CDをCodePipelineというのは結構ありな選択な気がした。

少なくとも自分が個人のリポジトリでAWSのCI/CDを動かすなら、多少課金があってもCodePipelineはありかなと思った。どっちかというとActionsでデプロイは個人だと危なっかしくてやりたくないというのが本音(バイナリのビルドぐらいだったら全然問題ないが)。CI/CDでのスクリプトの自由度はまだ見れてないので、今後使ってみたら評価変わるかもしれない。



Shikoan's ML Blogの中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内

技術書コーナー

北海道の駅巡りコーナー


Add a Comment

コメントをキャンセル

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

人気記事

アーカイブ


[8]ページ先頭

©2009-2025 Movatter.jp