Claude Codeのチュートリアルを読んでトラブルシューティングを実践してみた
お疲れさまです。とーちです。
Claude Codeが最近注目されていますね。私もClaude Codeに入門したいと思ったので公式チュートリアルをやってみました。チュートリアルをやってみて気付いた点や調べた内容などをつらつらと書いてみます。
会話の継続機能
基本的な会話再開コマンド
claude
コマンドを実行することで、Claude Codeとの対話モードに入れますが、以下のコマンドで以前の会話を再開することができます。
claude --continue
:最新の会話を再開claude --resume
:以前の会話を選択して再開
--resume
オプションを使うと以下のように以前の会話を選択する画面が表示されます。
Modified Created # Messages Summary
❯ 1. 1m ago 1m ago 22 Claude Codeの概要を教えて
2. 2m ago 2m ago 8 Claude Code: AI-Powered Development Assistant
3. 6m ago 6m ago 4 Claude Code: AI-Powered Development Assistant
4. 10m ago 17m ago 49 AWS Bedrock Chat Tool Development
5. 11m ago 11m ago 48 AWS Bedrock Chat Tool Development
6. 1 day ago 1 day ago 13 AWS Bedrock Chat Tool Development Begins
7. 1 day ago 1 day ago 8 AWS Bedrock Chat Tool Development Begins
会話履歴の保存場所と注意点
なお、--resume
オプションで確認できる会話履歴ですが、ディレクトリごとに保持されます。以前の会話が見つからないときは現在のディレクトリを確認してみましょう。このことからもわかる通り、会話履歴はローカルマシンに保存されているとのことです。
# 履歴が3個以上表示されている
> claude --resume
Modified Created # Messages Summary
❯ 1. 1m ago 1m ago 2 claude --resumeをしたときの履歴が同じ端末なのにターミナルによって異なるよう...
2. 22h ago 22h ago 74 IPv6 VPC Setup with Enhanced Security Configs
3. 22h ago 23h ago 15 AWS Bedrock Claude Chat Tool Security Review
<中略>
> cd test
# ディレクトリを移動すると一つしか表示されない
> claude --resume
Modified Created # Messages Summary
❯ 1. 18h ago 18h ago 120 Terraform RDS Setup and Deletion in AWS VPC
ワンショット実行機能
--print
オプションは対話モードに入らずに指示に対して応答を一度だけ返すものになっています。例えば以下のような感じです。
> claude --print "Claude Codeの概要を教えて"
Claude Codeは、AnthropicのClaude AIを使ったインタラクティブなCLI(コマンドライン・インターフェース)ツールです。
主な特徴:
- ファイルの読み書き、編集、検索機能
- Bashコマンドの実行
- リアルタイムでのコード解析と修正
- Todo管理によるタスク追跡
- GitやGitHubとの統合
- Webコンテンツの取得と解析
ソフトウェア開発タスクを支援し、バグ修正、新機能実装、リファクタリング、コード説明などを効率的に行えます。
>
--continue
オプションとも組み合わせることができるので、以前のタスクについて指示を出したり、進捗を聞いたりすることもできます。
> claude --continue --print "作成した各ファイルの概要を教えて"
プロジェクトのファイル概要:
**README.md** - プロジェクトのドキュメント。AWS BedrockとClaude 3モデルを使用するチャットツールの説明とセットアップ手順
**package.json** - Node.jsプロジェクトの設定ファイル。AWS SDK依存関係とスクリプト定義
**bedrock-config.js** - AWS Bedrockクライアントの設定。リージョン、認証情報、モデルID定義
**chat.js** - メインのチャット機能クラス。対話型チャットインターフェースとBedrock API連携
**example.js** - 使用例デモンストレーション。基本的な使用方法、会話例、異なるモデル使用例
AWS Bedrockを使ったClaude AIチャットツールのプロジェクトです。
実践的な開発フロー体験
実施した流れ
チュートリアルに沿って以下の一連の流れをやってみました。
- コードをGitHubリポジトリからcloneする
- cloneしてきたコードを解説させる
- コードを修正させる
- テストさせる
- プルリクエストを作成させる
コードについては私が以前作成したTerraformコードを使用しました。
コードベースの理解
まずは解説させてみます。
> git clone https://github.com/ice1203/blog-terraform-ipv6-vpc
> cd blog-terraform-ipv6-vpc/
> claude
<中略>
> このディレクトリの中身を説明して
⏺ List(.)
⎿ Listed 15 paths (ctrl+r to expand)
⏺ Read(aqua.yaml)
⎿ Read 14 lines (ctrl+r to expand)
⏺ Read(envs/dev/main.tf)
⎿ Read 77 lines (ctrl+r to expand)
⏺ Read(modules/ec2/main.tf)
⎿ Read 118 lines (ctrl+r to expand)
⏺ このディレクトリはTerraformプロジェクトで、IPv6対応のVPCとEC2インスタンスを構築します:
構成:
- aqua.yaml: ツール管理設定(Terraform、git-secrets)
- envs/dev/: 開発環境設定
- modules/ec2/: EC2モジュール
主な機能:
- IPv6対応VPC(デュアルスタック構成)
- プライベートサブネットはIPv6専用
- パブリックサブネットはIPv4/IPv6併用
- Amazon Linux 2023のEC2インスタンス
- SSM管理対応のIAMロール
コードの中の特定の処理がどこで実装されているかも聞いてみました。行まで含めて見つけられています。
> セキュリティグループを作っているのはどの部分ですか?
⏺ セキュリティグループの作成は modules/ec2/main.tf:2-12 で行われています:
resource "aws_security_group" "main" {
name_prefix = var.prefix
description = "for ${var.prefix}-server"
vpc_id = var.vpc_id
tags = {
Name = "${var.prefix}-ec2-sg"
}
lifecycle {
create_before_destroy = true
}
}
ルールは別リソースで定義:
- IPv6アウトバウンドルール: modules/ec2/main.tf:15-24
- IPv6インバウンドルール: modules/ec2/main.tf:27-36
セキュリティ改善の提案と実装
セキュリティ関連での推奨事項を聞いてみます。
> このコードについてセキュリティ関連の推奨事項を教えて
⏺ このTerraformコードのセキュリティ推奨事項:
セキュリティグループ
- アウトバウンドルールが全開放(::/0、全ポート)されています。必要な通信のみに制限することを推奨
- インバウンドルールが定義されていないため、デフォルトで全拒否されているのは良い設定
EC2設定
- IMDSv2が有効(http_tokens = "required")- 良い設定
- EBS暗号化が有効 - 良い設定
- SSM管理用IAMロールのみアタッチ - 適切
- パブリックIP無効化 - 良い設定
ネットワーク
- IPv6専用プライベートサブネット使用 - モダンな設計
- フローログが無効 - 監査のため有効化推奨
改善提案
1. アウトバウンドルールを必要最小限に制限
2. VPCフローログの有効化(enable_flow_log = true)
3. インバウンドルールで管理アクセス用ポートを適切に制限
インバウンドルールについては、SSM Session Managerで接続する関係で修正不要なので、以下のように改善を指示しました。
> 以下の改善提案の内容を実施して
改善提案
1. アウトバウンドルールを必要最小限に制限
2. VPCフローログの有効化(enable_flow_log = true)
ファイル編集時の確認機能
ファイル修正の際には以下のように確認メッセージが出てきます。
Do you want to make this edit to main.tf?
❯ 1. Yes
2. Yes, and don't ask again this session (shift+tab)
3. No, and tell Claude what to do differently (esc)
Yes, and don't ask again this session
でこのセッションでは以降、確認メッセージを出さないようにできます。No, and tell Claude what to do differently
は、提示された修正案を適用せずに異なる指示をClaude Codeに出したいときに選択します。
操作モードの切り替え
なお、確認メッセージを出すかどうかは shift+tab
で切り替えられます。
╭──────────────────────────────────────────────────────────────────────────────────╮
│ > │
╰──────────────────────────────────────────────────────────────────────────────────╯
⏵⏵ auto-accept edits on (shift+tab to cycle) ⧉ In main.tf
↑ ここがauto-accept edits onになっているときはファイル編集時の確認が行われない
shift+tab
を押すと上記のauto-accept edits on
の箇所が切り替わります。plan mode on
と表示されているときはPlan modeになります。Plan modeは、実際の変更を行わずに計画のみを立てるモードで以下の特徴をもちます。
- 読み取り専用 - ファイルの読み込みや検索のみ可能
- 変更禁止 - ファイル編集、設定変更、コミットなどは実行されない(実行するときは確認メッセージを出す)
- 計画策定 - 何をするかの計画を立て、ユーザーの確認を求める
処理の中断と再編集
またClaude Codeがなにか処理を実行している最中は esc
を押すことで処理を中断し、別の指示を出すことができます。
esc
を2度押すと以前に送信した内容を編集して再度送信することもできます。
╭────────────────────────────────────────────────────────────────────────────────────────────╮
│ Jump to a previous message │
│ This will fork the conversation │
│ │
│ 7 > OK │
│ │
│ 8 > 修正案を提示 │
│ │
│ 9 > 高優先度(必須)を実施して │
│ │
│ 10 > OK │
│ │
│ 11 > 修正案を提示して │
│ │
│ 12 > 修正して │
│ │
│ ❯ 13 (current) │
╰────────────────────────────────────────────────────────────────────────────────────────────╯
↑/↓ to select · Enter to confirm · Tab/Esc to cancel
修正結果の確認
ということで一旦、下記の内容で修正してもらいました。
⏺ 修正完了しました:
1. VPCフローログ有効化 - ネットワークトラフィック監視が有効になりました
2. セキュリティグループアウトバウンドルール制限 - 必要最小限のポートのみ許可:
- HTTPS (443/tcp) - Session Manager通信・パッケージ更新
- DNS (53/tcp,udp) - 名前解決
- NTP (123/udp) - 時刻同期
セキュリティが大幅に強化されました。
テスト実行とプルリクエスト作成
テストも依頼してみます。
> テストしてほしい。aws権限はawsume ***で取得できます
<中略>
⏺ Bash(source ~/.zprofile && awsume *** && terraform plan -var="env=dev" -var="system=blog-ipv6" -var="ec2_key_pair_name=test-key")
<中略>
⏺ テスト成功しました。Terraformの実行計画が正常に生成され、以下のリソースが作成される予定です:
主要リソース:
- VPC(IPv6対応、blog-ipv6-dev-vpc)
- パブリック/プライベートサブネット
- EC2インスタンス(t3.micro、IPv6対応)
- セキュリティグループ(制限されたアウトバウンドルール)
- VPCフローログ(CloudWatch連携)
- Internet Gateway / Egress-Only Internet Gateway
- NAT Gateway
構成は問題なく、セキュリティ設定も適切に適用されています。
変更した内容でプルリクエストを作成してもらいます。
> 変更した内容でPRを作成して
<中略>
⏺ PRを作成しました: https://github.com/ice1203/blog-terraform-ipv6-vpc/pull/1
セキュリティ改善の内容:
- VPCフローログ有効化
- セキュリティグループのアウトバウンドルールを最小権限に制限(HTTPS、DNS、NTP)
- 全許可ルールを削除
途中でClaude Codeが実行していたコマンド等は省略しますが、ちゃんとプルリクエストを出してくれました。
エラーメッセージ診断とトラブルシューティング
RDS作成によるトラブルシューティング検証
個人的にすごいと思ったのがトラブルシューティング能力です。
とある事情で以下のような検証をする必要がありました。
- 暗号化なしでRDSを作成
- 使用しているIAMロールに暗号化なしの場合RDS作成不可とするIAMポリシーを付与
- 暗号化なしでRDSを作成しちゃんと拒否されることを確認
そこでRDSの作成を一からやってみてもらいました。
> 暗号化なしでTerraformを使って適当なRDSをVPCから作ってください。
<中略>
⏺ 暗号化なしのRDSをVPC内に作成するTerraformコードを作成しました。
作成したファイル:
- main.tf: VPC、サブネット、インターネットゲートウェイなどのインフラ設定
- rds.tf: RDSインスタンス、サブネットグループ、セキュリティグループの設定
主な設定:
- MySQL 8.0のdb.t3.microインスタンス
- プライベートサブネット内に配置
- 暗号化は無効(storage_encrypted = false)
- VPC内からのみアクセス可能
デプロイするには terraform init → terraform plan → terraform apply を実行してください。
さくっと作成してくれたので、とりあえず実行してみてもらうことにしました。
> 実行してみて
<中略>
⏺ Bash(terraform plan)
⎿ Error: ╷
│ Error: No valid credential sources found
│
│ with provider["registry.terraform.io/hashicorp/aws"],
│ on main.tf line 10, in provider "aws":
│ 10: provider "aws" {
│
│ Please see https://registry.terraform.io/providers/hashicorp/aws
│ for more information about providing credentials.
│
… +12 lines (ctrl+r to see all)
⏺ AWS認証情報が設定されていません。まず以下のいずれかの方法でAWS認証を設定してください:
1. AWS CLI設定:
aws configure
<後略>
AWS認証情報がないため、terraform planの実行に失敗したようです。私は普段awsumeコマンドを使って認証を通しているので、それで認証するように指示しました。
> 認証は`awsume -c ***` でできます
<中略>
⏺ planが成功しました!12個のリソースが作成予定です。続いて実際にデプロイ
してみます。
<中略>
⏺ 成功しました!暗号化なしのRDSインスタンスがVPC内に作成されました。
作成されたリソース:
- VPC(10.0.0.0/16)
- パブリックサブネット2つ(ap-northeast-1a, 1c)
- プライベートサブネット2つ(RDS用)
- RDSサブネットグループ
- セキュリティグループ(VPC内からのMySQL接続を許可)
- MySQL 8.0のRDSインスタンス(db.t3.micro、暗号化無効)
<後略>
最低限の指示で理解して、実行できているのがすごいです。
IAMポリシーによる制限の検証
このタイミングでTerraform実行に使っているIAMロールに 暗号化していないと rds:CreateDBInstance
をDenyするポリシーを付けました。 以下のようなポリシーを手で付けた形です。
{
"Sid": "DenyCreatingNonEncryptedDBInstance",
"Effect": "Deny",
"Action": ["rds:CreateDBInstance"],
"Resource": "*",
"Condition": {
"Bool": {
"rds:StorageEncrypted": false
},
"StringEquals": {
"rds:DatabaseEngine": ["postgres", "mysql", "..."]
}
}
}
この状態で再度暗号化を無効にしたRDSインスタンスを作ってもらいました。
> 別のRDSインスタンスを同じように暗号化を無効にした状態で作ってみてください
⏺ 別のRDSインスタンスを作成します。まず計画をタスクリストに追加します。
⎿ ☐ Add second RDS instance configuration
⎿ ☐ Add second RDS instance configuration
<中略>
⏺ Bash(awsume *** && terraform apply -auto-approve)
⎿ Error: [***] Role credentials will expire 2025-06-09 13:31:34
<中略>
⏺ AWS IAMの権限不足でRDSインスタンスの作成が拒否されました。権限設定を確認する必要がありますが、PostgreSQLセキュリティグループは
作成されました。
当然ながらIAMポリシーにより作成に失敗します。これについて何が原因で失敗したのかを調べてもらいました。(IAMポリシーを追加したことについては一度もClaude Code上では触れていない状態です)
詳細な原因分析
> 何が原因で作成できなかったのか分析して
⏺ RDS作成失敗の原因を分析します。
⏺ Bash(awsume *** && aws sts get-caller-identity)
<中略>
⏺ Bash(awsume *** && aws iam get-role-policy --role-name *** --policy-name AllowAll 2>/dev/null ||
<中略>
⏺ Bash(awsume *** && aws rds describe-db-instances --db-instance-identifier rds-mysql-instance --query
<中略>
⏺ Bash(awsume *** && aws rds create-db-instance --db-instance-identifier test-postgres --db-instance-class db.t3.micro
<中略>
⏺ Bash(awsume *** && aws iam simulate-principal-policy --policy-source-arn
<中略>
トラブルシューティングの一環とはいえ、rds create-db-instance
をしているのがなかなか強気ですね。権限の与えすぎには注意かなと思ったりしました。また、aws iam simulate-principal-policy
というコマンドは初めて見ました。生成AIのほうが私よりもAWSに詳しいようです。
RDS作成失敗の原因分析結果:
<中略>
問題:
1. 明示的な拒否ポリシー:explicit deny in an identity-based policy
2. RDS作成権限なし:rds:CreateDBInstanceアクションが拒否されている
3. 最初のRDSは作成済み:MySQL インスタンスは既に存在していた
なぜ最初のRDSは作成できたのか:
- 既存のインスタンスをTerraformにインポートしただけ
- 実際には作成していない
権限を確認・修正するか、管理者に権限付与を依頼する必要があります。
上記のとおり、IAMのエラーであることまで突き止めてくれましたが、「なぜ最初のRDSは作成できたのか」の部分をもう少し踏み込んでほしくなり、追加で以下の指示を出してみました。
さらなる深掘り分析
> 分析を継続して
⏺ 分析を継続します。
⎿ ☐ Analyze RDS creation failure causes
<中略>
⏺ Bash(awsume *** && aws rds describe-db-instances --query 'DBInstances[?contains(DBInstanceIdentifier,
`rds-mysql`)].{ID:DBInstanceIdentifier,Created:Instan…)
⎿ [
{
"ID": "rds-mysql-instance",
"Created": "2025-06-09T02:17:33.428000+00:00",
… +4 lines (ctrl+r to expand)
⏺ Bash(awsume *** && aws iam get-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --query
'Policy.{PolicyName:PolicyName,CreateDate:CreateDate…)
⎿ {
"PolicyName": "AdministratorAccess",
"CreateDate": "2015-02-06T18:39:46+00:00"
}
[***] Role credentials will expire 2025-06-09 13:31:34
⎿ ☒ Analyze RDS creation failure causes
どうやら、RDSインスタンス作成時間やIAMポリシーの作成時間を調べているようです。
最終的に以下の結論を出してくれました。根本原因を発見しているのもすごいのですが、「推測される経緯」という部分で完全にエラーとなった経緯を当てられているのがすごいです。
⏺ RDS作成失敗の詳細分析結果
根本原因発見
IAMポリシー rds-deny が暗号化なしRDS作成を明示的に拒否
{
"Sid": "DenyCreatingNonEncryptedDBInstance",
"Effect": "Deny",
"Action": ["rds:CreateDBInstance"],
"Resource": "*",
"Condition": {
"Bool": {
"rds:StorageEncrypted": false
},
"StringEquals": {
"rds:DatabaseEngine": ["postgres", "mysql", "..."]
}
}
}
権限の矛盾
1. AdministratorAccess:全権限を許可
2. rds-deny:暗号化なしRDS作成を明示的拒否
→ Denyが優先されるため、暗号化なしRDS作成は不可能
既存MySQLインスタンスの謎
- 作成日時:2025-06-09T02:17:33(今日の朝)
- 暗号化:false
- 状況:ポリシー作成(02:03)後に作成されている
推測される経緯:
1. 最初にMySQLインスタンス作成(ポリシー適用前?)
2. rds-denyポリシーが後から適用された
3. 現在は新規暗号化なしRDS作成が不可能
解決策
4. 暗号化を有効化:storage_encrypted = trueに変更5. ポリシー除外:管理者にrds-denyポリシーの一時解除を依頼
6. 例外条件追加:特定条件下での暗号化なし作成を許可
現在の設定では、組織のセキュリティポリシーにより暗号化なしDBの新規作成が禁止されています。
上記により、エラーメッセージの診断やトラブルシューティングにも役立ちそうなことが伝わるかなと思います。
まとめ
長くなってきたのでここで一旦切ろうと思います。チュートリアルの項目としてはまだまだあるので、記事にできそうなら記事にしようと思います。
Claude Codeすごいですね。トラブルシューティング能力の高さは特に驚きでした。またgit関連の操作も少し複雑な操作だと私はすぐにコマンドを忘れてしまうので、これからはClaude CodeにGit操作周りはお任せしようかなと思ってしまいました。
以上、とーちでした。