0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub Actions + SSM + Ansibleで自動デプロイ環境を構築するときにハマったこと

0
Posted at

はじめに

Terraformで構築したAWS環境に対して、

  • GitHub Actions
  • OIDC
  • SSM Run Command
  • Ansible

を利用した自動デプロイ環境を構築しました。

最終的には問題なく動作するようになりましたが、構築中にはいくつかハマったポイントがありました。

この記事では、実際に遭遇したエラーや調査方法、解決までの流れをまとめます。

同じような構成を構築している方の参考になれば幸いです。


構成

GitHub Actions
    ↓
OIDC認証
    ↓
IAM Role
    ↓
SSM Run Command
    ↓
EC2
    ↓
Ansible
    ↓
Spring Boot

ハマったポイント①

SSMコマンドが成功なのに何も起きない

最初に遭遇した問題です。

GitHub Actions上では正常終了しているにも関わらず、EC2側では何も実行されていませんでした。

実際の状況

GitHub Actions
↓
Success

しかし、

EC2
↓
何も実行されていない

という状態でした。


調査

まずはSSMの実行履歴を確認しました。

Systems Manager
↓
Run Command
↓
Command History

すると、コマンド自体は正常に送信されていることが確認できました。


原因

GitHub Actionsでは以下を実行していました。

aws ssm send-command

しかし、このコマンドは処理完了まで待ってくれるわけではありません。

実際には

コマンド送信
↓
Command ID返却
↓
終了

という非同期処理でした。

つまり、

GitHub Actions Success
≠
EC2上の処理成功

だったのです。


解決

Command IDを取得し、実行完了までポーリングするようにしました。

STATUS=$(aws ssm get-command-invocation \
  --command-id "${COMMAND_ID}" \
  --instance-id "${EC2_INSTANCE_ID}" \
  --query "Status" \
  --output text)

さらに、

if [ "${STATUS}" != "Success" ]; then
  exit 1
fi

を追加し、SSM実行失敗時はWorkflowも失敗するようにしました。


ハマったポイント②

SSMのログをどこで見ればいいのかわからない

SSM実行結果を確認したかったのですが、

最初はどこを見ればいいのかわかりませんでした。


解決

以下の画面から確認できます。

Systems Manager
↓
Run Command
↓
Command History

ここを見ると、

  • 実行結果
  • エラー内容
  • 実行時間

などを確認できます。

トラブルシューティングの第一歩はここでした。


ハマったポイント③

CloudWatch Logsにログが出力されない

SSM実行結果を詳しく確認したくてCloudWatch Logs出力を設定しました。

しかし、ロググループには何も出力されません。


調査①

まずCloudWatch Logsを確認すると、

ロググループ自体が存在していませんでした。

そのためTerraformでロググループを作成しました。

resource "aws_cloudwatch_log_group" "ssm_run_command" {
  name              = "SSMRunCommandLogs"
  retention_in_days = 7
}

しかしまだ出力されない

ロググループ作成後もログは出力されませんでした。


調査②

さらに調査すると、EC2ロール側にCloudWatch Logsへの書き込み権限が不足していました。

不足していた権限は以下です。

logs:CreateLogStream
logs:DescribeLogStreams
logs:PutLogEvents

解決

EC2ロールへ以下の権限を追加しました。

{
  "Effect": "Allow",
  "Action": [
    "logs:CreateLogStream",
    "logs:DescribeLogStreams",
    "logs:PutLogEvents"
  ]
}

追加後は正常にログが出力されるようになりました。


ハマったポイント④

IAM権限不足の調査とResourceの絞り込み

Terraform Plan実行時に以下のエラーが発生しました。

AccessDenied:
iam:GetInstanceProfile

最初は、

  • Terraformの設定ミス?
  • OIDCの設定ミス?
  • IAMロールの設定ミス?

と原因が分かりませんでした。


調査

CloudTrailのイベント履歴を確認しました。

CloudTrail
↓
Event History
↓
エラーイベントを確認

すると、

