東大のAWSによるクラウド入門やってみた日記 2

## 前回
https://qiita.com/jextra_kingdomofudo/items/24e82e1f0c8f7b9d6756

## 今回進んだところ

3.6～4.5まで進みました。

## AWSの登録

4.1でAWSアカウントの準備が必要なので進めました。
最初にEメールで登録したユーザはルートユーザで、この先の手順に書かれている端末からのアクセスではこのユーザを直接使う事ができないので、別途ユーザを作る必要があります。

AWSではユーザや役割による権限、グループなどを管理する機能はIAMにまとめられています。

私はとりあえずというのと資料を読み勧めるの優先でAdmin権限を持ったユーザを作ってしまいましたが、本来であれば権限周りの理解や最低限のセキュリティ設定をしたうえで使ったほうが良いと思います。

とりあえず最小限のセキュリティだけでも確保したい人向け
https://qiita.com/yanyansk/items/3a989b70d2d3d49eff16

IAMや権限周りのベストプラクティスを知りたい人向け
https://qiita.com/c60evaporator/items/0121399880625cc1de51

あと注意が必要な点ですが、端末からのアクセスに必要な情報のうちシークレットアクセスキーはユーザ作成時に表示されたあとは確認する方法がありません。
ユーザー作成時にメモしておきましょう。

## aws-cdk

今回一番ハマった点です。
資料中ではaws-cdkのバージョンは1.30.0が推奨されていますが、手順通り1.30.0で進めるとcdk bootstrapでエラーになります。

そもそも1.30.0のpackeage.jsonにはnodeの必須バージョンが10.3.0と書いてありますが、10.3.0では動きませんでした。
↓こんな感じのエラーになります。
```
/home/***/.nvm/versions/node/v10.3.0/lib/node_modules/aws-cdk/node_modules/minimatch/dist/commonjs/index.js:192
    options;
           ^

SyntaxError: Unexpected token ;
    at new Script (vm.js:74:7)
    at createScript (vm.js:246:10)
    at Object.runInThisContext (vm.js:298:10)
    at Module._compile (internal/modules/cjs/loader.js:670:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:713:10)
    at Module.load (internal/modules/cjs/loader.js:612:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:551:12)
    at Function.Module._load (internal/modules/cjs/loader.js:543:3)
    at Module.require (internal/modules/cjs/loader.js:650:17)
    at require (internal/modules/cjs/helpers.js:20:18)
```

nodeのバージョンをそれぞれ12.22.12と14.21.3で試したところ14.21.3だと動きましたが、`pip install -r requirement.txt`後にcdk bootstrapを実行してもエラーになります。（jissのバージョンの問題？）

```
$ nvm use 14
Now using node v14.21.3 (npm v6.14.18)
$ cdk --version
1.30.0 (build 4f54ff7)
$ source .env/bin/activate
(.env)$ pip install -r requirements.txt
(.env)$ cdk bootstrap
Traceback (most recent call last):
  File "/mnt/***/intro-aws/handson/01-ec2/app.py", line 53, in <module>
    MyFirstEc2(
  File "/mnt/***/intro-aws/handson/01-ec2/.env/lib/python3.10/site-packages/jsii/_runtime.py", line 66, in __call__
    inst = super().__call__(*args, **kwargs)
  File "/mnt/***/intro-aws/handson/01-ec2/app.py", line 13, in __init__
    vpc = ec2.Vpc(
  File "/mnt/***/intro-aws/handson/01-ec2/.env/lib/python3.10/site-packages/jsii/_runtime.py", line 66, in __call__
    inst = super().__call__(*args, **kwargs)
  File "/mnt/***/intro-aws/handson/01-ec2/.env/lib/python3.10/site-packages/aws_cdk/aws_ec2/__init__.py", line 25781, in __init__
    jsii.create(Vpc, self, [scope, id, props])
  File "/mnt/***/intro-aws/handson/01-ec2/.env/lib/python3.10/site-packages/jsii/_kernel/__init__.py", line 224, in create
    response = self.provider.create(
  File "/mnt/***/intro-aws/handson/01-ec2/.env/lib/python3.10/site-packages/jsii/_kernel/providers/process.py", line 333, in create
    return self._process.send(request, CreateResponse)
  File "/mnt/***/intro-aws/handson/01-ec2/.env/lib/python3.10/site-packages/jsii/_kernel/providers/process.py", line 303, in send
    data = json.dumps(req_dict, default=jdefault).encode("utf8")
  File "/usr/lib/python3.10/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/usr/lib/python3.10/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.10/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/mnt/***/intro-aws/handson/01-ec2/.env/lib/python3.10/site-packages/jsii/_kernel/providers/process.py", line 146, in jdefault
    raise TypeError("Don't know how to convert object to JSON: %r" % obj)
TypeError: Don't know how to convert object to JSON: <SubnetType.PUBLIC: 'PUBLIC'>
Subprocess exited with error 1
```

