はじめに

アプリケーションのリリース作業は、手順が多くなるほどヒューマンエラーのリスクや作業負荷が高くなります。
特にEC2環境で手動デプロイをしていると、「毎回同じ操作を繰り返すのが面倒」「更新のたびにサーバーへログインするのが大変」と感じることも多いのではないでしょうか。
本記事では、AWS CodeDeploy(以降、CodeDeployと表記)を使って、EC2インスタンスへのデプロイ作業を自動化する方法をご紹介します。

対象読者

  • AWS上でアプリケーションの自動デプロイを試してみたい方
  • 初めてCodeDeployを使う方

前提条件

  • EC2インスタンスを使用していて接続できること(今回はAL2を使用しSSMで接続します)
  • S3バケットを作成・操作できるIAM権限があること

CodeDeployで自動化できる範囲

手作業でアプリをデプロイする場合、次のような手順になることが多いと思います。

  1. アプリ資材をS3にアップロード
  2. EC2にログインして、コマンドでS3からファイルをダウンロード
  3. ダウンロードしたファイルを展開し、フォルダを配置したりサービスを再起動したりする

これらの作業は毎回手動で行う必要があり、手間になるほかミスの原因にもなります。


CodeDeployを使えば、S3からのファイル取得やソフトウェアのインストール、サービスの再起動などを自動で行ってくれます。
つまり、S3にファイルを置いたあとの2,3の作業を自動化できるのが大きなポイントです。
この記事ではApacheをインストールし起動させるだけですが、実際の業務では、リリースに必要なファイルや手順がもっと複雑になることが多いため、CodeDeployのような自動化ツールの効果をより強く実感できるはずです。

手順

ステップ1. CodeDeployのサービスロールを作成

IAMのサービスページから[ロールを作成]を押下し、CodeDeployのサービスロールを作成します。

  • 信頼されたエンティティタイプ:AWSのサービス
  • サービス:CodeDeploy
  • ユースケース:CodeDeploy


ちなみにEC2のIAMロールには以下のポリシーが付与されている必要があります。

  • AmazonEC2RoleforAWSCodeDeploy
  • AWSCodeDeployFullAccess
  • AmazonS3ReadOnlyAccess

【参考】
CodeDeployのサービスロールを作成する
https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/getting-started-create-service-role.html

ステップ2. インスタンスにCodeDeployエージェントをインストール

ホームディレクトリに移動して、まずはRubyをインストールします。

$ cd /home/ec2-user
$ sudo yum install ruby

次にCodeDeployエージェントインストーラをダウンロードします。

$ wget https://bucket-name.s3.region-identifier.amazonaws.com/latest/install

bucket-nameはリージョンのリソースキットバケット名のことで、region-identifierはリージョンの識別子を指します。→ 各リージョンのバケット名と識別子

東京リージョンの場合は以下のコマンドを実行すればOKです。

$ wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install

最後にインストールファイルに実行権限を設定し、CodeDeployエージェントをインストールします。

$ sudo chmod +x ./install
$ sudo ./install auto

CodeDeployエージェントがインストールされていることを確認できればインストール完了です。

systemctl status codedeploy-agent

【参考】
コマンドラインを使用してCodeDeployエージェントをインストールする
https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/codedeploy-agent-operations-install-cli.html

ステップ3. appspec.yml ファイルを作成

任意のディレクトリに下記のappspec.ymlファイルを作成します。
今回は下記のようなファイル構成で作業をしていきます。

/ 
├── appspec.yml
└── scripts
    └── apache-install.sh

EC2/オンプレミスデプロイのAppSpecファイルは、ローカルデプロイを実行しない限りappspec.ymlという名前にする必要があるので注意してください。

version: 0.0
os: linux
files:
  - source: ./
    destination: /var/www/codedeploy
hooks:
  AfterInstall:
    - location: scripts/apache-install.sh
      runas: ec2-user
  • source:デプロイパッケージ内のコピー元のファイルやディレクトリを指定します。
  • destination:source で指定したファイルやディレクトリをコピー先の場所を指定します。
  • AfterInstall:インスタンスにファイルがコピーされた後に実行されるスクリプトやコマンドを指定します。
  • location:実行するスクリプトのパスを指定します。

