scratch3.0でAWSを操作してみたかった(できなかった)

# 前置き

これは[株式会社SUPER STUDIO Advent Calendar 2022](https://adventar.org/calendars/8255)の19日目の記事です。

せっかく機会を得たので、Qiitaの記事を久しぶりに書いてみようと思って自分のアカウントを見たら、前に投稿したのが2014年でした。恐るべき光陰。
以前の記事の頃とは自分の境遇も変わったので、新たな気持ちで記事を作ってみようと思います。

技術トピックで自分がよく読む記事としては、筆者の経験を踏まえたうえで他の人の役に立つようなナレッジを共有しているものと、役に立つかわからないことに情熱を注いでいるようなものと、のどちらかが好きです。
今回記事を作るにあたり、他の人の役に立つものも一瞬考えたのですが、今回は後者で行きます。

### 前提条件

今回の記事の筆者の環境です。

* Windows 10 Pro
* Ubuntu 20 on WSL2

あと、AWSアカウントを持っていることが前提です。

# やりたいこと

ノーコードとかいうのが流行っているらしいじゃないですか。ものとして本当に流行っているかは知らないんですが、ワードとしては流行っている雰囲気を醸し出している。
最近、子供がレゴのSPIKEというものをやっていて、SPIKEアプリというもので簡単なプログラミングをしています。このSPIKEアプリはScratchというWebベースでのプログラミングツールがベースになっていて、ブロックでプログラムを組むといういわゆるノーコードな奴です。
SPIKEアプリはレゴを動かす専用なんですが、Scratch自体は汎用的なツールと聞いていまして、ちょっといじってみたいなーとふわっと思っていました。せっかくなので、この機会にちょっといじってみようと考えました。

Scratchを使ってScratchのプログラムを書くような記事はほかの人がいくらでも書いてくれているので、今回は自分が普段やっていることをScratchで実施してみようということを考えます。仕事でAWSを使っている私は思います。

ScratchでもAWSが動かせるんじゃね？

Scratchは一定の機能を持ったブロックを並べて、プログラムを実行するという考え方のツールです。
このブロックにAWS操作ができる機能を持たせることができれば、定型的な作業だったら、Scratchでも実行できるんじゃないかなと考えました。

# 構成

普段はAWSの操作にpythonを使っているので、ブロックで示す先のプログラムがpythonで書ければらくちんだなと思ったのですが、そんなに単純でないようでした。
javascriptの取り扱いについてはへっぽこもいいところなので、コピペに毛が生えた程度の作業しかできない自信があります。ブロック側のプログラムはできるだけ簡単に実装したい。
外部webサーバにアクセスしに行くだけのブロックを作って、その外部サーバでpythonプログラムを実行するというのが実装が簡単そうだったので、今回はそれで実装をためしてみることにしました。（結論として、できませんでした）

# 準備

## scratch3.0をローカルに立てる

基本的には、こちらの記事を参考にdockerで環境を構築していきます。
おおよそ書いてある通りに実行したところ、ローカルでScratch3.0を立ち上げることができました。

https://deep.tacoskingdom.com/blog/29

引っかかったのは以下の2点。

* node のバージョンが 12.22-alpine3.11 のまま実行したところ、yarn installの途中でnodeのバージョンが古いと怒られて止まった。Dockerfile で node14 の docker image に指定しなおす。
* node14にしたら、docker-compose build で落ちる。python2というパッケージがないとのこと。とりあえず python3 に置換したら後続に進めた。（影響範囲はわからない）

ローカルで画面表示ができたところまで

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45890/814ee044-96c3-0762-6af3-2bb5161145c6.png)

## pythonコードを実行するためのwebをローカルに立てる

pythonでwebサーバを立てるのとコードを書くのが一緒にできるとらくちんです。
今回はdockerでflaskを使ってwebを構築することにします。flaskは以前使ったこともあるので何とかなりそう。

下記の記事が要点がまとまっていたので、そのまま使いました。

https://gray-code.com/blog/flask-on-docker/

webページを表示できたのがこちら

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45890/e6252e76-40d7-9883-2742-cc7349eacdec.png)

## AWS操作用の関数を実装する

flaskでリクエストを受け取ったら、AWSのコードを実行するようにプログラムを書き換えます。
今回はとりあえず動作を確認したいだけなので、新規IAM Userを追加するくらいにしましょう。それだけならお金かからないし。
また、権限はAccesskeyで渡しちゃいます。本格的に何か作る場合は工夫しましょう。（いないと思うけど）

変更箇所は以下の2点です。
変更前のファイルの中身は元記事を参照のこと。

### flaskのコンテナにboto3を入れる

Dockerfile の pip の行に boto3 を追記して image を build し直します。

```
(変更前)
RUN pip install Flask

(変更後)
RUN pip install Flask boto3
```

### IAM追加の関数を追記する。

app/index.py 内に IAM User 追加の関数を入れます。
今回は単純にhtakoユーザを作るだけの機能を追加しました。
キーは自分の環境に合わせてください。

```
def index():
  boto3.client(
    'iam',
    aws_access_key_id='AKIxxxxxxxxxx',
    aws_secret_access_key='xxxxxxxxxxxxxxxxxxxx'
  ).create_user(UserName='htako')

  return "<h1>Hi, Flask!</h1>"
```

