---
title: "appspec.ymlとは？CodeDeployのAppSpecファイルの書き方・記述例・エラー対処"
url: "https://www.issoh.co.jp/tech/details/7564/"
published: 2025-07-04
updated: 2026-07-15
categories: ["AWS"]
publisher: "株式会社一創"
---

# appspec.ymlとは？CodeDeployのAppSpecファイルの書き方・記述例・エラー対処

`appspec.yml`（AppSpecファイル）は、AWS CodeDeployがデプロイの手順を読み取るための設計図です。「どのファイルをどこへ置くか」「各段階でどのスクリプトを実行するか」をこの1ファイルで宣言し、CodeDeployはこれに従ってデプロイを進めます。ところが同じCodeDeployでも、EC2/オンプレミス・AWS Lambda・Amazon ECSでは書くべきセクションもファイル名の制約も異なり、ここを取り違えるとデプロイが起動時に失敗します。本記事ではappspec.ymlの役割から基本構造、ライフサイクルフック、3プラットフォーム別の記述例、配置とインデントの落とし穴、よくあるエラーの対処までをAWS公式仕様に沿って整理します。

## まとめ：appspec.ymlの要点

- **役割**：CodeDeployがデプロイ手順を読むファイル。`version` は現状 `0.0` のみ指定可。
- **ファイル名と場所**：EC2/オンプレミスは **YAML形式・ファイル名 appspec.yml・リビジョンのルート直下**が必須。外すとデプロイが失敗する。Lambda・ECSはYAML/JSONどちらでも可。
- **構造はプラットフォームで違う**：EC2は `os/files/permissions/hooks`、Lambda・ECSは `resources/hooks`。
- **hooks**：EC2はライフサイクルイベントごとに**スクリプト**を実行、Lambda・ECSは**Lambda検証関数**を実行する。
- **つまずきやすい点**：インデント（スペース数）とファイル配置。YAMLのスペーシング仕様を外すと原因の分かりにくいエラーになる。

以降で、各プラットフォームの構造・フック・記述例・エラー対処を順に見ていきます。

## appspec.ymlとは｜CodeDeployにおける役割と読み込みタイミング

appspec.ymlは、CodeDeployがアプリケーションリビジョン（デプロイ対象一式をまとめたzip/tarなどのアーカイブ）内で最初に読み取る管理ファイルです。デプロイ対象のコードと一緒にリビジョンへ同梱し、S3バケットまたはGitリポジトリへアップロードして使います。CodeDeployはこのファイルの記述だけを頼りに「何を」「どの順で」実行するかを決めるため、appspec.ymlの内容がそのままデプロイの挙動になります。

### appspec.ymlが読み込まれるタイミング

EC2/オンプレミスのデプロイでは、CodeDeployエージェントが `DownloadBundle` イベントでリビジョンをインスタンスへ展開し、その後の各ライフサイクルイベント（`BeforeInstall` や `AfterInstall` など）でappspec.ymlの `hooks` を参照してスクリプトを起動します。`files` セクションは `Install` イベントでの配置内容を決めます。なお `ApplicationStop` だけは例外で、**今回のリビジョンではなく前回成功したリビジョンのappspec.ymlとスクリプト**が使われます。インスタンスへの初回デプロイ時はまだ前回分が存在しないため、`ApplicationStop` は実行されません。

### appspec.yml・appspec.yaml・JSONの違い（混同しやすい命名）

拡張子と形式の許容範囲はプラットフォームで異なります。**EC2/オンプレミスはYAML形式で、ファイル名は `appspec.yml` でなければなりません**（`appspec.yaml` やJSONは不可）。一方でLambda・ECSのAppSpecファイルはYAML/JSONのどちらでもよく、CodeDeployコンソールに内容を直接入力することもできます。「appspec.yaml でも動くはず」という思い込みはEC2デプロイで失敗の原因になるため、EC2では拡張子まで含めて `appspec.yml` に固定してください。

## プラットフォーム別のappspec.yml基本構造

appspec.ymlのトップレベルセクションは、デプロイ先のコンピューティングプラットフォームで変わります。`version` は3プラットフォーム共通で `0.0` を指定します（CodeDeployが予約している値で、これ以外は使えません）。