デプロイ時にライフサイクルイベントを実行するにはフックセクションを使用します。
今回はApacheをインストールするので、 AfterInstall ライフサイクルイベントを使用しています。

そして、locationに指定したパスにApacheをインストール&起動させるスクリプトを作成し、appspecファイルとまとめてzip化しておきます。

# Apacheインストール&起動させるスクリプト

$ cat scripts/apache-install.sh 
#!/bin/bash

## Apacheをインストール
sudo yum update -y
sudo yum install -y httpd

## Apacheサービスを起動
sudo systemctl start httpd
sudo systemctl enable httpd

# zip化

$ zip -r codedeploy.zip .

【参考】
EC2/オンプレミスデプロイのAppSpecファイルの例
https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-appspec-file-example.html#appspec-file-example-server
AppSpecの「フック」セクション
https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-AppSpec-file-structure-hooks.html

ステップ4. S3バケットを作成して格納する

任意のバケット名でS3を作成し、ステップ3で作成したappspecファイルを含んだzipファイルを格納します。

ステップ5. CodeDeploy を設定

5-1:アプリケーションを作成

CodeDeployのサービスページからアプリケーションを作成します。
コンピューティングプラットフォームは、「EC2/オンプレミス」を選択します。

5-2:デプロイグループを作成

作成したアプリケーションを選択し、以下の内容でデプロイグループを作成します。

  • デプロイグループ名:任意の名前
  • サービスロール:ステップ1で作成したサービスロールを選択。
  • デプロイタイプ:インプレース
  • 環境設定:EC2インスタンスを選択し、作成したEC2を指定。
  • AWS Systems Manager を使用したエージェント設定:なし
  • デプロイ設定:CodeDeployDefault.AllAtOnce
  • Load balancer:無効

ステップ6. デプロイ

作成したデプロイグループを選択し、デプロイの作成を押下。
リビジョンタイプはS3を選択し、格納したzipファイルのS3 URIを貼り付けます。
その他はデフォルトのままでページ最下部のデプロイの作成を押下するとデプロイが開始されます。

デプロイが正常に実行されれば、デプロイステータスが成功と表示されます。

ステップ8. デプロイ確認

デプロイ前

[root@ip-10-0-12-195 ~]# ls /var/www/codedeploy
-bash: ls: /var/www/codedeploy: No such file or directory
[root@ip-10-0-12-195 ~]#
[root@ip-10-0-12-195 ~]# systemctl status httpd
Unit httpd.service could not be found.
[root@ip-10-0-12-195 ~]#

デプロイ後

[root@ip-10-0-12-195 ~]# ls /var/www/codedeploy
AppSpec.yml scripts
[root@ip-10-0-12-195 ~]#
[root@ip-10-0-12-195 ~]#
[root@ip-10-0-12-195 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2025-05-06 09:53:33 UTC; 1min 24s ago
Docs: man:httpd.service(8)
Main PID: 3363 (httpd)
Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/sec: 0 B/sec"
CGroup: /system.slice/httpd.service
├─3363 /usr/sbin/httpd -DFOREGROUND
├─3366 /usr/sbin/httpd -DFOREGROUND
├─3367 /usr/sbin/httpd -DFOREGROUND
├─3368 /usr/sbin/httpd -DFOREGROUND
├─3369 /usr/sbin/httpd -DFOREGROUND
└─3370 /usr/sbin/httpd -DFOREGROUND

May 06 09:53:33 ip-10-0-12-195.ap-northeast-1.compute.internal systemd[1]: Starting The Apache HTTP Server...
May 06 09:53:33 ip-10-0-12-195.ap-northeast-1.compute.internal systemd[1]: Started The Apache HTTP Server.
[root@ip-10-0-12-195 ~]#

指定したディレクトリにファイルが配置され、Apacheも問題なくインストール&起動しています。

おわりに

今回はCodeDeployを使って、Apacheのインストールと起動までを自動化する手順をご紹介しました。
シンプルな構成でしたが、実際の業務ではもっと複雑なファイル構成や前後処理が必要になる場面も多いため、自動化による恩恵はさらに大きくなります。
まずは小さな構成から始めて、少しずつ自動化の範囲を広げてみてはいかがでしょうか。