上記以外にはまったポイントは

* docker containerがなぜかDNSを引けなくなって2回引っかかった。一回うまくいったのに。WSL2経由のdockerという構成上、どこを直すことで根本解決できるか時間がかかりそうだったので、今回は場当たり的な解決。
  * 1つ目はdocker buildのpip。 `RUN echo "nameserver 8.8.8.8" > /etc/resolv.conf && pip install boto3 Flask` みたいにして解決。
  * 2つ目はboto3でアクセスする `https://iam.amazonaws.com/` にアクセスできないというエラー。pipの時と同様に、コンテナ内の `/etc/resolve.conf` を編集して `nameserver 8.8.8.8` に誘導して解決。

webアクセスした後、IAM Userが追加されたことを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45890/bc3444db-d5d8-4392-5902-0b288e938810.png)

## scratch3.0の拡張機能を作る

ここが本番です。

https://deep.tacoskingdom.com/blog/29

https://ja.scratch-wiki.info/wiki/Scratch_3.0%E3%81%AE%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BD%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86

http://www.moonmile.net/blog/archives/10331

https://qiita.com/Hiroyuki_OSAKI/items/a46e1c881d3aed4661f7

結論からいうと、いろいろと参考文献に当たったんですが、できませんでした。
できなかったポイントだけ整理して、この記事は終わろうと思います。ただでさえ、締め切りをだいぶ過ぎてしまったので。

### ポイント1

yarn link というものが具体的に何をやっているかがわからない、を解消できませんでした。

scratchの最初の構築の手順でこういうのがあります。

```
$ git clone --depth 1 https://github.com/llk/scratch-vm.git
$ git clone --depth 1 https://github.com/llk/scratch-gui.git
$ cd scratch-vm && yarn install && yarn link
$ cd scratch-gui && yarn link scratch-vm && yarn install
```

ここの `yarn link scratch-vm` をすると、この構築が終わった後にサーバを起動する `yarn start` でコンパイルが失敗するという現象を解決できませんでした。

コンパイルで出ているエラーを見るとこれっぽい。

```
ERROR in unable to locate '/usr/src/app/scratch-gui/node_modules/scratch-vm/dist/web/extension-worker.{js,js.map}' glob
```

確かにこのパスにファイルないんですが、scratch-guiの下にscratch-vmなんてフォルダはもともとないので、linkとかするとこういう紐づけが発生するんじゃないかなと想像したんですが、そこから先わからず。

### ポイント2

上記問題で、`yarn link scratch-vm` をしないとscratchが立ち上がるし使えるんですが、いざ拡張機能を作って使おうとすると、表示されない。
拡張機能一覧には出るんですが、その拡張機能をクリックすると作成したブロックが使えるようになるはずなんですが、ならない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45890/18f49ce4-38fc-54c4-4980-37bf53d9146c.png)
赤枠のところに作ったextentionは表示されているが、クリックしても

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45890/46bbf8a9-35b9-3c63-0620-0d51ef7de3cd.png)
左ペインに出てくるはずの拡張機能が出てこない。


chromeのdeveloperツールでconsoleを見ると、以下のエラーが出ている。

```
localhost/:1 Uncaught (in promise) DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:8601/htako' failed to load.
```

確かに、このURLをクリックしてもコンテンツがないみたいなんですが、なんでないのかがわからない。
拡張機能を追加するのにいじるコードファイルは3つしかなく、何回も確認したんですが、間違いが見当たらない。
調べる限り、どうもこのエラーはreact業界ではあるあるの雰囲気を感じるのですが、業界人でないのでピンと来ない。
で、先ほどの `yarn link ～` やってないからなんじゃなかろうかと思って戻っても、linkってなんじゃらほいなので、ここでタイムアップとなりました。

# 実行

と進むはずだったんですが、今回は実装が完了しなかったので未達。
無念。

# 感想

解決できた、という記事を上げられたらかっこよかったんですが、今回はできませんでした。すみません。

AWSをScratchで動かすというのは、ほぼほぼ無駄です。
そもそもAWSコンソールがGUIなので、それでできることをboto3というAPIを経由させてさらにGUIでラッピングするということが無駄です。
あえて意義を見出すとしたら、AWSコンソールというものが汎用ツールであるので、いろいろできすぎてしまう問題に対して、工夫ができるかもしれません。例えば自社サービスではインスタンスはこの条件でしかcreateしません、というような場合はインスタンス作成ボタンが一つあればいいので、それほどスキルを要求しなくてもその作業を他人に頼めるようになる、というような用途があったとしたら使える可能性があります。

技術者というのは、プライベートでも仕事でもこういう問題によくあたって、なんとなく解決できたりできなかったりするということを、頻繁に繰り返す生き物です。
全然わからないことを思い付きでやってみるというのは、自分の知識を整理するのにも良いし、新しいことにチャレンジするのが年々つらくなるという加齢現象にあらがうためにも、良いのではないかと思います。いい技術者というのは、多分見えないところで解決できなかった問題をたくさん乗り越えているのだと思います。
今回のこれもその一つなのですよ。ええ。

scratchはまだまだ付き合いがある（子供がいじっているので）と思うので、もう少しやってみたいというのと、今回解決できなかったのが悔しいというのとがあるので、解決編がいずれ書ければと思っています。