/var/www/yatta47.log

/var/www/yatta47.log

やったのログ置場です。スクラップみたいな短編が多いかと。

Connect timeout on endpoint URL: https://sts.ap-northeast-1.amazonaws.com の原因と対処法(EC2 Proxy環境)

EC2のProxy環境で aws ecr get-login-passwordaws sts get-caller-identity がタイムアウトする場合、まず NO_PROXY169.254.169.254 が入っているか確認するとほぼ解決します。
見えているエラーはSTSですが、実際に詰まっているのはその手前のIMDS到達です。

前提条件

  • 実行環境: EC2(インスタンスプロファイル/IAMロールを使用)
  • AWS CLI: v2 系
  • ネットワーク: 外向き通信はProxy経由、IMDSは NO_PROXY で除外する構成

エラー内容

CIでECRログインを実行したら、次のエラーで止まりました。

Connect timeout on endpoint URL: "https://sts.ap-northeast-1.amazonaws.com/"

同じインスタンスでSSHして手動実行すると通るので、最初は「ネットワークが不安定?」と思ったんですが、犯人はProxy設定でした。

実ログはこんな形でした(実行コマンド直後のstderr)。

$ aws sts get-caller-identity

Connect timeout on endpoint URL: "https://sts.ap-northeast-1.amazonaws.com/"

再現コマンド(失敗時):

aws sts get-caller-identity

失敗時の出力例:

Connect timeout on endpoint URL: "https://sts.ap-northeast-1.amazonaws.com/"

原因

EC2のIAMロール資格情報は、AWS CLIが内部的にIMDS(169.254.169.254)から取得します。
NO_PROXY 未設定だとこのIMDSアクセスまでProxyに流れて、link-localに到達できずタイムアウトします。

処理の流れはこうです。

aws sts get-caller-identity
  -> 認証情報が必要
  -> IMDS (http://169.254.169.254/...) へアクセス
  -> NO_PROXYなし: Proxy経由になって失敗
  -> 結果としてSTS呼び出し前に詰まり、STSタイムアウトに見える

要するに「STSが悪い」のではなく、「IMDSをProxy除外していない」のが原因です。

解決方法

最小構成はこれです。EC2ランナーなら 169.254.169.254 が最重要です。

export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080
export NO_PROXY=169.254.169.254,localhost

ワークフローに固定する場合:

env:
  HTTP_PROXY: ${{ secrets.HTTP_PROXY }}
  HTTPS_PROXY: ${{ secrets.HTTPS_PROXY }}
  NO_PROXY: 169.254.169.254,localhost

確認コマンド:

aws sts get-caller-identity

成功時の出力例:

{
  "UserId": "AROAXXXXXXXXXXXXX:botocore-session-1234567890",
  "Account": "123456789012",
  "Arn": "arn:aws:sts::123456789012:assumed-role/your-role/i-0abc123def456"
}

IMDS疎通も合わせて確認しておくと安全です。IMDSv2必須環境でも判定できるように、トークン取得付きで確認します。

TOKEN=$(curl -sS --max-time 2 -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 60") \
  && curl -sS --max-time 2 -H "X-aws-ec2-metadata-token: $TOKEN" \
     http://169.254.169.254/latest/meta-data/iam/info > /dev/null \
  && echo "IMDS reachable" || echo "IMDS unreachable"

なぜ気づきにくいか

このトラブル、実運用だと見抜きにくいです。

  • SSHログイン時は .bashrc などでProxy変数が読み込まれて動く
  • CIプロセスはシェルプロファイルを読まず、設定差分が出る
  • エラー文面がSTSなので、IMDS起因に見えない

「手動では通るのにCIだけ失敗」が出た時点で、NO_PROXY を最初に疑うのが早いです。

CI/CDでの防御策

テンプレート化して、毎回同じ3点セットで入れるのが一番事故りません。

env:
  HTTP_PROXY: ${{ secrets.HTTP_PROXY }}
  HTTPS_PROXY: ${{ secrets.HTTPS_PROXY }}
  NO_PROXY: "169.254.169.254,169.254.170.2,localhost"

補足:

  • ECSタスクロールまで使うなら 169.254.170.2 も入れます
  • 可能なら aws sts get-caller-identity を最初のヘルスチェックに入れます
  • Proxy URLに認証情報を含める場合は、平文の vars ではなく secrets で管理します

まとめ

Connect timeout on endpoint URL: https://sts.ap-northeast-1.amazonaws.com がEC2 Proxy環境で出たら、まず NO_PROXY=169.254.169.254 を確認することをお勧めします。
STSタイムアウトに見えても、実際はIMDS到達の問題であることが多いです。

参考