さくらインターネットでエンジニアをしている 芦野と申します。( https://x.com/tar_xzvff )
アカウント名の通り、自宅サーバに始まり、かれこれずっとサーバに関わる仕事をしています。
普段はインフラエンジニア/バックエンドエンジニアとして勤務しており、
VMM やコンテナ技術周辺を主な関心領域としています。
社外での活動では、ITカンファレンスのイベントネットワーク(NOC)に携わることがあります。
ルータ、L2スイッチ、無線LANアクセスポイントなどの物理機材を用いた構築が主ですが、最近では監視やログサーバなどをクラウド上に事前構築しておき、現地から VPN でクラウドに接続することで迅速にサービスを展開する、といったハイブリッド構成を取ることが増えてきました。
そのような場面で、チームメンバーに対して Terraform + GitHub Actions を使った IaC / CI/CD をレクチャーする機会がありました。
本記事では、その際に実践した「GitHub Actions で Terraform を使ってさくらのクラウドを管理する方法」を紹介します。
本記事は、Terraform や GitHub Actions をある程度触ったことがあり、さくらのクラウドを GitOps で管理してみたい方を対象としています。
前提
- GitHubにサインアップ済み
- さくらのクラウドにサインアップ済み、プロジェクト作成済み
- まだの方は以下をご覧ください
- https://cloud.sakura.ad.jp/flow/
1. Terraform Backendとして利用するストレージを作成
Terraform の Backend として、さくらのクラウドのオブジェクトストレージ(S3互換)を利用します。
tfstate の保存先となるバケットを作成します。作成方法は以下をご参考ください。
https://manual.sakura.ad.jp/cloud/objectstorage/basic.html
今回は以下の内容で作成しました。任意の名前で作成してください。
バケット名: sacloud-terraform
バケット作成後パーミッションを作成します。作成方法は以下をご参考ください。
バケット sacloud-terraform に対して、 READ/WRITE の設定を行ってください。
https://manual.sakura.ad.jp/cloud/objectstorage/basic.html#objectstrage-about-permission
今回は以下の内容で作成しました。
パーミッション名: gha
アクセスキーIDとシークレットアクセスキーが発行されるので手元にコピーしてください、後ほど利用します。
バケットに対してパーミッションからREAD/WRITEの権限が付与されていることを確認してください。
2. さくらのクラウド APIキーの作成
Terraform からさくらのクラウドにアクセスするために、API キーを作成します。
APIキーの作成方法は以下をご参考ください。
https://manual.sakura.ad.jp/cloud/api/apikey.html
アクセスレベル: 作成・削除 で作成してください。
アクセストークンとアクセストークンシークレットが発行されるので手元にコピーしてください、後ほど利用します。
3. GitHubリポジトリの作成
TerraformでCI/CDするために管理用のリポジトリを作成します。
mainブランチが存在しているところまで進めてください。
https://github.com/new
4. Terraform Provider設定
mkdir terraform
bucket = "sacloud-terraform" の部分は作成したバケット名に修正してください。
terraform {
backend "s3" {
bucket = "sacloud-terraform"
key = "terraform.tfstate"
region = "jp-north-1"
endpoints = {
s3 = "https://s3.isk01.sakurastorage.jp"
}
skip_credentials_validation = true
skip_requesting_account_id = true
skip_region_validation = true
skip_metadata_api_check = true
skip_s3_checksum = true
}
required_providers {
sakuracloud = {
source = "sacloud/sakuracloud"
version = "2.31.2"
}
}
}
provider "sakuracloud" {}
5. GitHub Actionsの設定
mkdir -p .github/workflows
name: CI
on:
pull_request:
branches:
- main
paths:
- "terraform/**"
workflow_dispatch:
permissions:
contents: write
pull-requests: write
defaults:
run:
working-directory: ./terraform
env:
TF_VERSION: "1.13.0"
TFCMT_VERSION: "v4.14.12"
SAKURACLOUD_ACCESS_TOKEN: ${{ secrets.SAKURACLOUD_ACCESS_TOKEN }}
SAKURACLOUD_ACCESS_TOKEN_SECRET: ${{ secrets.SAKURACLOUD_ACCESS_TOKEN_SECRET }}
SAKURACLOUD_ZONE: ${{ vars.SAKURACLOUD_ZONE }}
AWS_ACCESS_KEY_ID: ${{ secrets.SAKURACLOUD_STORAGE_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SAKURACLOUD_STORAGE_SECRET_ACCESS_KEY }}
AWS_REQUEST_CHECKSUM_CALCULATION: WHEN_REQUIRED
AWS_RESPONSE_CHECKSUM_VALIDATION: WHEN_REQUIRED
jobs:
fmt:
name: terraform fmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TF_VERSION }}
- name: terraform fmt
run: terraform fmt -check
validate:
name: terraform validate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TF_VERSION }}
- run: terraform init
- run: terraform validate -no-color
plan:
name: terraform plan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TF_VERSION }}
- name: setup tfcmt
run: |
wget "https://github.com/suzuki-shunsuke/tfcmt/releases/download/${TFCMT_VERSION}/tfcmt_linux_amd64.tar.gz" -O /tmp/tfcmt.tar.gz
tar xzf /tmp/tfcmt.tar.gz -C /tmp
mv /tmp/tfcmt /usr/local/bin
tfcmt --version
- run: terraform init
- name: terraform plan
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: tfcmt plan --patch -- terraform plan -no-color -input=false
name: CD
on:
push:
branches:
- main
paths:
- "terraform/**"
concurrency:
group: terraform-deploy
cancel-in-progress: false
permissions:
contents: write
pull-requests: write
defaults:
run:
working-directory: ./terraform
env:
TF_VERSION: "1.13.0"
TFCMT_VERSION: "v4.14.12"
SAKURACLOUD_ACCESS_TOKEN: ${{ secrets.SAKURACLOUD_ACCESS_TOKEN }}
SAKURACLOUD_ACCESS_TOKEN_SECRET: ${{ secrets.SAKURACLOUD_ACCESS_TOKEN_SECRET }}
SAKURACLOUD_ZONE: ${{ vars.SAKURACLOUD_ZONE }}
AWS_ACCESS_KEY_ID: ${{ secrets.SAKURACLOUD_STORAGE_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SAKURACLOUD_STORAGE_SECRET_ACCESS_KEY }}
AWS_REQUEST_CHECKSUM_CALCULATION: WHEN_REQUIRED
AWS_RESPONSE_CHECKSUM_VALIDATION: WHEN_REQUIRED
jobs:
apply:
name: terraform apply
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TF_VERSION }}
- name: terraform fmt
run: terraform fmt -check
- name: setup tfcmt
run: |
wget "https://github.com/suzuki-shunsuke/tfcmt/releases/download/${TFCMT_VERSION}/tfcmt_linux_amd64.tar.gz" -O /tmp/tfcmt.tar.gz
tar xzf /tmp/tfcmt.tar.gz -C /tmp
mv /tmp/tfcmt /usr/local/bin
tfcmt --version
- run: terraform init
- run: terraform validate -no-color
- name: terraform apply
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: tfcmt apply -- terraform apply -auto-approve
6. シークレット・変数の設定
Terraformの実行に必要な環境変数を設定します。
作成した GitHub リポジトリの Settings → Secrets and variables → Actions から、
Repository Secrets & Variables にシークレットと変数を設定します。
https://docs.github.com/ja/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets
https://docs.github.com/ja/actions/how-tos/write-workflows/choose-what-workflows-do/use-variables
先ほど作成した、オブジェクトストレージとさくらのクラウド APIキーの情報をそれぞれ設定してください。
Secrets
| 環境変数 | 値 |
|---|---|
| SAKURACLOUD_STORAGE_ACCESS_KEY_ID | オブジェクトストレージのアクセスキーID |
| SAKURACLOUD_STORAGE_SECRET_ACCESS_KEY | オブジェクトストレージのシークレットアクセスキー |
| SAKURACLOUD_ACCESS_TOKEN | さくらのクラウド APIキーのアクセストークン |
| SAKURACLOUD_ACCESS_TOKEN_SECRET | さくらのクラウド APIキーのアクセストークンシークレット |
Variables
| 環境変数 | 値 | 説明 |
|---|---|---|
| SAKURACLOUD_ZONE | is1b | リソースの作成先ゾーン |
7. terraform plan の動作確認
手元で作成したファイルを Push し、Pull Request を作成します。
git checkout -b init
git add .github/
git add terraform/provider.tf
git commit -m "init"
git push origin init
Pull Request作成すると、 terraform fmt / plan / validateのワークフローが実行されます。

