書籍「AWSではじめるインフラ構築入門」　サンプルアプリに関するメモ

## はじめに
[「AWSではじめるインフラ構築入門 第2版」(翔泳社)](https://www.amazon.co.jp/AWS%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9%E6%A7%8B%E7%AF%89%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E5%AE%89%E5%85%A8%E3%81%A7%E5%A0%85%E7%89%A2%E3%81%AA%E6%9C%AC%E7%95%AA%E7%92%B0%E5%A2%83%E3%81%AE%E3%81%A4%E3%81%8F%E3%82%8A%E6%96%B9-%E4%B8%AD%E5%9E%A3-%E5%81%A5%E5%BF%97/dp/4798178004)を購入して、AWSでのインフラ構築を実践的に学習した。
第1章から順に読み進めたが、第13章「サンプルアプリを動かしてみよう」でいくつか問題が発生したので記事にまとめる。
私は、インフラ、AWS、Webアプリ開発の技術者ではない。簡単なWebアプリを作成し、仮想マシン上でWebサーバーを立てて社内公開したことはある。サンプルアプリで使用されているRuby on Railsについてはよく知らない。

## 問題点と対処
### Ruby2.6.6でRails5.1.6が環境構築できない
本書p322に従って、Ruby2.6.6でRuby on Rails5.1.6をインストールしようとすると以下のエラーメッセージが表示される。
```
[deploy@ip-10-0-79-108 ~]$ gem install rails -v 5.1.6
...
ERROR:  Error installing rails:
        The last version of nokogiri (>= 1.6) to support your Ruby & RubyGems was 1.13.10. Try installing it with `gem install nokogiri -v 1.13.10` and then running the current command again
        nokogiri requires Ruby version >= 3.0, < 3.4.dev. The current ruby version is 2.6.6.146.
```
この問題については、以下の記事に従い、`nokogiri`と`rails-html-sanitizer`というライブラリを更新する。
[There are no versions of nokogiri (~> 1.14) compatible with your Ruby & RubyGems. エラーの解消](https://qiita.com/murata0705/items/dfa2fed6c773f925a975)

この対処後、Rails5.1.6をインストールしようとすると、さらに以下のエラーメッセージが表示される。
```
[deploy@ip-10-0-79-108 ~]$ gem install rails -v 5.1.6
...
ERROR:  Error installing rails:
        The last version of net-imap (>= 0) to support your Ruby & RubyGems was 0.3.7. Try installing it with `gem install net-imap -v 0.3.7` and then running the current command again
        net-imap requires Ruby version >= 2.7.3. The current ruby version is 2.6.6.146.
```
エラーメッセージに従い、`gem install net-imap -v 0.3.7`を実行して`net-imap`というライブラリを更新すると、Rails5.1.6がインストールできる。
(以前は、Ruby2.6.6でRails5.1.6がすんなりと環境構築可能であったが、その後ライブラリの更新により不可になったらしい。)

### アプリがS3にアクセスできない
本書p326のテーブルの作成を実行すると、以下のエラーが出る。
```
[deploy@ip-10-0-79-108 aws-intro-sample-2nd]$ rails db:migrate RAILS_ENV=production
[fog][WARNING] Unable to fetch credentials: Expected(200) <=> Actual(401 Unauthorized)

rails aborted!
ArgumentError: Missing required arguments: aws_access_key_id, aws_secret_access_key
/var/www/aws-intro-sample-2nd/config/initializers/carrier_wave.rb:4:in `block in <top (required)>'
/var/www/aws-intro-sample-2nd/config/initializers/carrier_wave.rb:2:in `<top (required)>'
/var/www/aws-intro-sample-2nd/config/environment.rb:5:in `<top (required)>'
/var/www/aws-intro-sample-2nd/bin/rails:9:in `require'
/var/www/aws-intro-sample-2nd/bin/rails:9:in `<top (required)>'
/var/www/aws-intro-sample-2nd/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Tasks: TOP => db:migrate => environment
(See full trace by running task with --trace)
```
これは、`fog`というライブラリが、S3にアクセスする権限がないので、`aws_access_key_id`と`aws_secret_access_key`を要求しているというメッセージである。
（`fog`はS3にファイルをアップロードするためのライブラリ）
本書のアプリへのアクセス権限付与方法は、本書9.4「ロールを作成してEC2に適用する」で`AmazonS3FullAccess`の許可ポリシーを持つロールを作成して、EC2(web01、web02)に適用するというものである。
もちろんその通りにロールを作成、適用し、本書9.5「動作確認」も実施済である。
p325の`.bash_profile`に記載する`AWS_INTRO_SAMPLE_S3_REGION`と`AWS_INTRO_SAMPLE_S3_BUCKET`も適切である。
素人なりに調べたところ、以下のことがわかった。
- `fog`のS3のアクセス権限の取得方法は`/アプリのインストールフォルダ/config/initializers/carrier_wave.rb`に記載される。`use_iam_profile     => true`の時、EC2に適用されたロールの情報を使用する。
- `fog`で`use_iam_profile     => true`としても、適切に動作しないことがあるらしい。

https://github.com/fog/fog-aws/issues/162

結局、EC2に適用されたロールの情報を使用することをあきらめ、本書3.2.4「グループを使用したアクセス許可の割り当て」で`PowerUserAccess`を割り当てたユーザー(Developersグループに所属するユーザー)のアクセスキーを使用することにした。

まず、以下の記事などを参考に、アクセスキーを取得する。
[AWSのアクセスキーを取得する方法](https://qiita.com/yamasakk/items/3060d22faeed8e05ebe4)

次に、`carrier_wave.rb`を以下の通り修正する(web01、web02とも)。
```carrier_wave.rb
if Rails.env.production?
  CarrierWave.configure do |config|
    config.fog_public = false
    config.fog_credentials = {
      # Amazon S3用の設定
      :provider        => 'AWS',
      :region          => ENV['AWS_INTRO_SAMPLE_S3_REGION'],     # 例: 'ap-northeast-1'
      # :use_iam_profile => true                              # コメントアウト
      :use_iam_profile => false,                              # 追加
      :aws_access_key_id => ENV['AWS_ACCESS_KEY_ID'],         # 追加
      :aws_secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']  # 追加
    }
    config.fog_directory =  ENV['AWS_INTRO_SAMPLE_S3_BUCKET']
  end
end
```
さらに、EC2のdeployユーザーの`.bash_profile`に以下を追記する(web01、web02とも)。
```.bash_profile
# 追加の設定
export AWS_ACCESS_KEY_ID=PowerUserAccessを割り当てたユーザーのアクセスキー
export AWS_SECRET_ACCESS_KEY=PowerUserAccessを割り当てたユーザーのシークレットアクセスキー
```
`.bash_profile`を書き換えた後は、`source .bash_profile`を実行する。
上記により、`PowerUserAccess`を割り当てたユーザーの権限で、WebアプリがS3にアクセスできる。
**`carrier_wave.rb`に`aws_access_key_id`と`aws_secret_access_key`を直接記載しても動作するが、ソースコードの流出により、本書p122にも記載されている「アクセスキーの漏洩と被害」が発生する恐れがあるので避ける。**
**また、`.bash_profile`に記載する方法でも、ロールを用いる方法よりセキュリティのレベルは低いと思われるので、自己責任でお願いします。**

#### 補足
本書p324の`bundle install`を実行すると以下のメッセージが表示される。
```
[deploy@ip-10-0-79-108 aws-intro-sample-2nd]$ bundle install
...
Post-install message from fog:
------------------------------
Thank you for installing fog!

IMPORTANT NOTICE:
If there's a metagem available for your cloud provider, e.g. `fog-aws`,
you should be using it instead of requiring the full fog collection to avoid
unnecessary dependencies.

'fog' should be required explicitly only if:
- The provider you use doesn't yet have a metagem available.
- You require Ruby 1.9.3 support.
------------------------------
```
`fog`でなく`fog-aws`を使用することが望ましいとのことか？
前述の`fog`に関するトラブルとの関係しているかはよくわからない。

### デプロイ時のメッセージ
本書p327の`rails assets:precompile RAILS_ENV=production`のコマンドを入力すると、次のメッセージが表示される。
```
[deploy@ip-10-0-79-108 aws-intro-sample-2nd]$ rails assets:precompile RAILS_ENV=production
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
...
```
実行可能な`yarn`がシステム内で検出されなかったとある。
`yarn`というライブラリがどのようなもので、アプリの動作にどのような影響を与えるかは理解できていない。
本書の読者で同じ報告があるので、私固有の問題ではないようだ。

https://zenn.dev/solxyz_bso/articles/aws_infra_book_review

## 結果
Webアプリのデプロイにおいていくつか不明点が残っているものの、サンプルアプリを動作させることに成功した。
#### 投稿画面
![AWS_Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641825/8f5c5ae2-8589-0705-26de-8c69d103e08f.png)
#### フォロワー画面
![フォロワー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641825/388099e9-cd19-305e-5f34-76d3e4ee397f.png)

## おわりに
付け焼刃ながらもいくつかの対処により、サンプルアプリを動かすことができた。
ただし、上に記載した事象、特に「S3にアクセスできない」（EC2にロールを付与する方法で）は、私の設定ミス等の問題か、Webアプリの共通の問題なのかわかっていない。

したがいまして、本書のサンプルアプリに関しまして、**この記事と同じ事象が発生した（この記事が役立った、もっと良い対処がある）**、**同じ事象は発生しなかった、別の事象が発生した**等の情報をいただけますと幸いです。

## 追記
自分と同じエラーの人を見つけた。
(AWSのアクセスキーIDとシークレットアクセスキーの設定不足)
https://ebookstore.sony.jp/review/LT000177258001711192/
やっぱり共通の問題がありそうね。

## 参考
著者サポートページ

https://sites.google.com/view/aws-intro-2nd/