Event Source
↓
iam.amazonaws.com

Event Name
↓
GetInstanceProfile

Error Code
↓
AccessDenied

となっていました。

これにより、GitHub Actions用IAMロールが

iam:GetInstanceProfile

を実行しようとして失敗していたことが分かりました。


解決

GitHub Actions用ロールへ以下の権限を追加しました。

iam:GetInstanceProfile

追加後はTerraform Planが正常に実行できるようになりました。


Resourceの絞り込みにも苦戦した

今回の構築では、IAMポリシーを必要最小限にすることも意識していました。

最初は動作確認を優先し、

{
  "Resource": "*"
}

のような広い権限で検証していました。

しかし、そのままでは権限が広すぎるため、実際に使用するリソースのARNへ絞り込むことにしました。
すると今度は別の権限エラーが発生するようになりました。

そのたびにCloudTrailを確認し、

  • 誰が
  • どのAPIを
  • どのリソースに対して
  • なぜ失敗したのか

を調査しながら権限を修正しました。


学んだこと

IAMポリシーは最初から完璧に設計するのは難しいと感じました。

まずは動作確認を行い、その後CloudTrailを利用して実際に使用されているAPIやリソースを確認しながら、少しずつ権限を絞っていく方が効率的でした。

また、IAM権限エラーが発生した場合は、

CloudTrail
↓
Event History

を確認することで、

  • 誰が
  • どのAPIを
  • なぜ失敗したのか

を把握できるため、トラブルシューティングに非常に役立ちました。


ハマったポイント⑤

Terraform Stateが実環境とずれた

学習中、AWSコンソールから直接リソースを削除したことがありました。

その後Terraformを実行すると、エラーが発生するようになりました。


実際の状況

Terraformは、

Terraform State
↓
EC2が存在する

と認識しています。

しかし実際のAWS環境では、

AWS環境
↓
EC2は削除済み

という状態になっていました。

つまり、

Terraform State
↓
存在する

実環境
↓
存在しない

という不整合が発生していました。


なぜ起きたのか

TerraformはStateファイルを基準にリソースを管理しています。

そのため、

Terraform
↓
Stateを参照
↓
変更差分を計算

という流れで動作します。

AWSコンソールから直接リソースを削除しても、TerraformのStateは自動では更新されません。

結果として、

Terraformの認識
↓
まだ存在する

実際
↓
既に削除済み

となり、エラーが発生します。


解決方法

状況に応じて以下を利用しました。

Stateから削除する場合

terraform state rm <resource>

Terraformの管理対象からリソースを外します。


既存リソースを取り込む場合

terraform import

既に存在するAWSリソースをTerraform管理下へ取り込みます。


学んだこと

学習中はAWSコンソールから直接操作したくなることがあります。

しかしTerraform管理下のリソースについては、

Terraformで作る
↓
Terraformで変更する
↓
Terraformで削除する

を徹底した方がよいと感じました。

特にチーム開発では、コンソールからの直接変更はStateとの不整合を引き起こす原因になります。

今回の経験を通じて、

「Terraformの本当の管理対象はAWSではなくStateファイルである」

ということを強く実感しました。

まとめ

GitHub Actions + SSM + Ansibleによる自動デプロイ環境は便利ですが、
構築中にはさまざまなトラブルに遭遇しました。

今回紹介した内容はすべて実際に発生したものです。

今回の構築を通して特に学びになったのは以下の3点です。

  • SSMは非同期で動作するため、実行結果の確認が必要
  • CloudWatch LogsやSSM Command Historyなどのログ確認がトラブルシューティングの第一歩になる
  • IAM権限不足の調査にはCloudTrailが非常に有効

また、Terraformを利用する場合は、AWSコンソールから直接変更せず、

Terraformで作成
↓
Terraformで変更
↓
Terraformで削除

を徹底することの重要性も実感しました。

今回の経験を通じて、

「AWSのトラブルシューティングはまずログを見る」
という習慣の大切さを学びました。

同じような構成を構築する際の参考になれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?