terraform fmt / plan / validateが全て通ることを確認します。

全て通ったことを確認したら、マージします。
8. terraform apply の動作確認
Actionsタブを開き、terraform applyのワークフローが実行されたことを確認します。
9. [実践編] サーバを作成する
これまでの手順で準備が整いました、実際にさくらのクラウド上にリソースを作成してみましょう。
今回はGitHubに登録している公開鍵でログインできるサーバを1台作成します。
git checkout main
git pull origin main
git checkout -b feat/add-server
2つのファイルを作成します。
ご自身のGitHubユーザ名などに置き換えてください。
github_username = "tar-xzvff"
variable "github_username" {
type = string
description = "GitHub username for fetching public SSH keys"
}
data "sakuracloud_archive" "ubuntu" {
os_type = "ubuntu2404"
}
data "http" "key" {
url = format("https://github.com/%s.keys", var.github_username)
}
resource "sakuracloud_disk" "server" {
name = "server"
source_archive_id = data.sakuracloud_archive.ubuntu.id
}
resource "sakuracloud_server" "server" {
name = "server"
disks = [sakuracloud_disk.server.id]
core = 1
memory = 1
description = "terraformから作成"
network_interface {
upstream = "shared"
}
disk_edit_parameter {
hostname = "server"
disable_pw_auth = true
ssh_keys = split("\n", trimspace(data.http.key.response_body))
}
}
手元で作成したファイルをPushしPull Request作成します。
git add terraform/
git commit -m "Add new server"
git push origin feat/add-server
terraform plan の結果がPull Requestのコメントとして投稿されます。
マージ前に確認をしましょう。

