Amazon Lightsail上でソースコードの更新作業をいちいちしたくなかったので自動化した振り返り
TL;DR
目的
- Amazon Lightsailのインスタンスの作成とセットアップを行う。
- ローカル環境からGitHubにPushしたソースコードの変更を、AWS CodeDeployとAWS CodePipelineを使用し、作成したAmazon Lightsailのインスタンス上に自動で反映する。
方針
以下3記事の副読本的な位置付けになります。
詰まった箇所、違うことをした箇所を補足します。
基本的な流れは以下の記事に沿って行いました。
インスタンスを立てた後の初期設定については以下の記事に沿って行いました。
CodeDeploy・CodePipelineのセットアップは以下の記事に沿って行いました。
構成
ソースコード
モチベーション
- ホームページをDjangoかHTMLかなんかで作ってAWSに乗せて公開したいと思った
- コードを書き換える度にいちいち変更を適用する作業をするのが面倒だと思った。
- GitHubにPushしたら自動でAWS上に変更を反映したい(CI/CD的な?)とざっくり思った。
想定
- GitHubアカウントを作成済み
- AWSアカウントを作成済み
- AWS CLIをローカル環境にインストール済み
(インストール方法について前回の記事で少しだけ触れています)
1. ロールを作成する
今回の目的に則した適切な権限を持つロールを作成します。
しばらく参考記事の流れ通りに進めます。
- AWSのコンソールにサインインし、IAMコンソール( https://console.aws.amazon.com/iam/ )を開きます。
- 左側のダッシュボードから[ロール]を選択し、[ロールの作成]をクリックします。
- ロールを使用するサービスを選択します。
- 信頼されたエンティティの種類を選択: AWS サービス
- ユースケースの選択: CodeDeploy
- 下部のリストからユースケースを選択し、[次のステップ:アクセス権限]をクリックします。
- ユースケースの選択(下部): CodeDeploy
- [次のステップ:タグ]をクリックし、[次のステップ:確認]をクリックします。
- [ロール名] を入力します(例: CodeDeployServiceRole)。
- [ロールの作成]をクリックします。
2. S3バケットを作成する
GitHubにPushを行った際、CodeDeployによって以下の物がS3バケット[1]に保存されます。
- ソースコード
- インストール・更新に必要なスクリプトを含む圧縮ファイル
ここではそのS3バケットを作成します。
参考記事の流れ通りに進めます。
- AWSのコンソールにサインインし、IAMコンソール( https://console.aws.amazon.com/s3/ )を開き、[バケットを作成]をクリックします。
- [バケット名]を入力します。
- バケット名はグローバルで一意でなければなりません。
- 命名規則を守って入力して下さい。
- バケット名が決まったら、バケット名をメモに控えます。
- [パブリックアクセスをすべてブロック]にチェックが入っていることを確認します。
- [バケットを作成]をクリックします。
3. IAMポリシーを作成する
AWS CodeDeployの実行時、S3バケットの読み取りのみを許可するIAMポリシー[2]を作成します。
参考記事の流れ通りに進めます。
- AWSのコンソールにサインインし、IAMコンソール( https://console.aws.amazon.com/iam/ )を開きます。
- 左側のダッシュボードから[ポリシー]を選択し、[ポリシーを作成]をクリックします。
- [JSON]タブをクリックします。
- 以下のコードで上書きします。
- 「<S3 Bucket Name>」の部分は、「手順2-2:S3バケットを作成する」で控えたS3バケットの名前に書き換えます。
- 参考記事と同じコードを以下記載します。
JSON{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*" ], "Resource": [ "arn:aws:s3:::<S3 Bucket Name>/*" ] } ] }
- [次のステップ:タグ]をクリックし、[次のステップ:確認]をクリックします。
- ポリシーの[名前]を入力します(例: CodeDeployS3BucketPolicy)。
- [ポリシーの作成]をクリックします。
4. IAMユーザを作成する
CodeDeployを実行可能なIAMユーザを作成します。
「手順3:IAMポリシーを作成する」で作成したIAMポリシーをアタッチします。
参考記事の流れ通りに進めます。
- AWSのコンソールにサインインし、IAMコンソール( https://console.aws.amazon.com/iam/ )を開きます。
- 左側のダッシュボードから[ユーザー]を選択し、[ユーザーを追加]をクリックします。
- [ユーザー名]を入力します(例: LightSailCodeDeployUser)。
[AWS 認証タイプの選択]で[アクセスキー - プログラムによるアクセス]にチェックを入れます。
[次のステップ:アクセス権限]をクリックします。 - [アクセス許可の設定]は[既存のポリシーを直接アタッチ]を選択します。
ポリシーの一覧から、先ほど作成したポリシー(CodeDeployS3BucketPolicy)にチェックを入れます。検索ボックスに「CodeDeployS3BucketPolicy」を入力するとすぐ見つかると思います。 - [次のステップ:タグ]をクリックし、[次のステップ:確認]をクリックし、[ユーザーの作成]をクリックします。
- 「アクセスキーID」「シークレットアクセスキー」をメモに控えます。
- [閉じる]をクリックします。
- 今作成したユーザをクリックします。
[ユーザーのARN]をメモに控えます。
5. Lightsailインスタンスを作成しセットアップを行う
これまで参照してきた参考記事とはここでお別れしたいと思います(どうもありがとう)。
ここからは以下の記事も参考にしながら、Lightsailインスタンスの作成・セットアップを行います。
1. インスタンスを作成
- AWSのコンソールにサインインし、Lightsailのホーム( https://lightsail.aws.amazon.com/ )を開きます。
- [インスタンスの作成]をクリックします。
- 作成したいリージョンになっていることを確認してください。
作成したいイメージを選択してください。
ここでは「Linux/Unix」「OS Only > Amazon Linux 2」を選択しています。
- インスタンスのプランを選択します。
お試しで立てていることもあり、一番左の$3.5USDを選択しました(クラウド破産も怖いので)。
- [インスタンスを確認]にインスタンス名を入力し、[インスタンスを作成]をクリックします。
- インスタンスが「実行中」となれば無事作成できています。おめでとうございます!
2. インスタンスのセットアップ
ここからは参考記事に沿ってセットアップを行います。
- 先ほど作成したインスタンスのターミナルマーク(?)をクリックします。
- パッケージのアップグレードを行います。AWS Web console
[ec2-user@ip-172-xxx-xxx-xxx ~]$ sudo yum update -y ... Complete!
- ユーザを作成します。
- rootに切り替えてパスワードを設定します。AWS Web console
[ec2-user@ip-172-xxx-xxx-xxx ~]$ sudo su - [root@ip-172-xxx-xxx-xxx ~]# passwd Changing password for user root. New password: Retype new password: passwd: all authentication tokens updated successfully.
- 新しいユーザを作成します。
(以降「satory074」の部分は任意のユーザ名に読み替えてください)AWS Web console[root@ip-172-xxx-xxx-xxx ~]# adduser satory074
- パスワードを設定します。AWS Web console
[root@ip-172-xxx-xxx-xxx ~]# passwd satory074 Changing password for user satory074. New password: Retype new password: passwd: all authentication tokens updated successfully.
- 作成したユーザにsudoの権限を付与します。AWS Web console
[root@ip-172-xxx-xxx-xxx ~]# usermod -G wheel satory074
- 作成したユーザがsudo権限を持つgroupに入っていることを確認します。AWS Web console
[root@ip-172-xxx-xxx-xxx ~]# grep wheel /etc/group wheel:x:10:ec2-user,satory074
- sudo権限が付いていることをidコマンドで確認します。
(パスワードを求められるので入力します)AWS Web Console[root@ip-172-xxx-xxx-xxx ~]# su - satory074 [satory074@ip-172-xxx-xxx-xxx ~]$ sudo id We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things: #1) Respect the privacy of others. #2) Think before you type. #3) With great power comes great responsibility. [sudo] password for satory074: uid=0(root) gid=0(root) groups=0(root)
- rootに切り替えてパスワードを設定します。
- 作成したユーザのSSH設定を行います。
- /etc/sudoers.d/cloud-initに設定を記入します。AWS Web Console
[ec2-user@ip-172-xxx-xxx-xxx ~]$ su - satory074 [satory074@ip-172-xxx-xxx-xxx ~]$ echo 'username ALL = NOPASSWD: ALL' | sudo tee --append /etc/sudoers.d/cloud-init username ALL = NOPASSWD: ALL
- ec2-userのauthorized_keysを作成したユーザのの.sshディレクトリにコピーします。AWS Web Console
[satory074@ip-172-xxx-xxx-xxx ~]$ sudo rsync -a /home/ec2-user/.ssh/authorized_keys ~/.ssh/
- パーミッションを変更します。AWS Web Console
[satory074@ip-172-xxx-xxx-xxx ~]$ sudo chown -R satory074:satory074 ~/.ssh [satory074@ip-172-xxx-xxx-xxx ~]$ sudo chmod -R go-rwx ~/.ssh
- パーミッションを確認します。AWS Web Console
[satory074@ip-172-26-15-163 ~]$ sudo ls -la ~/.ssh/ total 4 drwx------ 2 satory074 satory074 29 Sep 22 08:04 . drwx------ 3 satory074 satory074 74 Sep 22 08:04 .. -rw------- 1 satory074 satory074 394 Sep 22 07:27 authorized_keys
- /etc/sudoers.d/cloud-initに設定を記入します。
- ローカルから作成したユーザでSSH接続
ec2-userを削除したいのですが、ブラウザのターミナルではデフォルトでec2-userでログインするため、削除ができません。
(本当はできるのかもしれない...)
ので、ローカルから作成したユーザでSSH接続し、ec2-userの削除をします。- Lightsailのホームから、「アカウント > アカウント」をクリックします。
- 以下の情報を確認してください。
- IPアドレス
- サインインに使用しているキーペア
- [SSHキー]タブをクリックし、[ダウンロード]をクリックし、デフォルトのSSHペアキーをダウンロード
(サインインに使用しているキーペアがデフォルト以外だった場合、以降キーペアの部分を読み変えてください)
- 「LightsailDefaultKey-<RegionName>.pem」という名前のSSHペアキーがダウンロードされたかと思います。
(ここではLightsailDefaultKey-ap-northeast-1.pem)
ダウンロードしたSSHペアキーを.sshディレクトリに移動し、パーミッションを変更します。Local Terminalsatory074@MacBook-Pro ~ $ mv ~/Downloads/LightsailDefaultKey-ap-northeast-1.pem ~/.ssh/ satory074@MacBook-Pro ~ $ sudo chmod 400 ~/.ssh/LightsailDefaultKey-ap-northeast-1.pem
- configにssh接続情報を追記します。
<>の部分は書き換えて追記してください。Local Terminalsatory074@MacBook-Pro ~ $ vim ~/.ssh/config
~/.ssh/configHost LightsailInstance HostName <HostName> Port 22 IdentityFile ~/.ssh/LightsailDefaultKey-ap-northeast-1.pem User <User>
項目 内容 備考 Host 接続時の名前 「ssh LightsailInstance」とコマンドを打って接続することになります。 HostName 接続先IPアドレス 「手順5-2:インスタンスのセットアップ」で確認したIPアドレス Port ポート 22 IdentityFile SSHペアキー 先ほどダウンロードしたペアキーを指定 User ユーザ名 「手順5-2:インスタンスのセットアップ」で作成したLinuxのユーザ名(ここではsatory074) - Lightsailに接続します。
問題がなければ接続成功です。おめでとうございます。Local Terminalsatory074@MacBook-Pro ~ $ ssh LightsailInstance Last login: Wed Sep 22 09:57:03 2021 __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/
- Lightsailのホームから、「アカウント > アカウント」をクリックします。
- Lightsailに接続してec2-userを削除します。Local Trminal
satory074@MacBook-Pro ~ $ ssh LightsailInstance
Lightsail Terminal[satory074@ip-172-xxx-xxx-xxx ~]$ sudo userdel ec2-user userdel: user ec2-user is currently used by process 3355 [satory074@ip-172-xxx-xxx-xxx ~]$ sudo kill 3355 [satory074@ip-172-xxx-xxx-xxx ~]$ sudo userdel ec2-user
- 時刻を設定します。
EC2では初期の時刻設定がUTCになっているのでJSTに変更します。Lightsail Terminal[satory074@ip-172-xxx-xxx-xxx ~]$ date Wed Sep 22 10:23:31 UTC 2021 [satory074@ip-172-xxx-xxx-xxx ~]$ sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime [satory074@ip-172-xxx-xxx-xxx ~]$ date Wed Sep 22 19:24:54 JST 2021
- clockの中身の設定を変更してcronを再起動します。Lightsail Terminal
[satory074@ip-172-xxx-xxx-xxx ~]$ sudo vi /etc/sysconfig/clock
/etc/sysconfig/clockZONE="Asia/Tokyo" UTC=true
Lightsail Terminal[satory074@ip-172-xxx-xxx-xxx ~]$ sudo systemctl restart crond.service
3. インスタンスのセットアップ2
1つめの参考記事で、インスタンスを作成する際に以下の起動スクリプトを指定していました。
このスクリプトではCodeDeployを行うための設定やインストールを行っています。
このスクリプトを実行していきます。
mkdir /etc/codedeploy-agent/
mkdir /etc/codedeploy-agent/conf
cat <<EOT >> /etc/codedeploy-agent/conf/codedeploy.onpremises.yml
---
aws_access_key_id: <Access Key ID>
aws_secret_access_key: <Secret Access Key>
iam_user_arn: <IAM User ARN>
region: <Desired Region>
EOT
wget https://aws-codedeploy-us-west-2.s3.us-west-2.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
-
ディレクトリの作成
Lightsail Terminalsudo mkdir /etc/codedeploy-agent/ sudo mkdir /etc/codedeploy-agent/conf
-
AWSパラメータの記述
Lightsail Terminal[satory074@ip-172-xxx-xxx-xxx ~]$ sudo vim /etc/codedeploy-agent/conf/codedeploy.onpremises.yml
/etc/codedeploy-agent/conf/codedeploy.onpremises.ymlaws_access_key_id: <Access Key ID> aws_secret_access_key: <Secret Access Key> iam_user_arn: <IAM User ARN> region: <Desired Region>
「<>」の部分は下記の値に書き換えます。
項目 内容 備考 Access Key ID アクセスキーID 「手順4:IAMユーザを作成する」で控えたアクセスキーID Secret Access Key シークレットアクセスキー 「手順4:IAMユーザを作成する」で控えたシークレットアクセスキー IAM User ARN IAMユーザのARN 「手順4:IAMユーザを作成する」で控えたユーザのARN Desired Region リージョン この記事では東京リージョンを指定しているので「ap-northeast-1」 -
CodeDeploy実行に必要なインストーラをwget
CodeDeployを実行させるのに必要なものを、参考記事では「CodeDeployのエージェント」という風に呼んでいます。
ここではそのインストーラをwgetします。wgetのリンクのリージョン名を、指定したリージョン名(ap-northeast-1)に書き換えています。
Lightsail Terminal[satory074@ip-172-xxx-xxx-xxx ~]$ wget https://aws-codedeploy-ap-east-1.s3.ap-east-1.amazonaws.com/latest/install ... Saving to: 'install' 100%[=========================>] 17,482 --.-K/s in 0.05s 2021-09-24 13:58:42 (331 KB/s) - 'install' saved [17482/17482]
-
インストーラ実行
起動スクリプトにはありませんでしたが、そのままインストーラを実行すると「rubyが無いよ!」って怒られるのでrubyをインストールします。Lightsail Terminal[satory074@ip-172-xxx-xxx-xxx ~]$ sudo yum install ruby ... Complete!
インストーラのパーミッションを変更してインストールを行います。
Lightsail Terminalchmod +x ./install sudo ./install auto
-
実行確認
CodeDeployのエージェントが正常に実行されていることを確認できたら成功です!やったー!
(PIDは異なります)Lightsail Terminal[satory074@ip-172-xxx-xxx-xxx ~]$ sudo service codedeploy-agent status The AWS CodeDeploy agent is running as PID 19406
6. LightsailインスタンスをCodeDeployに登録
作成したLightsailインスタンスをローカルマシンからAWS CLIによってCodeDeployに登録します。
-
LightsailインスタンスをCodeDeployに登録
Local Terminalsatory074@MacBook-Pro-2 ~ $ aws deploy register-on-premises-instance --instance-name <Instance Name> --iam-user-arn <IAM User ARN> --region <Desired Region>
「<>」の部分は下記の値に書き換えます。
項目 内容 備考 Instance Name インスタンス名 「手順5-1:インスタンスを作成」で名付けたインスタンス名 IAM User ARN IAMユーザのARN 「手順4:IAMユーザを作成する」で控えたユーザのARN Desired Region リージョン この記事では東京リージョンを指定しているので「ap-northeast-1」 -
LightsailインスタンスにCodeDeployで使用するためのタグを登録
Local Terminalsatory074@MacBook-Pro-2 ~ $ aws deploy add-tags-to-on-premises-instances --instance-names <Instance Name>--tags Key=<key>,Value=<value> --region <Desired Region>
「<>」の部分は下記の値に書き換えます。
項目 内容 備考 Instance Name インスタンス名 「手順5-1:インスタンスを作成」で名付けたインスタンス名 key タグキー 参考記事の例: Name value タグの値 参考記事の例: CodeDeployLightsailDemo Desired Region リージョン この記事では東京リージョンを指定しているので「ap-northeast-1」 -
正常に登録されたことを確認
Local Terminalsatory074@MacBook-Pro-2 ~ $ aws deploy list-on-premises-instances --region <Desired Region> { "instanceNames": [ <Instance Name> ] }
「<>」の部分は下記の値に書き換えます。
項目 内容 備考 Desired Region リージョン この記事では東京リージョンを指定しているので「ap-northeast-1」
7. アプリケーションの作成
そういえばLightsailに乗せるアプリケーションを用意していませんでした。
この記事を書くにあたって以下のサンプルコードを用意しました。
forkしても良いですし、非常に簡単なコードですので、ご自身で用意していただいても構いません。
8. CodeDeployにデプロイするアプリケーションを設定する
ここまで来たらあと少しです。
以下参考記事の「6.CodeDeployにデプロイするアプリケーションを設定する」からの作業を行い、CodeDeployのセットアップを行います。
- AWSのコンソールにサインインし、CodeDeployコンソール( https://console.aws.amazon.com/codesuite/codedeploy/start )を開きます。
- [アプリケーションの作成]をクリックします。
- [アプリケーション名]を入力します(例:CodeDeployTest)。
[コンピューティングプラットフォーム]で[EC2/オンプレミス]を選択します。
[アプリケーションの作成]をクリックします。 - [デプロイグループの作成]をクリックします。
- [デプロイグループ名]を入力します(例:CodeDeployGroup)。
[サービスロール]で「手順1:ロールを作成する」で作成したロールを選択します(入力欄をクリックするとロール一覧が出てきます)。 - [環境設定]で[オンプレミスインスタンス]にチェックを入れます。
[キー][値]の入力欄が出てきますので、「手順6:LightsailインスタンスをCodeDeployに登録」で登録したkeyとvalueを入力します。
(この記事の例の通りに設定した場合、keyは「Name」、valueは「CodeDeployLightsailDemo」) - [Load balancer]の[ロードバランシングを有効にする]のチェックを外します。
- [デプロイグループの作成]をクリックします。
9. GitHubリポジトリとCodePipelineを連携する
GitHubとCodePipelineの連携の設定を行います。
参考記事の流れ通りに進めます。
- AWSのコンソールにサインインし、CodePipelineコンソール( https://console.aws.amazon.com/codesuite/codepipeline/start )を開きます。
- [パイプラインの作成]をクリックします。
- [パイプライン名]を入力します(例:CodePipelineTest)。
- [高度な設定]の[アーティファクトストア]で[カスタムロケーション]を選択
[バケット]で「手順2:S3バケットを作成する」で作成したバケットを選択します(入力欄をクリックするとロール一覧が出てきます)。
[次に]をクリックします。 - [ソースプロパイダ]で[GitHub(バージョン2)]を選択します。
- GitHubの接続を作成します。
(スクショ撮るのを怠けてしまってすみません)- [接続]の[GitHubに接続する]をクリックします。
- [接続名]を入力します(例:GitHubConnectionTest)。
- [GitHubに接続する]をクリックします。
- [新しいアプリをインストール]をクリックし、GitHubとの連携を行います。
- 元の画面に戻ってきたら[接続]をクリックします。
- 「接続する準備が完了しました GitHub 接続を使用する準備ができました。」と画面に出れば成功です。
- [リポジトリ名]でLightsailにデプロイするリポジトリを選択します。
(この記事のソースコードを使う場合「aws_cicd_sample」)
[ブランチ名]でデプロイするブランチ名を選択します。
(この記事のソースコードを使う場合「main」)
[次に]をクリックします。 - [ビルドステージをスキップ]をクリックします。
- [デプロイプロバイダー]で[AWS CodeDeploy]を選択します。
[リージョン]はこれまで指定してきたものと同じものを指定します(この記事ではap-northeast-1)。
[アプリケーション名][デプロイグループ]で「手順8:CodeDeployにデプロイするアプリケーションを設定する」で入力した[アプリケーション名][デプロイグループ名]を選択します(入力欄をクリックするとロール一覧が出てきます)。
[次に]をクリックします。 - [パイプラインを作成する]をクリックします。
10. 変更の反映を確認
-
appspec.ymlを用意しましょう。
この記事で用いたaws_cicd_sampleリポジトリには既に含まれています。ディレクトリ構成は以下のようになっています。
ディレクトリ構成aws_cicd_sample |-- HelloWorld.txt <-- 更新反映の確認用 |-- README.md <-- なくてもいい |-- appspec.yml <-- 必要!
appspec.ymlは簡素化して以下のようにしました。
appspec.ymlversion: 0.0 os: linux files: - source: / destination: /home/satory074/src/aws_cicd_sample
項目 備考 source Lightsailインスタンスに反映させるファイルやディレクトリを指定します。 destination Lightsailインスタンス上にコードを配置するディレクトリを指定します。 -
GitHubにPushします。
Pushした瞬間からPipelineが動作しますので、「手順9:GitHubリポジトリとCodePipelineを連携する」で作成したPipelineのページから確認します。
もしかすると、「手順9:GitHubリポジトリとCodePipelineを連携する」を作成した時点でPipelineが動作しているかもしれません。[Source]と[Deploy]が「成功しました」となっていれば成功です!
-
Lightsail上のファイルを確認します。
distinationで指定したディレクトリにファイルが配置されているのを確認します。Lightsail Terminal[satory074@ip-172-xxx-xxx-xxx ~]$ ls -la /home/satory074/src/aws_cicd_sample/ total 8 drwxr-xr-x 2 root root 64 Sep 24 17:33 . drwxr-xr-x 3 root root 29 Sep 24 17:33 .. -rw-rw-r-- 1 root root 0 Sep 24 08:32 HelloWorld.txt -rw-rw-r-- 1 root root 17 Sep 24 08:32 README.md -rw-rw-r-- 1 root root 99 Sep 24 08:32 appspec.yml
-
更に確認を行います。
ファイル名の変更をPushし、Lightsailインスタンスに反映されているか確認してみます。Local Terminalsatory074@MacBook-Pro-2 ~/src/aws_cicd_sample main $ git mv HelloWorld.txt KonnichiWorld.txt satory074@MacBook-Pro-2 ~/src/aws_cicd_sample main $ git status satory074@MacBook-Pro-2 ~/src/aws_cicd_sample main $ git commit -m ''' Rename: HelloWorld.txt -> KonnichiWorld.txt ''' satory074@MacBook-Pro-2 ~/src/aws_cicd_sample main $ git push origin main
Lightsail Terminal[satory074@ip-172-xxx-xxx-xxx ~]$ ls -la /home/satory074/src/aws_cicd_sample/ total 8 drwxr-xr-x 2 root root 64 Sep 24 17:33 . drwxr-xr-x 3 root root 29 Sep 24 17:33 .. -rw-rw-r-- 1 root root 0 Sep 24 08:32 KonnichiWorld.txt -rw-rw-r-- 1 root root 17 Sep 24 08:32 README.md -rw-rw-r-- 1 root root 99 Sep 24 08:32 appspec.yml
ファイル名の変更が確認できたら大成功です!ここまでお付き合いありがとうございました。
間違っている箇所があれば申し訳ないです。
おわりに
なっっっっっっっっっっっっっが!!!!!!!!!!!!!!!!!!!!!!
Discussion