| セクション       | EC2/オンプレミス        | AWS Lambda   | Amazon ECS |
| ----------- | ----------------- | ------------ | ---------- |
| version     | 必須(0.0)           | 必須(0.0)      | 必須(0.0)    |
| os          | 必須(linux/windows) | ―            | ―          |
| files       | あり                | ―            | ―          |
| permissions | あり(Linux系のみ)      | ―            | ―          |
| resources   | ―                 | あり(Lambda関数) | あり(タスク定義等) |
| hooks       | スクリプト             | Lambda検証関数   | Lambda検証関数 |

### EC2/オンプレミス：os・files・permissions・hooks

`os` にはデプロイ先の `linux` または `windows` を指定します。`files` は `Install` イベントでインスタンスへコピーするファイルの `source`（リビジョン内のパス）と `destination`（配置先）の対応を書きます。`permissions` はコピーしたファイルの所有者やモードを指定する任意セクションで、Amazon Linux・Ubuntu Server・RHELのみが対象です。`hooks` には各ライフサイクルイベントで動かすスクリプトを紐づけます。

### AWS Lambda：resources・hooks

Lambdaデプロイでは `os` や `files` は使いません。`Resources` にデプロイするLambda関数のバージョン（名前・エイリアス・現行/目標バージョン）を記述し、`Hooks` にトラフィック切り替え前後で走らせる検証用Lambda関数を指定します。利用できるフックは `BeforeAllowTraffic` と `AfterAllowTraffic` の2つだけです。Lambda・ECSのキーは `Resources`・`Hooks` と大文字で始まる点に注意してください（EC2の `files`・`hooks` は小文字。`version` のみ全プラットフォーム共通で小文字です）。

### Amazon ECS：resources・hooks

ECSデプロイでは `Resources` にタスク定義（`TaskDefinition` のARN）や、トラフィックを切り替えるコンテナ名・ポート（`LoadBalancerInfo`）、必要に応じてプラットフォームバージョン・サブネット・セキュリティグループを記述します。`Hooks` にはデプロイ検証用のLambda関数を指定します。ECSのAppSpecファイル自体はYAMLでもJSONでも記述でき、書き方の詳細は[AWS ECSとは？コンテナの仕組み・起動タイプ・料金・EKSとの違い](/tech/details/3870/)の運用と合わせて設計すると分かりやすくなります。

## ライフサイクルイベントフックの一覧と実行順序

`hooks` はappspec.ymlの中心です。CodeDeployはデプロイを一連のライフサイクルイベントに分割し、各イベントに紐づけたスクリプト（EC2）または検証関数（Lambda/ECS）を実行します。フックを書かなかったイベントでは何も実行されません。

### EC2/オンプレミスのフックと実行順序

インプレースデプロイでは、フックは次の順で実行されます。

```
ApplicationStop
DownloadBundle        # 予約（スクリプト不可）
BeforeInstall
Install               # 予約（スクリプト不可）
AfterInstall
ApplicationStart
ValidateService
# ↓ デプロイグループにロードバランサーがある場合のみ
BeforeBlockTraffic
BlockTraffic          # 予約（スクリプト不可）
AfterBlockTraffic
BeforeAllowTraffic
AllowTraffic          # 予約（スクリプト不可）
AfterAllowTraffic
```

`DownloadBundle`・`Install`・`BlockTraffic`・`AllowTraffic` はCodeDeployエージェント専用の予約イベントで、スクリプトを割り当てられません。トラフィックの遮断・許可に関する6つのフックは、デプロイグループにClassic/Application/Network Load Balancerを指定している場合にだけ実行されます。`ApplicationStop`・`ValidateService` などの主要イベントは、それぞれ「前バージョンの安全な停止」「デプロイ後の疎通確認」といった役割で使います。

### フックエントリの書き方（location・timeout・runas）

各フックにはスクリプトを配列で複数指定できます。エントリの要素は次の3つです。

- **location**（必須）：実行するスクリプトのパス。**リビジョンのルートからの相対パス**で書く。
- **timeout**（任意）：スクリプトの制限時間（秒）。既定は3600秒で、これが1イベントあたりの上限。1イベント内の全スクリプトの合計がこれを超えるとデプロイは失敗する。
- **runas**（任意）：スクリプトを実行するユーザー。Amazon Linux・Ubuntu Serverのみ有効。CodeDeployはパスワードを保持しないため、パスワードが必要なユーザーには成りすませない。