CIも全て通ったことが確認できたらマージしましょう。
マージ後 terraform applyのワークフローが実行されます。
今回は約2分半ほどで完了しました。
Pull Requestのコメントを確認するとterraform applyの結果が投稿が確認できます。
さくらのクラウドのコントロールパネルから作成されたサーバを確認します。
これでGitHub ActionsによるTerraformでのさくらのクラウド上へのリソース作成が完了となります。
ポイント
Terraform Backendの設定
さくらのクラウド オブジェクトストレージを利用する場合は、環境変数の設定が必要となります。
以下の 2 つの値に WHEN_REQUIRED をセットします。
- AWS_REQUEST_CHECKSUM_CALCULATION
- AWS_RESPONSE_CHECKSUM_VALIDATION
今回はこれらの値を workflow の env で指定しています。詳細は以下をご覧ください。
https://cloud.sakura.ad.jp/news/2025/02/04/objectstorage_defectversion/
terraform apply ワークフローでの排他制御
万が一、同時に terraform apply が実行された場合、エラーや tfstate の破損などにつながる恐れがあるため、concurrency を設定し terraform apply が複数同時に実行されないようにしています。
また、cancel-in-progress: false を指定することで、すでに実行中の apply を途中で強制停止せず、後から来た実行はキューにたまるようになっています。
Terraform の実行を中断すると状態の不整合につながりやすいため、この設定は特に重要です。
感想
今回は最低限の構成でGitHub Actionsによるさくらのクラウドの管理の仕組みをご紹介しました。
実際の運用では Branch ruleset などを活用することで、より安全にインフラを管理する仕組みを実現できます。
また、このような GitOps を行うことで Source of Truth を実現できます。
情報の不整合性の排除、権限と操作の集中管理、履歴管理による再現性の確保などさまざまな恩恵を享受することができます。
この記事をきっかけに、さくらのクラウドを CI/CD で管理することにトライしてみようと思っていただけたら幸いです。
今回の記事で設定したファイル一式を含んだ、GitHubリポジトリテンプレートも用意しました。
このテンプレートからリポジトリを作成することで、より簡単に本記事と同じ環境を構築できます。
ぜひご活用ください
https://github.com/tar-xzvff/sacloud-gitops-template/