色々バージョンを探ってみましたが、わからん+時間がかかるので動きそうなaws-cdkのバージョンに変えました。
nodeの18.20.3をつかって最新のaws-cdkを入れました。

:::note info
後で書きますが、aws-cdkはnodeのバージョン18をサポートしていないので、最初から17.3をインストールして作業を進めることをおすすめします。
:::

```
$ nvm use 18
Now using node v18.20.3 (npm v10.7.0)
$ npm install aws-cdk
added 1 package in 4s
```
cdk initを実行するため、空のディレクトリを作って、そこで作業します。
```
$ mkdir work
$ cd work
$ cdk init app --language=python
（出力は長いので省略）
$ python3 -m venv .env
$ source .env/bin/activate
$ pip install -r requirements.txt
（出力は長いので省略）
$ cdk bootstrap
```

**動かん……。**

`Cannot find module '@aws-cdk/cx-api'`というエラーが発生しました。
どうやら2.14.0は問題があるらしく2.13.0を使えというissueを見つけました（※後日2.14.9はうまく動きました）。
https://github.com/localstack/aws-cdk-local/issues/59

aws-cdkは開発が活発なようでチョロチョロバグを踏む可能性がありそうです。
aws-cdkのバージョンを2.13.0に変更して`cdk bootstrap`を実行したところうまく動きました。
```
Trusted accounts for deployment: (none)
Trusted accounts for lookup: (none)
Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize.
Bootstrap stack already at version '21'. Not downgrading it to version '10' (use --force if you intend to downgrade)
 ✅  Environment aws://339712945862/ap-northeast-1 bootstrapped (no changes).
```

ここで起動時のwarningでnodeのバージョン18はサポートしてないよと出るので、バージョンを17.3に切り替えました。

この状態で4.4.1から作業を進めると4.4.4の「デプロイを実行」で引っかかりました。
https://tomomano.gitlab.io/intro-aws/#_%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B

```
Traceback (most recent call last):
  File "/mnt/c/Users/AtsushiYamazaki/git/intro-aws/handson/01-ec2/app.py", line 1, in <module>
    from aws_cdk import (
ImportError: cannot import name 'core' from 'aws_cdk' (/mnt/c/Users/AtsushiYamazaki/git/intro-aws/work/.venv/lib/python3.10/site-packages/aws_cdk/__init__.py)
Subprocess exited with error 1
```

上でも書きましたがaws-cdkは開発が活発で、破壊的な更新も少なくないようです。
要は東大が用意してくれたpythonのコードはaws-cdk2.13.0では使えないようです

なので下記の記事を元に書き換えます。
https://qiita.com/t-kigi/items/8115456ebbb43c5c738e

```
from aws_cdk import (
    core,
    aws_ec2 as ec2,
)
import os
```

```
from aws_cdk import (
    aws_ec2 as ec2,
)
import aws_cdk as core
import os
```

これでうまく動きます。
(※このあとknown_hostsに書き込めないというエラーが出たりもしたのですが、パーミッションを変えればいいだけだったので、問題はないかなと思います。）