Skip to content

運用スクリプト作成ガイド

概要

本ガイドは ops/scripts/ 配下に配置する運用スクリプトのネーミングルール、ディレクトリ構成、実装スタイルを定義します。Gulp タスクランナーと連携し、環境構築・デプロイ・プロビジョニング・運用タスクを自動化します。

ディレクトリ構成

ops/
├── scripts/
│   ├── shared.js              # 共通ユーティリティ
│   ├── ssh.js                 # SSH/SCP ヘルパー
│   ├── deploy_dev.js          # 開発環境デプロイ
│   ├── deploy_stg.js          # ステージング環境デプロイ
│   ├── deploy_prd.js          # 本番環境デプロイ
│   ├── provision_stg.js       # ステージング環境プロビジョニング
│   ├── provision_prd.js       # 本番環境プロビジョニング
│   ├── develop.js             # アプリケーション開発タスク
│   ├── release.js             # リリースワークフロー
│   ├── journal.js             # 開発ジャーナル生成
│   ├── mkdocs.js              # ドキュメントビルド
│   ├── vault.js               # シークレット管理
│   ├── ssh_stg.js             # ステージング SSH・踏み台
│   ├── ssh_prd.js             # 本番 SSH・踏み台
│   ├── sonar_local.js         # SonarQube ローカル環境
│   └── sonar_aws.js           # SonarQube AWS 環境
├── terraform/                  # IaC(Terraform)
├── docker/                     # Docker 関連設定
└── nix/                        # Nix 開発環境(任意)

ネーミングルール

ファイル名

{カテゴリ}_{環境}.js の形式で命名する。

カテゴリ 説明
deploy デプロイスクリプト deploy_dev.js, deploy_stg.js, deploy_prd.js
provision IaC プロビジョニング provision_stg.js, provision_prd.js
ssh SSH・踏み台操作 ssh.js(共通), ssh_stg.js, ssh_prd.js
develop アプリケーション開発タスク develop.js
release リリースワークフロー release.js
journal 開発ジャーナル journal.js
mkdocs ドキュメント mkdocs.js
sonar コード品質分析 sonar_local.js, sonar_aws.js
shared 共通ユーティリティ shared.js
vault シークレット管理 vault.js

環境サフィックス:

サフィックス 環境
_dev 開発環境 deploy_dev.js
_stg ステージング環境 deploy_stg.js, provision_stg.js
_prd 本番環境 deploy_prd.js, provision_prd.js
_local ローカル環境 sonar_local.js
_aws AWS 環境 sonar_aws.js
なし 環境非依存 / 共通 shared.js, ssh.js, release.js

Gulp タスク名

{カテゴリ}:{環境}:{アクション} の形式で命名する。

deploy:dev:build          # 開発環境: ビルド
deploy:dev:push           # 開発環境: Registry プッシュ
deploy:dev                # 開発環境: デプロイ実行
deploy:dev:status         # 開発環境: ステータス確認
deploy:dev:logs           # 開発環境: ログ取得
deploy:dev:clean          # 開発環境: クリーンアップ
deploy:dev:setup          # 開発環境: 初回セットアップ
deploy:dev:help           # 開発環境: ヘルプ

provision:stg:plan        # ステージング: Terraform plan
provision:stg:vpc         # ステージング: VPC プロビジョニング
provision:stg:rds         # ステージング: RDS プロビジョニング
provision:stg:ecs         # ステージング: ECS プロビジョニング
provision:stg             # ステージング: 全リソース一括
provision:stg:destroy     # ステージング: 全リソース廃棄
provision:stg:help        # ステージング: ヘルプ

ssh:stg:login             # ステージング: 踏み台ログイン
ssh:stg:tunnel            # ステージング: SSH トンネル
ssh:stg:backup            # ステージング: DB バックアップ
ssh:stg:restore           # ステージング: DB リストア

dev:sms                   # SMS 開発サーバー起動
dev:sms:product           # SMS product プロファイル起動
tdd:sms                   # SMS TDD モード

実装スタイル

基本構造

すべてのスクリプトは以下の構造に従う。

'use strict';

import path from 'path';
import { execSync } from 'child_process';
import { cleanDockerEnv } from './shared.js';

// ============================================
// 設定
// ============================================

