1. 概要
- JenkinsでTerraformのCI/CDを構築する手順
- Jenkinsfileでのplan/applyパイプライン
- AWS認証情報をJenkinsのCredentialsで管理する方法
- plan結果の承認ゲートの設定
Jenkinsはオンプレミスでの実績があるCI/CDサーバーです。Terraform専用機能はありませんが、Jenkinsfileでplan/applyのパイプラインを自由に構築できます。
2. Terraform設定
terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "my-company-tfstate"
key = "app/terraform.tfstate"
region = "ap-northeast-1"
encrypt = true
dynamodb_table = "terraform-lock"
}
}
provider "aws" {
region = "ap-northeast-1"
}
variable "environment" {
description = "環境名"
type = string
default = "dev"
}
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = "t3.micro"
root_block_device {
volume_size = 20
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${var.environment}-web"
Environment = var.environment
ManagedBy = "terraform"
}
}
3. Jenkinsfile(宣言型パイプライン)
// Jenkinsfile
pipeline {
agent any
environment {
AWS_REGION = 'ap-northeast-1'
TF_VERSION = '1.9.0'
TF_VAR_environment = 'dev'
}
tools {
// Jenkins Tool設定でTerraformを登録している場合
// terraform 'terraform-1.9'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Terraform Init') {
steps {
withCredentials([
string(credentialsId: 'aws-access-key-id',
variable: 'AWS_ACCESS_KEY_ID'),
string(credentialsId: 'aws-secret-access-key',
variable: 'AWS_SECRET_ACCESS_KEY')
]) {
sh '''
terraform init \
-backend-config="bucket=my-company-tfstate" \
-backend-config="key=app/terraform.tfstate" \
-backend-config="region=${AWS_REGION}"
'''
}
}
}
stage('Terraform Validate') {
steps {
sh 'terraform validate'
}
}
stage('Terraform Plan') {
steps {
withCredentials([
string(credentialsId: 'aws-access-key-id',
variable: 'AWS_ACCESS_KEY_ID'),
string(credentialsId: 'aws-secret-access-key',
variable: 'AWS_SECRET_ACCESS_KEY')
]) {
sh 'terraform plan -no-color -out=tfplan | tee plan_output.txt'
}
// plan結果をJenkinsのArtifactとして保存
archiveArtifacts artifacts: 'plan_output.txt', fingerprint: true
}
}
stage('Approval') {
// mainブランチのみ承認ゲートを設ける
when {
branch 'main'
}
steps {
// 手動承認(デフォルト60分でタイムアウト)
timeout(time: 60, unit: 'MINUTES') {
input message: 'Terraform Applyを実行しますか?',
ok: 'Apply',
submitter: 'admin,infra-team'
}
}
}
stage('Terraform Apply') {
when {
branch 'main'
}
steps {
withCredentials([
string(credentialsId: 'aws-access-key-id',
variable: 'AWS_ACCESS_KEY_ID'),
string(credentialsId: 'aws-secret-access-key',
variable: 'AWS_SECRET_ACCESS_KEY')
]) {
sh 'terraform apply tfplan'
}
}
}
}
post {
always {
// tfplanファイルを削除(Stateファイルのリークを防ぐ)
sh 'rm -f tfplan'
}
success {
echo 'Terraform pipeline succeeded'
}
failure {
echo 'Terraform pipeline failed'
}
}
}
4. AWS認証情報の管理
Credentials設定(Jenkins UI):
Jenkins → Manage Jenkins → Credentials → System → Global → Add Credentials
- Kind: Secret text
- ID:
aws-access-key-id/aws-secret-access-key - Secret: IAMアクセスキーID / シークレットキー
IAMロールで認証する場合(JenkinsがEC2上で動いている場合):
// IAMロールをEC2インスタンスプロファイルで設定している場合
// AWS認証情報の記述は不要
stage('Terraform Plan') {
steps {
sh 'terraform plan -no-color'
}
}
5. 関連記事
- Terraform Cloud vs Jenkins — エンタープライズ選定ガイド — プラットフォーム比較
- GitHub ActionsでTerraformを実行する方法 — モダンCI/CDとの比較
- Terraform CI/CDのシークレット管理 — 認証情報の扱い
- Terraform CI/CDのブランチ戦略 — ブランチ設計
- backend — stateファイルの保存場所を設定 — S3バックエンド
- Terraform Cloud vs GitHub Actions — ツール選定
6. まとめ
- Jenkinsfileの宣言型パイプラインでinit → validate → plan → 承認 → applyを構築できる
- AWS認証はJenkins Credentialsに保存するか、EC2インスタンスプロファイル(推奨)を使う
inputステップで手動承認ゲートを設けることで意図しないapplyを防止できる- Terraform専用機能はないが、Jenkinsの柔軟なパイプラインでカスタムワークフローを実現できる
対象バージョン: Terraform >= 1.9 / Jenkins LTS 公式ドキュメント: https://www.jenkins.io/doc/book/pipeline/