生成 AI との付き合い方 : AWS SSM 実装における実践例

## はじめに
今年、AI 技術は開発現場に急速に進化し、開発の現場にも一気に浸透した一年でした。Qiita でも多くの記事が投稿され勉強させていただきました！ありがとうございます！

一部の現場では、機密情報の漏洩という観点からはまだまだ敬遠されがちではあります。特に弊社のような受託開発では事前に締結した機密保持契約の内容に抵触することもあり、導入には慎重にならざるを得ないケースがあります。

私個人としては、AI の技術がなかった頃の古い契約はこれを機に見直し、双方合意の上で積極的に取り入れたいと思っています。

そういった機密保持の理由以外でも、まだまだ AI に向き合えない(どう使って良いのかわからない)方も多いと思います。特に、「使ってみたけど欲しい回答が返ってこなかった」、「AI の回答が間違っていた」など、「ふーんその程度かー」で使わなくなった方も多いのではないでしょうか？

AI も完全ではないので間違いはあります。ただ、それ以上に人間側の質問が曖昧であったり、的を得ていないことの方が多く、結局は人間がどれだけ問題点を言語化できるか、というところに尽きると思います。流石に AI もエスパーではないので、人間の頭の中までは見ることができません。効率よく正確に指示を出す、というのは現実世界でもコミュニケーション上大事な要素であり、AI 云々に限った話ではありません。コンピュータサイエンスの分野において用いられる表現で GIGO (Garbage In, Garbage out = 入力がゴミであれば出力もまたゴミである) という言葉がありますが、AI の使い方もまた然り、いくらAIが進化してもプロンプト次第でゴミ生成器になる可能性は十分にありえます。


そんなわけで、本記事では、AIツールを活用したAWS SSM（Systems Manager）の実装過程を例に、効果的なAIとの対話方法と問題解決のアプローチを紹介します。テクニックなどという大それたものではなく、AI でこんなに楽しく調べ物ができるんだ！という魅力に気付いてもらえると幸いです。

尚、今回は [Claude 3.5 Sonnet](https://www.anthropic.com/news/claude-3-5-sonnet) を使用しました。


## 実践例：AWS SSM の実装
### 1. 目線合わせから始める対話
AI にいきなり核心を付くような質問を投げることができればそれに越したことはないのですが、そうではないことの方が多いと思います。そういう時に私がよく使うのは、「私の理解が浅く、何から質問したら良いかわからないので、一緒に考えてくれませんか？」というスタンスから質問に入ることです。

今回は、SSH の踏み台を使わない仕組みとして、AWS SystemManager を使用する案件でのデプロイ自動化を調べる必要があり、SSM も始めてであったため下記のような質問から入ってみました。

> aws の ssm という仕組みを使って、踏み台なしで ssh 接続し、ansible を使って、gitlab のソースをデプロイする gitlab-ci.yml の作成を一緒に手伝ってくれませんか？

すると AI からは、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6102/81d2952f-6cc8-5d58-9bc4-880166479b2f.png)

もういきなり芯を食った回答が来ました。でもちゃんとポイントも解説してくれていますね。ふむふむ、認証は IAM を使って AWS CLI でデプロイしているのね。ちゃんと gitlab-ci.yml (中身は省略) も作成してくれています。もちろんこの設定ファイルでいきなりゴールではないので、まずはこれを叩き台として AI と対話しましょう。

提案してもらった gitlab-ci.yml は、Ansible のインベントリが before_script の中で作られており、メンテし辛そうに見えたので、下記のように指示を出してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6102/506ea95d-9c08-0924-f77f-79a5843954f1.png)

これに対して AI は下記のように提案してくれました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6102/28423ed4-bd36-88c8-f993-28f2592ce1b9.png)

なかなか良い感じです。SSM についての理解が無い状態から、一気に gitlab-ci.yml と Ansible の Playbook の叩き台が作れました。
ここまでくればあとは色々いじりながら試せそうですが、せっかくなので引き続き AI に手伝ってもらいましょう。

### 2. エラー対応と試行錯誤
まずは提案してもらった gitlab-ci.yml をそのまま使い、環境変数などをセットして実行してみました。
流石に一発でうまくいく訳はなく、下記のようなエラーが出ました。

```
TASK [Gathering Facts] *********************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the TerminateSession operation: User: arn:aws:iam::###############:user/xxxxxxxxxxx is not authorized to perform: ssm:TerminateSession on resource: arn:aws:ssm:ap-northeast-1:###############:session/xxxxxxxxxxx-zzzzzzzzzzzzzzzzzzzzzzzzzzz because no identity-based policy allows the ssm:TerminateSession action
fatal: [target]: FAILED! => {"msg": "Unexpected failure during module execution.", "stdout": ""}
```

なんとなく権限がない的なエラーなので IAM ポリシーなのかなというところまでは分かります。エラーメッセージをそのまま貼り付けて聞いてみました。

> このエラーは AWS Systems Manager (SSM) の権限が不足していることを示しています。デプロイに使用している IAM ユーザー（xxxxxxxxxxx）に必要な SSM のアクセス権限を追加する必要があります。
> 以下のような IAM ポリシーを追加しましょう：SSM Access PolicyClick to open codeこのポリシーを適用するには以下の手順を実行します：