const PREFIX = 'DEV'; // 環境変数プレフィックス

/** サービス定義 */
const SERVICES = [
  { name: 'backend', port: 8080, container: 'app-backend', label: 'Backend' },
  { name: 'frontend', port: 3000, container: 'app-frontend', label: 'Frontend' },
];

// ============================================
// ヘルパー関数
// ============================================

/**
 * JSDoc コメントで関数の目的・引数・戻り値を記述
 * @param {string} param - パラメータの説明
 * @returns {string}
 */
function helperFunction(param) {
  // 実装
}

// ============================================
// Gulp タスク
// ============================================

export default function(gulp) {
  // タスク登録
  gulp.task('deploy:dev:build', (done) => {
    // タスク実装
    done();
  });
}

コーディング規約

1. strict mode

すべてのファイルの先頭に 'use strict'; を記述する。

2. ESM(ES Modules)

import / export 構文を使用する。require は使用しない。

// Good
import path from 'path';
import { execSync } from 'child_process';
import { cleanDockerEnv } from './shared.js';

// Bad
const path = require('path');

3. セクション区切り

コード内のセクションは以下のコメントで区切る。

// ============================================
// 設定
// ============================================

// ============================================
// ヘルパー関数
// ============================================

// ============================================
// Gulp タスク
// ============================================

4. JSDoc コメント

すべての関数に JSDoc コメントを記述する。

/**
 * docker build に渡すオプションを組み立てる
 * @returns {string} ビルドオプション文字列
 */
function dockerBuildOptions() {
  // ...
}

5. 環境変数の管理

環境変数は .env ファイルで管理し、環境プレフィックス(DEV_, STG_, PRD_)で名前空間を分離する。

// 環境変数プレフィックスで名前空間を分離
const PREFIX = 'STG';
const awsProfile = () => process.env.STG_AWS_PROFILE || '';
const sshHost = () => process.env[`${PREFIX}_SSH_HOST`];

環境変数の命名規則:

プレフィックス 環境
DEV_ 開発環境 DEV_SSH_HOST, DEV_SSH_USER
STG_ ステージング環境 STG_AWS_PROFILE, STG_DB_USERNAME
PRD_ 本番環境 PRD_AWS_PROFILE, PRD_DB_USERNAME
GHCR_ GitHub Container Registry GHCR_USER, GHCR_TOKEN
DOCKER_ Docker 関連 DOCKER_BUILD_NETWORK, DOCKER_BUILD_DNS

6. サービス定義

複数サービスを扱うスクリプトでは、サービスを配列で定義する。

const SERVICES = [
  { name: 'sms', port: 8080, container: 'app-sms', label: 'SMS(販売管理)' },
  { name: 'fas', port: 8081, container: 'app-fas', label: 'FAS(財務会計)' },
];

サービス定義を基に、個別タスクと一括タスクを動的に生成する。

// 個別タスク: deploy:dev:build:sms, deploy:dev:build:fas
SERVICES.forEach((svc) => {
  gulp.task(`deploy:dev:build:${svc.name}`, (done) => {
    buildImage(svc);
    done();
  });
});

// 一括タスク: deploy:dev:build(全サービス)
gulp.task('deploy:dev:build', gulp.series(
  ...SERVICES.map((svc) => `deploy:dev:build:${svc.name}`)
));

7. エラーハンドリング

execSync のエラーは適切にキャッチし、ユーザーにわかりやすいメッセージを表示する。

try {
  execSync(command, { stdio: 'inherit', env: cleanDockerEnv() });
} catch (err) {
  console.error(`エラー: ${err.message}`);
  process.exit(1);
}

8. ヘルプタスク

各カテゴリにヘルプタスクを提供する。

gulp.task('deploy:dev:help', (done) => {
  console.log(`
=== 開発環境デプロイコマンド ===

  deploy:dev:build          全サービスをローカルビルド
  deploy:dev:push           全イメージを Registry にプッシュ
  deploy:dev                全サービスをデプロイ
  deploy:dev:status         コンテナ状態を確認
  deploy:dev:logs           コンテナログを表示
  deploy:dev:clean          開発環境を完全削除
  deploy:dev:setup          初回セットアップ
  deploy:dev:help           このヘルプを表示
  `);
  done();
});

