🐈

【AWS × Terraform】一時認証自動設定(MFA対応)

に公開

概要

Terraform ハンズオンなどで AWS CLI を使う際、
毎回 MFA(多要素認証)の 6 桁コードを入力して
aws sts get-session-token を実行し、
出力された 3 行の export コマンドをコピーするのは面倒ですよね。

本記事では、臨時認証取得 sts.sh の仕組みを解説し、
それを自動化する便利スクリプト login.sh の作り方を紹介します。

目標:
source ./login.sh だけで、MFA付き AWS 一時認証が自動で設定される!


前提条件

ツール バージョン例 備考
AWS CLI 2.x ~/.aws/credentials に profile 設定済み(例:terraformlearning
jq 1.6 以上 JSON抽出用ツール
Bash Git Bash / Linux / macOS で利用可
MFA 設定済み IAM ユーザー Google Authenticator 等で6桁コード生成可能

sts.sh の内容と仕組み

sts.sh は、AWS CLI の STS (Security Token Service) を使ってMFA 認証付きの一時認証情報 を取得するスクリプトです。

コード全文(配布版)

#!/usr/bin/bash

jq_result=$(which jq &> /dev/null)
if [ `echo $?` -ne 0 ]; then
    echo "You must install jq for $0."
    exit 1
fi

if [[ -z "$2" ]]; then
    export profile="terraformlearning"
else
    export profile=$2
fi

if [[ -z "$1" ]]; then
    echo "[Usage] bash sts.sh <token code> (<profile>)"
    echo "You must set token code for ${profile} shown on your MFA device, such as Google Authenticator."
    exit 1
else
    export token_code=$1
fi

serial_numbers=$(aws iam list-mfa-devices --profile ${profile} | grep SerialNumber | sed 's/\"SerialNumber\"\://' | sed 's/[\ \" \,]//g')

if [ ${#serial_numbers[@]} -eq 1 ]
then
    serial_number=${serial_numbers[0]}
else
    serial_number=${serial_numbers[-1]}
fi

export temp_credentials=`aws sts get-session-token --profile ${profile} --serial-number ${serial_number} --token-code ${token_code} >&1`
if [ `echo $?` != 0 ]; then
    exit 1
fi

access_key_id=`echo ${temp_credentials} | jq -r '.Credentials.AccessKeyId'`
secret_access_key=`echo ${temp_credentials} | jq -r '.Credentials.SecretAccessKey'` 
session_token=`echo ${temp_credentials} | jq -r '.Credentials.SessionToken'` 
expiration=`echo ${temp_credentials} | jq -r '.Credentials.Expiration'`

echo  
echo export AWS_ACCESS_KEY_ID=${access_key_id}
echo export AWS_SECRET_ACCESS_KEY=${secret_access_key}
echo export AWS_SESSION_TOKEN=${session_token}
echo 
echo "(Expiration: ${expiration})"

動作の流れ

ステップ 処理内容
jq がインストールされているか確認
AWS プロファイル名(例:terraformlearning)を設定
引数から 6 桁の MFA コードを取得
aws iam list-mfa-devices で MFA デバイスの ARN を取得
aws sts get-session-token を実行して JSON を取得
jq で AccessKey, SecretKey, SessionToken を抽出
export コマンド形式で出力

出力例

$ bash sts.sh 123456

export AWS_ACCESS_KEY_ID=ASIAxxxxxxxxxxxx
export AWS_SECRET_ACCESS_KEY=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
export AWS_SESSION_TOKEN=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
(Expiration: 2025-10-15T08:30:00+00:00)

この3行をコピーして貼り付ければ、一時的に認証が有効になります。
👉 ただしこれは 手動操作
次に紹介する login.sh を使えば、これが全自動になります!


login.shsts.sh を自動実行して export を反映する

以下のスクリプトを sts.sh と同じディレクトリに作成してください。

#!/usr/bin/env bash
# -----------------------------------------------
# login.sh
# 目的 : sts.sh を自動実行し、AWS 一時認証情報を現在のシェルに設定する
# 使い方 : source ./login.sh  (./login.sh ではなく source を使用!)
# -----------------------------------------------

set -eo pipefail
GIT_PS1_SHOWCONFLICTSTATE=${GIT_PS1_SHOWCONFLICTSTATE:-}

# 1️⃣ 「source」で実行しているか確認
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
  echo "❗このスクリプトは『source ./login.sh』で実行してください。"
  exit 1
fi

# 2️⃣ sts.sh の位置(同じフォルダ想定)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
STS_SH="${STS_SH:-$SCRIPT_DIR/sts.sh}"

# 3️⃣ jq と sts.sh の存在確認
command -v jq >/dev/null || { echo "jq が必要です。インストールしてください。"; return 1; }
[[ -f "$STS_SH" ]] || { echo "sts.sh が見つかりません: $STS_SH"; return 1; }

# 4️⃣ MFA コード入力
read -rp "6桁のMFAコードを入力してください: " MFA_CODE
if [[ ! "$MFA_CODE" =~ ^[0-9]{6}$ ]]; then
  echo "❌ コード形式が正しくありません(6桁の数字)。"
  return 1
fi

echo "▶ 一時認証情報を取得中..."
STS_OUT="$("$STS_SH" "$MFA_CODE" 2>&1 | tee /dev/tty)"

# 5️⃣ export 行を抽出して反映
EXPORTS="$(printf '%s\n' "$STS_OUT" | grep -E '^export (AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|AWS_SESSION_TOKEN)=')"
if [[ -z "$EXPORTS" ]]; then
  echo "❌ sts.sh の出力から認証情報を取得できません。"
  return 1
fi
eval "$EXPORTS"

# 6️⃣ 有効期限表示
EXPIRATION="$(printf '%s\n' "$STS_OUT" | sed -n 's/^[[:space:]]*(Expiration:[[:space:]]*\([^)]*\)).*/\1/p')"
[[ -n "$EXPIRATION" ]] && echo "⏰ 有効期限: $EXPIRATION"

# 7️⃣ 現在の認証ユーザーを確認
if command -v aws >/dev/null; then
  echo "▶ 現在の認証ユーザー:"
  aws sts get-caller-identity || echo "⚠️ 確認失敗: 認証情報を再取得してください。"
fi

echo "✅ 一時認証情報を現在のシェルに設定しました。"
echo " この認証情報はターミナルを閉じるか、有効期限を過ぎると失効します。"
echo " 再ログインする場合は再度:source ./login.sh を実行してください。"

実行方法

chmod +x login.sh
source ./login.sh

注意:必ず source で実行してください!
./login.sh だとサブシェルで実行されるため、環境変数が親シェルに反映されません。

仕組みまとめ

ファイル 役割 実行タイミング
sts.sh AWS CLI を使って一時認証情報(JSON)を取得し、export 形式で出力 MFA コード入力時に自動実行される
login.sh sts.sh の出力を読み取り、現在のシェルに export を適用 source ./login.sh 実行時

よくあるエラーと対処

エラー内容 原因 対処法
unbound variable: GIT_PS1_SHOWCONFLICTSTATE Bash の set -u と Git プロンプト設定が競合 GIT_PS1_SHOWCONFLICTSTATE=${GIT_PS1_SHOWCONFLICTSTATE:-} を追加(上記スクリプト済)
sts.sh not found ファイルパス誤り STS_SH=/path/to/sts.sh を事前に export
not authorized to perform IAM 権限不足 管理者に権限依頼、または既存 VPC を使用
You must install jq jq 未インストール jq公式ページ から導入

Tips

どこからでも使えるようにする

mkdir -p ~/bin
mv sts.sh login.sh ~/bin/
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

以降はどのディレクトリでも:

source login.sh

だけで MFA 認証できます。


まとめ

  • sts.shMFA付きAWS一時認証トークンを取得 するためのスクリプト
  • login.sh はその結果を 自動で環境変数に反映
  • source ./login.sh 一発で認証完了
  • Terraform や AWS CLI ですぐ利用可能
  • 有効期限切れ後も再実行するだけでOK

Discussion