### Lambda・ECSのフック

Lambda・ECSの `hooks` はスクリプトではなく**Lambda検証関数**を指定します。関数はデプロイの妥当性を検査し、`putLifecycleEventHookExecutionStatus` でCodeDeployへ `Succeeded` または `Failed` を通知します。この通知が1時間以内に返らないと、そのデプロイは失敗と見なされます。ECSで使えるフックは `BeforeInstall`・`AfterInstall`・`AfterAllowTestTraffic`・`BeforeAllowTraffic`・`AfterAllowTraffic` の5つです。いずれかの検証関数が失敗（`Failed` を通知）すると、デプロイは停止し直前の安定したタスクセットへロールバックされます。

## appspec.ymlの記述例（EC2・Lambda・ECS）

### EC2/オンプレミスの記述例

Linuxインスタンスへ静的コンテンツを配置し、インストール前後とアプリ起動・停止でスクリプトを実行する例です。`files` でソースと配置先を対応させ、`hooks` で各段階のスクリプトを指定します。

```
version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/html/WordPress
hooks:
  BeforeInstall:
    - location: scripts/install_dependencies.sh
      timeout: 300
      runas: root
  AfterInstall:
    - location: scripts/change_permissions.sh
      timeout: 300
      runas: root
  ApplicationStart:
    - location: scripts/start_server.sh
  ApplicationStop:
    - location: scripts/stop_server.sh
      timeout: 300
      runas: root
```

### AWS Lambdaの記述例

Lambda関数のバージョンを切り替え、トラフィック移行の前後で検証関数を走らせる例です。`os` や `files` は登場しません。

```
version: 0.0
Resources:
  - myLambdaFunction:
      Type: AWS::Lambda::Function
      Properties:
        Name: "myLambdaFunction"
        Alias: "myLambdaFunctionAlias"
        CurrentVersion: "1"
        TargetVersion: "2"
Hooks:
  - BeforeAllowTraffic: "BeforeTrafficHook"
  - AfterAllowTraffic: "AfterTrafficHook"
```

### Amazon ECSの記述例

タスク定義とロードバランサー先のコンテナ・ポートを指定し、検証用フックを紐づける例です。

```
version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/my-task:1"
        LoadBalancerInfo:
          ContainerName: "web"
          ContainerPort: 80
Hooks:
  - BeforeInstall: "BeforeInstallHook"
  - AfterAllowTestTraffic: "TestTrafficHook"
  - AfterAllowTraffic: "AfterTrafficHook"
```

## YAMLインデントと配置場所の落とし穴

appspec.ymlのトラブルは、記述内容そのものより「置き場所」と「空白」に起因することが多いです。ここは競合記事でも軽く流されがちですが、失敗を最初に踏むポイントなので押さえておきます。

### appspec.ymlはリビジョンのルート直下に置く

EC2/オンプレミスでは、appspec.ymlをリビジョン（デプロイするソース一式）の**ルートディレクトリの直下**に置かなければなりません。サブフォルダに入れたり、ファイル名を `appspec.yaml` にしたりすると、CodeDeployがファイルを認識できずデプロイに失敗します。`hooks` の `location` に書くスクリプトのパスも、このルートからの相対パスとして解決される点に注意してください。

### スペーシング（インデント）の仕様

YAMLはインデントで階層を表すため、スペースの数がずれると意味が変わります。CodeDeployはスペーシングが正しくないと原因を特定しにくいエラーを出します。公式が示す基本ルールは次のとおりです。

- `version:` や `os:` のコロンと値の間はスペース1つ。
- `files` や `hooks` 配下の各項目はスペース2つ＋ハイフンで始める。
- `timeout` や `runas` などのプロパティはさらに深くインデントする。
- **タブは使わずスペースで統一**し、YAMLの文字列は原則クォートで囲まない。

手元でインデントを崩さないよう、YAML対応エディタのバリデーションを有効にしておくと、デプロイ実行前に構文エラーを潰せます。

## appspec.ymlでよくあるエラーと対処法

### 「AppSpecファイルが見つからない・内容が不正」