共通ユーティリティ(shared.js)

環境をまたいで共通的に使用するユーティリティ関数を shared.js に集約する。

'use strict';

/**
 * DOCKER_HOST を除外した環境変数を返す
 * Docker Desktop 使用時に DOCKER_HOST が設定されていると接続エラーが発生するため除外する
 * @returns {Object} DOCKER_HOST を除外した環境変数
 */
export function cleanDockerEnv() {
  const env = { ...process.env };
  delete env.DOCKER_HOST;
  return env;
}

SSH ヘルパー(ssh.js)

SSH/SCP 操作を共通化する。環境プレフィックスで接続先を切り替える。

/**
 * SSH 接続パラメータを取得
 * @param {string} [prefix='DEV'] 環境変数プレフィックス
 * @returns {{ host: string, user: string, port: string, keyFile: string | undefined }}
 */
export function getSSHConfig(prefix = 'DEV') {
  const host = process.env[`${prefix}_SSH_HOST`];
  const user = process.env[`${prefix}_SSH_USER`];
  const port = process.env[`${prefix}_SSH_PORT`] || '22';
  const keyFile = process.env[`${prefix}_SSH_KEY`];

  if (!host || !user) {
    throw new Error(`${prefix}_SSH_HOST と ${prefix}_SSH_USER を .env に設定してください`);
  }

  return { host, user, port, keyFile };
}

/**
 * SSH でリモートコマンドを実行
 * @param {string} command 実行するコマンド
 * @param {object} [options] オプション
 * @param {boolean} [options.ignoreError] エラーを無視するか
 * @param {boolean} [options.capture] 出力を文字列で返すか
 * @param {string} [options.prefix] 環境変数プレフィックス
 * @returns {string} 標準出力
 */
export function sshExec(command, options = {}) {
  // 実装
}

/**
 * SCP でローカルファイル/ディレクトリをリモートに転送
 * @param {string} localPath ローカルパス
 * @param {string} remotePath リモートパス
 * @param {object} [options] オプション
 * @param {boolean} [options.recursive] ディレクトリを再帰的に転送
 * @param {string} [options.prefix] 環境変数プレフィックス
 */
export function scpUpload(localPath, remotePath, options = {}) {
  // 実装
}

AWS 連携パターン

aws-vault ラッパー

AWS 操作では aws-vault exec 経由で認証情報を自動取得する。

/**
 * aws-vault ラッパーを組み立てる
 * @returns {string} コマンドプレフィックス
 */
function awsExecPrefix() {
  const profile = process.env.STG_AWS_PROFILE || '';
  if (!profile) return '';
  return `aws-vault exec ${profile} -- `;
}

Terraform 操作

/**
 * Terraform コマンドを実行
 * @param {string} subcommand - Terraform サブコマンド
 * @param {object} options - オプション
 */
function terraform(subcommand, options = {}) {
  const prefix = awsExecPrefix();
  const cmd = `${prefix}terraform ${subcommand}`;
  execSync(cmd, { cwd: options.cwd, stdio: 'inherit' });
}

Gulp タスク登録パターン

gulpfile.js

import gulp from 'gulp';
import deployDev from './ops/scripts/deploy_dev.js';
import deployStg from './ops/scripts/deploy_stg.js';
import provisionStg from './ops/scripts/provision_stg.js';

// 各モジュールのタスクを登録
deployDev(gulp);
deployStg(gulp);
provisionStg(gulp);

package.json のスクリプト

{
  "scripts": {
    "deploy:dev": "npx gulp deploy:dev",
    "deploy:stg": "npx gulp deploy:stg",
    "provision:stg": "npx gulp provision:stg"
  }
}

スクリプト作成の手順

新しい運用スクリプトを作成する際は以下の手順に従う。

  1. ネーミング: {カテゴリ}_{環境}.js でファイル名を決定
  2. テンプレート: 基本構造(設定→ヘルパー関数→Gulp タスク)に従って実装
  3. 共通関数: shared.jsssh.js の既存関数を活用
  4. 環境変数: .env.example に必要な環境変数を追記
  5. ヘルプ: {カテゴリ}:{環境}:help タスクを作成
  6. gulpfile.js: タスクを登録
  7. ドキュメント: コマンドリファレンスを作成・更新