技術ブログ

itamae を再実行して cron / batch を最新化する手順

概要

デモ環境のサーバで、Jenkins による資材最新化は済んでいるものの、itamae 管理配下の cron / batch が古い状態のため、itamae を再実行して最新化する手順をまとめます。

本記事は以下をゴールとします。

  • itamae を安全に再実行できる(事前退避・差分確認込み)
  • cron / batch が最新化されたことを確認できる
  • Public IP がない(Private サブネット)環境でも実行できる

前提

  • 対象はデモ環境の EC2(またはVM相当)
  • 対象ホストは Public IPv4なし(Private IPのみ) の想定
  • 接続経路は次のいずれか
    • SSM Session Manager(推奨)
    • 踏み台 / VPN 経由で SSH
  • itamae の実行方式は次のいずれか
    • 対象ホスト上で itamae を実行(local)
    • 手元または CI(Jenkins等)から itamae を実行(ssh)

記載ルール

本記事では手順で使用する情報を以下の形式で置き換えています。

  • AWS アカウントID:<AWS_ACCOUNT_ID>
  • リージョン:<REGION>
  • インスタンスID:<INSTANCE_ID>
  • Private IP:<PRIVATE_IP>
  • 環境名:<ENV>(例:demo / stg / prd)
  • リポジトリ名:<ITAMAE_REPO>
  • role / recipe:<ROLE_RECIPE>
  • SSH鍵:<KEY_PATH>
  • 踏み台:<BASTION_HOST>

1. 事前準備(安全のためにやる)

1-1. 対象ホストの特定

「メール(デモ)」の実体ホストがどれかを確認します。

  • EC2名(タグ)、systemd サービス名、ログ出力先などで特定
  • 対象ホスト情報例(マスク)
    • Instance ID:<INSTANCE_ID>
    • Private IP:<PRIVATE_IP>
    • Region:<REGION>

1-2. 変更前の退避(必須)

cron/batch を更新する前に、現状の定義を退避して差分確認できるようにします。

# root の crontab
sudo crontab -l | tee ~/crontab_root.before.txt

# ログインユーザーの crontab(必要に応じて)
crontab -l | tee ~/crontab_user.before.txt

# /etc/cron.d 配下
ls -la /etc/cron.d | tee ~/etc_cron_d_list.before.txt
sudo find /etc/cron.* -maxdepth 1 -type f -print | tee ~/etc_cron_files.before.txt

# batch 配置先(例:環境に合わせて変更)
ls -la /opt/batch /usr/local/bin 2>/dev/null | tee ~/batch_list.before.txt

ポイント:後で「何が変わったか」を説明するため、before を残しておくと運用が楽になります。

2. 接続(Public IPなしの想定)

パターンA:SSM Session Manager(推奨)

SSM が使える場合、鍵配布や踏み台が不要で運用が安定します。

aws ssm start-session \
  --target <INSTANCE_ID> \
  --region <REGION>

SSMが使えない場合のチェック観点

  • インスタンスロールに AmazonSSMManagedInstanceCore 相当が付いているか
  • VPCからSSMへ到達できる(NAT または VPC Endpoint)か
  • SSM Agent が稼働しているか

パターンB:踏み台 / VPN 経由で SSH

踏み台がある場合は Jump(Proxy)で接続します。

ssh -J <BASTION_USER>@<BASTION_HOST> <TARGET_USER>@<PRIVATE_IP>;

3. itamae の再実行(2パターン)

パターン1:対象ホスト上で itamae を実行(local)

対象ホストに itamae の資材(リポジトリ)を配置して運用している場合の手順です。

3-1. itamae 資材を最新化

cd /path/to/<ITAMAE_REPO>;
git fetch --all
git checkout main
git pull

3-2. 依存関係の導入(Bundler運用の場合)

bundle install --path vendor/bundle

3-3. ドライラン(可能なら推奨)

bundle exec itamae local <ROLE_RECIPE> -n

3-4. 本適用

bundle exec itamae local <ROLE_RECIPE>;

パターン2:手元/CIから itamae を実行(ssh)

踏み台経由や VPN 経由で対象に到達できる場合の手順です。

bundle exec itamae ssh \
    -h <PRIVATE_IP> \
    -u <TARGET_USER> \
    -i <KEY_PATH> \
       <ROLE_RECIPE>

踏み台が必要な場合は .ssh/config を使うと安定します(例)。

Host target-demo
HostName <PRIVATE_IP>
User <TARGET_USER>
IdentityFile <KEY_PATH>
ProxyJump <BASTION_USER>@<BASTION_HOST>

実行:

bundle exec itamae ssh -h target-demo <ROLE_RECIPE>

4. 適用後の確認(差分・証跡)

4-1. crontab の差分確認

sudo crontab -l | diff -u ~/crontab_root.before.txt -
crontab -l | diff -u ~/crontab_user.before.txt -

4-2. /etc/cron.d の差分確認

ls -la /etc/cron.d | diff -u ~/etc_cron_d_list.before.txt -

4-3. batch の更新確認(配置先が分かる場合)

ls -la /opt/batch /usr/local/bin 2>/dev/null

4-4. ログ確認(環境依存)

sudo tail -n 200 /var/log/cron 2>/dev/null
sudo tail -n 200 /var/log/syslog 2>/dev/null

ポイント:cron から起動されるジョブが systemd timer に移行されている場合もあるため、必要に応じて以下も確認します。

systemctl list-timers --all

5. よくあるハマりどころ

  • Jenkins で最新化したのが アプリ資材のみで、itamae リポジトリが古いまま
  • itamae の role/recipe が想定と異なり、cron を触らないレシピを実行している
  • 変数(node属性 / env)が違い、テンプレート生成結果が一致しない
  • 複数台構成(冗長化・AutoScaling)なのに一台だけ適用している
  • cron ではなく systemd timer 管理に移行していた

ここまで読んでいただき、ありがとうございます。もしこの記事の技術や考え方に少しでも興味を持っていただけたら、ネクストのエンジニアと気軽に話してみませんか。

  • 選考ではありません
  • 履歴書不要
  • 技術の話が中心
  • 所要時間30分程度
  • オンラインOK

エンジニアと話してみる