最も多いのが配置とファイル名の問題です。EC2/オンプレミスでは、リビジョンのルートに `appspec.yml`（この名前・この拡張子）が存在するかをまず確認します。ビルド成果物をzip化する際に階層が1つ深くなり、appspec.ymlがサブフォルダに潜っているケースが典型です。

### ApplicationStopで失敗する

`ApplicationStop` は前回成功したリビジョンのスクリプトを実行するため、**過去に配置した停止スクリプトが壊れていると、今回のデプロイがこの段階で止まります**。前回のスクリプトを修正できない場合は、該当インスタンスの直近成功リビジョン情報をリセットするなどの対処が必要です。初回デプロイでは `ApplicationStop` は実行されない点も踏まえて切り分けます。

### フックスクリプトの失敗・タイムアウト

スクリプトが0以外の終了コードを返す、または `timeout` を超えるとそのフックは失敗し、デプロイが止まります。スクリプト内で参照するファイルは相対パスの解決基準（エージェントの作業ディレクトリ）に依存するため、`DEPLOYMENT_ID` や `DEPLOYMENT_GROUP_ID` などの環境変数を使った絶対パス参照にすると安定します。原因はインスタンス上のCodeDeployエージェントのログで確認できます。

### 「too many individual instances failed deployment…」

このメッセージはデプロイグループ全体のヘルス条件を満たせなかったときに出ます。個々のインスタンスでフックスクリプトが失敗しているのが起点であることが多いため、まずは各インスタンスでどのライフサイクルイベントが失敗したかを特定し、そのフックのスクリプトとログを追うのが近道です。

## CI/CDパイプラインでのappspec.ymlの位置づけ

appspec.ymlは単体で使うより、CI/CDパイプラインの一部として運用するのが一般的です。ビルド成果物とappspec.ymlをまとめてリビジョン（zip/tar）にし、S3またはGitHubへ配置してCodeDeployが取得します。[AWS CodePipelineとは何か？その基本的な概要と機能について](/tech/details/3107/)で組んだパイプラインからCodeDeployのデプロイステージを呼び出す構成が定番で、ビルドを[GitHub Actionsでビルド・自動テストを設定する方法](/tech/details/2497/)や各種CIツールに任せ、appspec.ymlはリポジトリで管理します。CIツールの選定は[GitHubとGitLabの違い（CI/CD・セキュリティで選ぶ判断基準）](/tech/details/4219/)も参考にしてください。

## よくある質問

### appspec.ymlとappspec.yamlはどちらが正しいですか？

EC2/オンプレミスのデプロイでは `appspec.yml` でなければならず、`appspec.yaml` やJSONは認識されません。Lambda・ECSではYAML/JSONのどちらでも記述でき、コンソールへの直接入力も可能です。

### appspec.ymlはどこに置けばよいですか？

EC2/オンプレミスでは、デプロイするソース一式（リビジョン）のルートディレクトリの直下に置きます。サブフォルダに入れるとデプロイが失敗します。

### hooksセクションは必須ですか？

必須ではありません。スクリプトやLambda検証関数を実行する場合にのみ記述します。フックを書かなければ、そのイベントでは何も実行されません。

### Lambda用のappspec.ymlにosやfilesは必要ですか？

不要です。Lambda（およびECS）では `resources` と `hooks` を使い、`os`・`files`・`permissions` はEC2/オンプレミス専用のセクションです。

### versionに0.0以外の値は指定できますか？

できません。`version` はCodeDeployが予約しており、現状は `0.0` のみが許可された値です。将来の拡張用に確保されている値なので変更しないでください。

## 関連記事

- [AWS CodePipelineとは何か？その基本的な概要と機能について](/tech/details/3107/)
- [AWS ECSとは？コンテナの仕組み・起動タイプ・料金・EKSとの違い【2026年版】](/tech/details/3870/)
- [GitHub Actionsでビルド・自動テストを設定する方法｜CI/CDワークフローの作り方](/tech/details/2497/)
- [GitHubとGitLabの違いを比較｜CI/CD・セキュリティで選ぶ判断基準](/tech/details/4219/)

---

出典: [appspec.ymlとは？CodeDeployのAppSpecファイルの書き方・記述例・エラー対処](<https://www.issoh.co.jp/tech/details/7564/>)（株式会社一創）