> - AWS マネジメントコンソールで IAM サービスに移動
> - ユーザー xxxxxxxxxxx を選択
> - 「アクセス許可の追加」→「インラインポリシーの作成」を選択
> - JSON タブを選択し、上記のポリシーを貼り付け
> - ポリシーの名前を設定（例：SSMSessionManagementPolicy）して作成
> 
> また、EC2 インスタンス側にも適切な IAM ロールがアタッチされていることを確認してください。EC2 インスタ> ンスには少なくとも AWSSystemsManagerManagedInstanceCore ポリシーが必要です。
> これらの権限を追加した後、再度デプロイを試してみてください。

との回答。ただ、提示してもらったポリシーを AWS コンソール上で確認したところ、正しく設定されているようでした。


#### 試行錯誤中のソースや設定ファイルも共有する
見落としがあるかもしれないので、IAM ポリシーの JSON をそのまま見てもらいました。

> xxxxxxxxxxx ユーザのポリシー設定 JSON は下記になります。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:StartSession",
                "ssm:SendCommand"
            ],
            "Resource": [
                "arn:aws:ec2:ap-northeast-1:###############:instance/*",
                "arn:aws:ssm:ap-northeast-1:###############:document/SSM-SessionManagerRunShell"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:TerminateSession",
                "ssm:ResumeSession"
            ],
            "Resource": [
                "arn:aws:ssm:*:*:session/${aws:userid}-*"
            ]
        }
    ]
}
```
それに対する AI の回答

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6102/ff9d6843-c550-9b32-5271-03ead5b776dd.png)

最初の質問通り、本当に一緒に考えてくれてますね。一人作業感が無くなり、孤独から解放されてありがたいです。

ただ、実際のデプロイは成功せず、その後も何度かエラーとフィードバックを繰り返しました。

#### 間違えたら訂正

その後も何度かエラーが出るたびに AI に投げては修正を繰り返しました。同僚とか先輩だったら逃げられそうですが、AI は黙々と調べて回答してくれます。

> AI. このエラーはもう少し詳細な情報が必要そうですね。デバッグ情報を表示するために、ansible-playbook コマンドに -vvv オプションを追加して実行してみましょう。

> まだ同様のエラーが発生していますね。AWS SSM プラグインの設定をさらに詳細に調整する必要があります。

> このエラーは SSM Session Manager Plugin の実行可能ファイルが正しく認識されていない問題のようです。.gitlab-ci.yml の設定を修正して、Session Manager Plugin のインストール方法と環境変数の設定を調整しましょう。

> 同じエラーが続いていますね。SSM Plugin の設定をさらに詳細に見直してみましょう。

> エラーが S3 バケットの検証に関連していることが分かりました。AWS SSM プラグインの設定を修正して、S3 の使用を完全に無効化する必要があります。

> デバッグログから、SSM接続で実行可能ファイルの問題が発生していることがわかります。SSM Session Manager Pluginの設定をもう少し詳細に調整しましょう。

このやり取りで半日。流石に疲れてきました。

#### 煮詰まったら流れを変えてみる
SSM の設定はそこまで複雑じゃないはず。ちょっと流れを変えてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6102/63810e04-76e2-a8ea-53df-b2ca6bb5ba37.png)

AI が謝った！しかもこちらに相談してきてる！

ただ、それでもデプロイは失敗しているので何度か格闘。
その後、また IAM ポリシーの不備を指摘されたので、AI にフィードバックしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6102/b36354f7-1256-d1e3-bb23-d98f8ecfac70.png)

「あぁ、申し訳ありません。既存のポリシーを見落としてました。」

AI も見落としとかあるんか...。ちょっと愛着が湧いてきました。
その後、ポリシー内の変数が `${aws:userid}` ではなく `${aws.username}`を使用することに気づく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6102/61bd1f7f-ed97-f87a-e3fb-962d42731641.png)

これでうまく動きました！ありがとう！


## 振り返り
実際にはS3バケット名が共有されていなかったりパフォーマンス改善などでもっと多くのやり取りがありましたが、無事に運用を迎えることができました。

最後に AI 自身に振り返りをしてもらいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6102/0618819a-4d03-9c8a-942a-fafb361a1c01.png)

とても良い振り返りですね。次回どのように AI に質問すれば良いのか？ということがわかるので、最後の振り返りはオススメです。

## まとめ
と言うわけで、3行でまとめ。

- 目線を合わせて一緒に考えてもらう
- 間違いの指摘やエラーメッセージを具体的な共有する
- 煮詰まったら軌道修正

AIは完璧なツールではありませんが、適切なアプローチで活用することで、開発効率を大きく向上させることができます。まだAIの活用に躊躇している方も、これを機に一歩を踏み出してみてはいかがでしょうか。

私自身はインフラが本職ではなく、要件定義から設計、開発、デバッグ、DevOps までの一連の開発業務を担当していますが、そのほとんどで AI を活用しており、[QodeMerge](https://github.com/Codium-ai/pr-agent) によるレビューや Copilot によるテストの生成、MCP を使った運用問題調査など、チーム開発においても AI を積極的に導入しています。また、AI 以外でも [Playwright](https://playwright.dev) によるテストの自動化や、[PHPStan](https://phpstan.org/) によるコード保守の自動化など、品質向上のために常に最新の技術をキャッチアップしています。

そんな弊社で一緒に働きたいエンジニアを募集しています！

https://www.qnote.co.jp/company/recruit/


#### 最後に業務連絡
忙しい中、アドベントカレンダーを書いてくれた弊社メンバー。お疲れ様でした。
アウトプットは大事なので来年もよろしくね！