OmniAICreator/Qiita-1.07M huggingface dataset:
AWS App Mesh を利用した Amazon ECS の Blue/Green デプロイ

[AWS Containers Advent Calendar 2020](https://qiita.com/advent-calendar/2020/aws-containers) の 8 日目の記事です。

本記事では、[AWS App Mesh](https://aws.amazon.com/jp/app-mesh/) を用いて [Amazon ECS](https://aws.amazon.com/jp/ecs/) にて Blue/Green デプロイを実施してみたいと思います。

## AWS App Mesh とは？
はじめに、簡単に AWS App Mesh について紹介します。

AWS App Mesh とは、サービス間の相互通信の制御や監視を容易にするサービスメッシュです。

コントロールプレーンを AWS App Mesh が管理しており、データプレーンとして Envoy proxy を利用します。
AWS App Mesh が定義するリソースを用いて下の図のようなネットワークモデルを構築することで、ネットワークモデルが Envoy の設定に変換されデータプレーンである Envoy proxy に配布されます。

[20201014 AWS Black Belt Online Seminar AWS App Mesh Deep Dive](https://www.slideshare.net/AmazonWebServicesJapan/20201014-aws-black-belt-online-seminar-aws-app-mesh-deep-dive/27)
![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79239/a80d990f-ad8c-6c80-ef44-170505a102c6.png)

ここで、ネットワークモデルを上記の図のように構成した場合、**Virtual Router** にてリクエストの振り分け先となる **Virtual Node** の重み付けや紐付けを変更することで、client である **Virtual Node** のリクエスト送信先を変更することなく Blue/Green デプロイを実施することができます。

## 実現方針
今回は、サンプルとして次の図のようなシンプルなアプリケーションを用意します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79239/50cd4c42-3985-f0a8-ba61-2517732c665b.png)

- `Frontend service`, `Backend service` はそれぞれ異なる ECS サービス
- `Frontend service` はリクエストを受けた後、`Backend service` から必要な情報を取得する
- `Frontend service` は **Virtual Service** で `Backend service` にリクエストを送信する

このアプリケーションに対して、以下のようにネットワークモデルを構築しておきます。

1. `Backend service` のサービスとして設定した **Virtual Service** のプロバイダーとして **Virtual Router** を設定
2. 1 で設定した **Virtual Router** の **Route** で、`Backend service (blue)` と `Backend service (green)` をターゲットとして設定
3. **Route** のターゲットの重み付けは blue : green = 1 : 0 とする

この状態で、**Route** のターゲットの重み付けを変更することで Blue/Green デプロイを実施することができます。

## 動作検証
それでは、実際に動作を確認していきたいと思います。

はじめに、Blue/Green デプロイ前の `Frontend service` にリクエストを投げてみます。

```shell-session
$ curl -s $ENDPOINT | jq
{
  "message": "\"blue\""
}
```

上記のように、blue 環境の情報が取得されています。

この状態で、**Route** のターゲットの重み付けを変更します。

```shell-session
$ cat update-route.json
{
    "meshName": "advent-calendar",
    "routeName": "default",
    "spec": {
        "httpRoute": {
            "action": {
                "weightedTargets": [
                    {
                        "virtualNode": "http-server-blue",
                        "weight": 0
                    },
                    {
                        "virtualNode": "http-server-green",
                        "weight": 1
                    }
                ]
            },
            "match": {
                "prefix": "/"
            }
        },
        "priority": 1
    },
    "virtualRouterName": "http-server-vr"
}
```

```shell-session
$ aws appmesh update-route --cli-input-json file://update-route.json
...
```

変更後、改めて `Frontend service` にリクエストを投げてみます。

```shell-session
$ curl -s $ENDPOINT | jq
{
  "message": "\"green\""
}
```

無事に green 環境の情報が取得されることを確認できました。

### まとめ
本記事では、AWS App Mesh を用いて Amazon ECS の Blue/Green デプロイを実施してみました。
今回の手順では、blue 環境から green 環境へトラフィックの切り替えを一度に実施しましたが、重み付けを調整して少しずつ green 環境へトラフィックを流して、徐々に blue 環境と green 環境を切り替えていくことも可能です。

この情報が、Amazon ECS で Blue/Green デプロイを検討されている方にとって、少しでもお役に立てますと幸いです〜 🙌
DeviseのUserテーブルにUpdateアクションでカラムを更新しようとするとうまくいかない現象について

#事の発端

Deviseで作ったUserモデルのテーブルにカラムを更新しようとするとできなかったことが始まりです。

意外なところで詰まったなぁと思ったので健忘録としてまとめます。

```user_controller.rb

  def update
    @user = User.find(params[:id])
    if @user.update(user_params)
      redirect_to user_path(@user.id)
    else  
      render :show
    end
  end
```
僕は月の走行距離をマイページにて追加したかった為詳細ページにform_withを構えています。

```show.html.erb
  <%= form_with(model: @user, local: true, class: "goal-form")  do |f| %>
    <%= f.text_field :distance, placeholder: "目標を記入する", class: "form__text" %>
    <%= f.submit "設定する", class: "btn btn-primary" %>
  <% end %>
```

送られてくる値も間違ってなかったのでなんでやねんと思っていたとこでした。
そこで以下のエラーを見つけました。
![EFE24E99-97AA-473B-8332-1DEF840AD209_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/915363/4ab200b1-c7b6-1b8e-cfed-d1198fb7ef43.jpeg)


#そもそもUserテーブルの編集にはPasswordの入力が必要だということ。

知りませんでした。
これまでユーザーの編集を行うことがなかったんです。

そこでPasswordを入力せずにユーザーの編集を行う方法を見つけました。
カラムを更新するには新たなコントローラの作成やメソッドが必要なようです。

まずは、users/registrations_controller.rbを作成します。

```registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_account_update_params, only: [:update]

  protected

  def configure_account_update_params
    devise_parameter_sanitizer.permit(:account_update, keys: [:name])
  end
end
```

次にルーティングを設定します。

```route.rb
  devise_for :users, controllers: {
    registrations: 'users/registrations'
  }
```

Userモデルを編集。メソッドを追加します。

```user.rb

  メソッドを追加
  def update_without_current_password(params, *options)
    params.delete(:current_password)

    if params[:password].blank? && params[:password_confirmation].blank?
      params.delete(:password)
      params.delete(:password_confirmation)
    end

    result = update_attributes(params, *options)
    clean_up_passwords
    result
  end
end
```

Userモデルで定義したメソッドを呼び出します。

```registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_account_update_params, only: [:update]

  protected
追加
  def update_resource(resource, params)
    resource.update_without_password(params)
  end

  def configure_account_update_params
    devise_parameter_sanitizer.permit(:account_update, keys: [:distance])
  end
```

また、モデルにpasswordのバリデーションがかかっているとまだエラーになると思うので外しておきましょう。

```user.rb
  with_options presence: true do
    validates :nickname
    validates :email
    validates :password    ←消す
  end  
```


https://gyazo.com/d2738db841e41a0679d16fae6836ace9

できました。ほぼコピペです…


ここで初見だった方々が多かったのでまとめてみました。



・:account_update・・・Updateをするときに指定する引数。
・blank?・・・中身が空もしくは存在しないときにtrueを返す。
・update_attributes・・・一つのカラムのみを変更できる。しかし、バリデーションがスルーされる為、エラーの判定位が出ない。（これに苦しめられた）



キリがないのでここまで。


#完成

これから、jsで今日走った距離が引かれて減っていくような機能を導入したいなと思います。
お疲れ様でした。

#参考文献

https://qiita.com/j-sunaga/items/8d6769dfd04da5d3eed5

https://qiita.com/somewhatgood@github/items/b74107480ee3821784e6

https://pikawaka.com/rails/update
AWS CLI だけで Hugo のホスティング環境を構築してみる ー はじめよう、技術ブログ

こちらの記事は下記に移転しました。

[AWS CLI だけで Hugo のホスティング環境を構築してみる ー はじめよう、技術ブログ - michimani.net](https://michimani.net/post/aws-provision-hugo-on-aws-using-only-aws-cli/)
Xamarin.Android で Unity as a Library (うまくいった話)

この記事は、[Xamarin Advent Calendar 2020](https://qiita.com/advent-calendar/2020/xamarin)の8日目の記事です。

# はじめに

[Xamarin.Android で Unity as a Library (をやろうとしてうまくいかなった話)](https://zenn.dev/tan_y/articles/9e082f8234f827) の記事を読んで、できないことはないよなと思い、自分でも試してみることにしました。

# 結果
**記事の手順でできました。**

試した環境は以下の通りです。

* macOS Big Sur
* Unity 2019.4.16f1
* Android Studio 4.1.1
* Visual Studio for Mac 8.8.3

実機（UMIDIGI A7 Pro）で試しています。また、デバッグ実行だとUnityの画面が表示されなかったのですが、デバッグなし実行だとうまくいきました。

![Screenshot_20201208-001920.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236182/b20cc33d-c7d7-8049-742c-7bcf5489a41e.png)




# コード
[こちら](https://github.com/f-miyu/UaaLXamarinAndroid)
記事にあったコードを拝借させていただきました。

# おわりに
どうしてうまくいかなかったのかは定かではありませんが、ひとまず、Xamarin.Androidでも、Unity as a Libraryは使えそうです。
rust-analyzerで"unresovled import"が出るときの対処法

rust-analyzerでちょっとハマったのでメモ
## 問題ないはずのimportでエラーが発生

ある日プログラミングしてたらErrorが出た。![スクリーンショット 2020-12-07 23.28.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167729/267ae388-40fd-679d-2e97-88d07384e461.png)
問題ないはずなのになぜ…？？
ethernet.rs を見てみる
![スクリーンショット 2020-12-07 23.30.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167729/13ca7ae8-0961-2c24-f282-4af9165d9901.png)
ethernet.rsのincludeを上手く検知できないっぽい

## 対処法

同じ様なことでハマってる人がいた
https://github.com/rust-analyzer/rust-analyzer/issues/688
これ追加すれば直せそう

```
"rust-analyzer.cargo.loadOutDirsFromCheck": true,
```

追加した![スクリーンショット 2020-12-08 0.03.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167729/a310a413-ccfb-ce8d-e8a0-5a044b3d322c.png)
直った！![スクリーンショット 2020-12-08 1.20.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167729/dd4f41af-91a6-6b57-e175-d7876b9991f0.png)
HTMLでブラウザにGoogleMapを表示させる

#はじめに 
本記事は 駆け出しエンジニアの第一歩！AdventCalendar2020 ８日目の記事です。
プログラミングを始めて３ヶ月の初学者ですが、アウトプットの練習も兼ねて、Qiita初投稿します。


##HTMLでGoogleMapを表示させる


####①まずはブラウザに表示させたい場所をGoogleMapで検索します
####②施設の詳細情報が表示されるので検索フォームの左側にあるハンバーガーメニューをクリックします

![スクリーンショット 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921841/75dc58df-3370-9d19-c4a8-0d2f7b0be2a5.png)

---

####③「地図を共有または埋め込む」をクリックします




![スクリーンショット 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921841/74ed2896-be1b-7313-f23e-2419f5c7fe42.png)

---

####④画面中央に共有が出てくる為、「地図を埋め込む」をクリックします

![スクリーンショット 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921841/95a0da11-474d-5745-2480-403a6fffbe06.png)

---

####⑤「HTMLをコピー」をクリックし、コードをコピーします
#####※地図のサイズはコード左側の『中』をクリックすると「小」「中」「大」「カスタムサイズ」から変更できます

![スクリーンショット 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921841/5bc6f562-abf8-9da3-2c3f-be1e40d6a707.png)

---

####⑥コピーしたコードをHTMLファイルに貼り付け、保存します
#####今回は「大」「中」「小」3つのサイズを貼ってみました

![スクリーンショット 7 .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921841/516fc887-f050-71df-569e-316b69b528c6.png)


---

####⑦ブラウザで確認すると地図が表示されます


![スクリーンショット 8 .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921841/5285ee10-2eb0-3d38-a626-596190adf351.png)


---

#最後に
今回の記事はつい最近聞いたことを参考に書きました。
まだ難しいことは書けないですが、今後も少しずつアウトプットをしていきたいと思います。
M5stackを開発者ではなくユーザとして愛用している話

# はじめに
- 今回の記事は、とある病気のコミュニティでM5stackが愛用されている話です
- ダレトクな話ではありますが、こんな使われ方もしているんのかふーん、みたいな生暖かい目でみていただければと思います
- 医学の専門家ではないため、所詮患者レベルの知識なのでご注意ください
- 開発の話は一切出てきません（たぶん）

# とある病気とは
- [一型糖尿病です](http://dmic.ncgm.go.jp/general/about-dm/050/010/01.html)
- 私は大人になってからの発症で、この病気とは１０年のおつき合いになりますが、小児糖尿病とも呼ばれることがあり、子供の頃からこの病気と付き合っている方もたくさんいます。

# 一型糖尿病ってめんどくさい
- 毎食前にインスリンを打つ
- 毎食前に血糖値を測る
- 低血糖に気をつける（突然死しかねない）
    - 特に子供だと低血糖に気づかないことがある
- 高血糖にも気をつける（長期的）

# 課題（大事なことなので２回目）
- 子供だと低血糖に気づかない（死にかねない）

一型糖尿病の子供を持つお父さんが作ったWebアプリケーション（後述のNightScout）とM5stackで常に血糖値を表示しておける仕組みが普及（とまではいかないかもですが）し始めているかもしれない

# 環境
- [FreeStyleリブレ](https://www.myfreestyle.jp/)......腕につけるタイプの持続型の血糖測定器
- [MiaoMiao](https://miaomiao.cool/).....FreeStyleLibre上に貼り付けて、後述のTomatoにBluetoothで血糖値を送信する
- [Tomato](http://tomato.cool/)......MiaoMiaoから血糖値を受け取る。NightScoutに血糖値を送るiPhoneアプリ。似たような、Spikeというものもあります。
- [NightScout](https://github.com/nightscout/cgm-remote-monitor)....血糖管理のためのWebアプリケーション（heroku&Atlasで構築）
- [M5stack](https://github.com/mlukasek/M5_NightscoutMon).....NightScoutもしくはTomatoと連携して、血糖値をリアルタイム表示
- ![スクリーンショット 2020-12-08 1.06.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74969/f8b4ae11-3eb9-702b-0db8-f5283b95637c.png)

これで、周りの人間が低血糖に気付ける

# 構築手順
エンジニアではない人が、この手順を実施しているのが感動でした。
親が子を思う気持ちは最強だと思います。
（基本は皆エンジニアでないのでマニュアルは基本はアカウントを作るところから。私は作っていなかったのはAtlasのみでしたのでAtlasのみ登録）

- リブレ、MiaoMiao、Tomatoの連携は通常のアプリ連携と同じ感じ
- NightScout
    - Githubのアカウントを作る
    - herokuのアカウントを作る
    - Atlasのアカウントを作る
    - Githubのリポジトリをforkして、herokuにデプロイ（ボタンをポチッとするだけなので、誰でもできる！作った人すごい！！）
- M5stack
    - 構築済みのものを購入

# おわりに
- 2020年11月からリブレを利用し始め、MiaoMiaoの存在を知り、NightScout、M5stackの存在を知り、初期設定に走り抜けた11月でした。主治医の先生に報告したいと思います。
- せっかくの患者本人かつ自称ソフトウェアエンジニアの端くれなので、来年中にはNightScoutもしくはM5_NightscoutMonのGitHubに何かコミットをしたい。お手伝いがしたいと思います。
【メモ】backgroundの使い方

#background

背景(画像)は以下の設定で行う

```ruby:sample.html.erb
<body>
  <div class="top_wallpaper">
|
|
|
```

```ruby:sample.css
.top_wallpaper{
  background-image: url(/wallpaper-new.jpg);
}
```
【CSS】
・該当するクラスに対し"background-image"を使用
#書き方
・`background-image: url(/xxx.yy)`
　・`/`:フォルダの場所("/"のみの場合publicフォルダが自動的に適用)
　・`xxx`:ファイル名
　・`yy`:拡張子名
[python] 主成分分析の主成分数と累積寄与率の関係を描画するスニペット

表題通りです。とりあえず、sklearn の [load_boston](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_boston.html) の結果を表示する様にしてあります。

```python:
from sklearn.datasets import load_boston
X = load_boston(return_X_y=True)[0]

from sklearn import decomposition
pca=decomposition.PCA()
pca.fit(X)
y = np.add.accumulate(pca.explained_variance_ratio_)
x = np.arange(y.size)+1
plt.plot(x, y, ls='--', marker='o')
plt.ylabel("cumulative contribution ratio")
plt.xlabel("number of principal components")
plt.show()
```
![スクリーンショット 2020-12-08 午前1.04.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178570/edf9d76f-3e9e-8dfb-4213-35813ecdaed9.png)
Xcode12以降のPlayground上でSwiftのパッケージをインポートする方法

#はじめに
Xcode12以降のPlaygroundにおいて、Swiftのパッケージ📦をドラッグ・アンド・ドロップすることで簡単にインポートしてできる機能が追加されました。
今までは簡単にドラッグ・アンド・ドロップでインポートできなかったのでこの使い方を紹介させて頂きたいと思います。

https://developer.apple.com/documentation/xcode-release-notes/xcode-12-release-notes
![スクリーンショット 2020-12-06 19.41.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877762/6d02755f-af66-dd52-35a7-ce8a99bdd9b6.png)

#Playgroundとは
`プレイグラウンド（Playground）`は別のプロジェクトの生成をしなく、Swiftのコーディング結果をリアルタイムで確認できる機能です。
基本的な文法から複雑なコードまで様々なケースで利用することができます。Swiftを試しに動かしたり、文法の練習にも使えるいいツールです。


#使い方

まず、新しいプロジェクトを作成します。
Xcodeを開いて_`File > New > Playground`_を選択してPlaygroundのファイルを該当プロジェクトに追加します。
![スクリーンショット 2020-12-06 19.49.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877762/2f78176b-5f51-5ab2-2338-3a30af7a603e.png)

その後、Playgoundのファイルを開いた状態で
_`File > Save As Workspace`_を選択してworkspaceファイルを生成します。

![スクリーンショット 2020-12-06 19.53.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877762/9f0aaa8e-fad8-ffa4-daa5-47dd7bb4a06d.png)

💡注意点として、ファイル生成後、右側の`show the file inspector`からRelative to Groupのオプションを選択することが必要です。
またPlayground SettingsのPlatformを現在使用しているPlatformを設定して`Build Active Scheme`にチェック☑️を入れます。

![スクリーンショット 2020-12-06 20.03.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877762/5227f5a1-843d-0d99-0798-47936da692b4.png)

ここまでできたらworksapceファイルを保存して再度開きます。
インポートしたいSwiftのバッケージをダウンロードしてXcodeの左側のファイルリストがある場所にドラッグアンドドロップします。

インポートが終わったらすぐにPlaygroundに使用することができます。

以下はPlotというパッケージをインポートしてみた列です。

![スクリーンショット 2020-12-06 20.12.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877762/8e81d6be-b35f-4641-88c8-d587cf81e01b.png)

![スクリーンショット 2020-12-06 19.07.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877762/153ce3b5-b3b7-40a1-84dd-1fb07c5c441e.png)

#まとめ
PlaygroundはまだSwiftに慣れてない人や練習コードを作成したい人たちにとっても便利な機能だと思います。
これを利用して楽しくコーディングをしましょう！

参考：
[Plot](https://github.com/JohnSundell/Plot)
[Importing Swift packages into a playground in Xcode 12](https://wwdcbysundell.com/2020/importing-swift-packages-into-a-playground-in-xcode12)
Faustによるオーディオプログラミング例

Faust
===

[オーディオプログラミング言語 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/audiolang)

# 概要

https://faust.grame.fr/

サウンド合成、オーディオ処理用関数型プログラミング言語(Functional-AUdio-STream)。コマンドラインコンパイラだけでなく、Web IDEやマルチプラットフォームで動くFaustLive統合環境なども用意されている。また、C++、C、Java、JavaScript、LLVM、WebAssemblyなど、多くの他言語やバイナリにトランスパイルできるのが特徴。

開発はGRAME(フランス国立音楽創造センター)。ブロックダイアグラムを代数的に表現するというアイデアは2002年(\*1)、それを関数型言語のアプローチによって実装したFaust言語が2004年に紹介された(\*2)。

(\*1) Yann Orlarey, Dominique Fober, and Stephane Letz. An algebra for block diagram languages. In ICMA, editor, Proceedings of International Computer Music Conference, pages 542–547, 2002.
(\*2) Yann Orlarey, Dominique Fober, and Stephane Letz. Syntactical and Semantical Aspects of Faust. Soft Computing, 8(9):623–632, 2004.

# 実装例

## サイン波生成

Faustのライブラリはオシレーターならos、エフェクトならefといった名前でグループ化されています。元がモノラルなので<: \_,\_をつけて2chのステレオ音声にして出力しています。この例ではわかりにくいですが、Faustが扱うデータはサンプル単位です（つまりMaxでいうところのGen）。  
Web IDE( https://faustide.grame.fr/ )やFaustLive( https://faust.grame.fr/downloads/#faustlive )で実行できます。

#### sine.dsp

```javascript
import("stdfaust.lib");

freq = 440;
gain = 0.5;

process = os.osc(freq) * gain <: _,_;
```

## Delayエフェクト

Faustにはwavファイルを読み込んで再生する機能はありません。代わりに今回はディレイフィルターをソースコードdelay.dspに記述して、それを以下のようにfaust2sndfileでコンパイルすることでwavファイル加工ツール「delay」を生成します。

```
> faust2sndfile delay.dsp
```

生成されたdelayの第一引数に入力wavファイルを指定して実行すると、第二引数で指定したwavファイルにディレイ効果をかけた音声を出力します。 

```
> ./delay ../voice.wav voice_with_fx.wav
```

faust2sndfileを使わずに、このdelay.dspをWeb IDEやFaustLiveでそのまま実行すると、マイク入力した音声ストリームにディレイをかけてスピーカーで鳴らします。

#### delay.dsp

```javascript
// compile: faust2sndfile delay.dsp
// run: ./delay ../voice.wav voice_with_fx.wav

import("stdfaust.lib");

maxDelayTime = 1.0;
delayTime    = 0.4;
feedback     = 0.5;

process = ef.echo(maxDelayTime, delayTime, feedback) <: _,_;
```


# 感想

関数型言語の特徴として「構造を宣言的に記述しやすい」という点があります。Faustも主眼はオーディオエンジンそのものではなくオーディオグラフ構造の記述性のようです。

オーディオプログラミングは逐次的処理のように思えるかもしれませんが、ほとんどの場合構造を定義する静的な部分と、構造に実際に信号を流し込む実行処理に分けることができます。Faustの場合、Maxのようなオーディオグラフの構造を代数的にテキスト言語で表現するという発想があり、それには関数型言語の文法が適していたということのようです。

テキスト言語で構造を記述することで、他の形式へ変換するトランスパイラが作りやすいという点は特徴的です。他にも、ビジュアル言語よりも最適化しやすく、ライブラリの再利用性も高いなどオーディオプログラミングがこれまで以上に進化する鍵になりそうな気もします。   
たとえ初見では黒魔術に見えたとしても。

触った印象としては、Web IDEやFaustLiveも安定しているしfaust2sndfileも一発で実行ファイルを生成できて、完成度としては高く感じました。ドキュメントも充実しているので、他にない特徴を持つ言語として今から学ぶには良いと思います。

ドキュメントに明記されていませんが、リポジトリにGPLとあるのでその点は少し注意が必要です。  
https://github.com/grame-cncm/faust/blob/master-dev/COPYING.txt

ライブラリはSTKライセンス。  
https://github.com/grame-cncm/faustlibraries/blob/master/licenses/stk-4.3.0.md

他の形式にトランスパイルするときの雛型となるアーキテクチャファイルはソースコードのコメントにGPLとあります。通常、コンパイラのライセンスとそれを使ってコンパイルした自作プログラムのライセンスは別ですが、リンクされるライブラリや雛型のライセンスは、ビルドしたプログラムを利用する際に考慮する必要があります。

Faustの場合、生成されたコードのライセンスはコンパイル対象のソースコードに従うという情報もあります。( http://olilarkin.co.uk/misc/JUCE_Summit.pdf )

[オーディオプログラミング言語 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/audiolang)
Vue Routerでページを更新or直接アクセス→CannotGETの対処 。Node.js(Express)の例


## Vue Routerでページを更新すると

`zukan`画面にいるときに、ページをリロードすると

画面
![スクリーンショット 2020-12-08 0.14.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378497/b566cfed-6003-2deb-d386-198016f1aa98.png)

Console
![スクリーンショット 2020-12-08 0.25.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378497/489eed86-ed6d-35e0-527a-0d6af4bd07b0.png)

みたいになる。

SPAは常にindex.html一枚で処理をしている。

にもかかわらず、URLが見かけ上の`zukan`のPATHにアクセスしようとするため、エラーになる。

## 環境

| | version |
|:-:|:-:|
| Node.js | v11.15.0 |
| OS | macOS Catalina v10.15.7 |
| プロセッサ | Intel Core i5 |

## 原因

historyを設定してURLから`#`を削除していると起こる。
ちなみにhistoryとは下で設定したやつ。

```js:router.js
const router = new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  //...略
```

## 対処

`#`を削除しつつ、問題を解決する方法は公式サイトに解説されている。

- [HTML5 History モード | Vue Router](https://router.vuejs.org/ja/guide/essentials/history-mode.html)


## Node.js(Express)の場合

自分が作ったものがこれだったのでもう少し詳しく。

公式にもあるように、[connect-history-api-fallback](https://github.com/bripkens/connect-history-api-fallback)を使うと良い。

### install

```
npm install connect-history-api-fallback
```

### server.jsの例

`app.use(history())`を追加する位置に注意。
`app.use(serveStatic(__dirname + "/docs"))`よりも後に書くと動作しなくなった。

```js:server.js
const express = require('express')
const serveStatic = require('serve-static')
const history = require('connect-history-api-fallback') // 追加
const port = process.env.PORT || 5000

app = express()
app.use(history()) // 追加
app.use(serveStatic(__dirname + "/docs"))
app.listen(port)
console.log('server started '+ port)
```
AWS IoTからS3にHive形式でデータを格納してAthenaで効率よく検索する

# 要約
　AWS IoTで受信したデータをS3にHive形式として保存すると、AthenaでのPartitionの作成が容易で検索性能向上や費用の削減に効果的。IoTデバイス側で最初からHive形式でトピックを指定しておけばS3へのHive形式での格納が容易。

# 目的
- 複数デバイス、複数センサから収集したデータをAthenaで検索したい。
- データ量が多くなることが想定されるので、検索性能を上げつつつも費用を抑えたい。もちろん検索クエリが簡易であることも重要。
- データを吸い出してから検索するまでの仕組みを簡素化してMVPを素早く実現したい。

# 構成
- IoTデバイス: IoTデバイスは複数あり、各デバイスに搭載された各種センサのデータを収集することを想定する。データのアップロードはAWS IoT Device SDKを用いてAWS IoT CoreのエンドポイントへPublishする。<strong>ここで指定するトピックをHive形式にすることでそのままS3へのデータ格納する。</strong>
- AWS IoT Core: IoTデバイスから受信したデータをルールエンジンで指定するキーに基づいてAmazon S3に格納する。<strong>受信したトピックを処理するためのルールクエリステートメントとアクションを設定することで、S3にHive形式で格納する。</strong>
- Amazon S3: データの格納先。
- Amazon Athena: Amazon S3に格納されたデータに対する検索エンジン。指定デバイスの任意のセンサに対して、時間範囲を指定してデータを取得するユースケースを想定する。

# S3にHive形式で格納する
S3にHive形式で格納することで、容易にAthenaでパーティション分割することができる。パーティション分割により、スキャン対象データの母数を限定することができるため、selectの応答時間や料金を削減することができる。
参考:
https://qiita.com/qiita-kurara/items/4872d2eed6b7d0b73fd4
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/partitions.html


# S3にHive形式で格納するトピックとAWS IoTの設定

## IoTデバイスでPublishするトピック
以下の様なHive形式のトピックにする。

```
your-project/device={デバイス名}/sensor={センサ名}/year={year}/month={month}/day={day}/{hour}-{minutes}.gz
```

`your-project`の部分で格納先のS3バケットを変えるので適宜変更する。
今回想定するIoTデバイスはデバイス名とセンサ名をあらかじめ指定した使い方をするので、Athenaで検索する母数を減らすために先頭で指定する。


## AWS IoTで設定するルールクエリステートメントとアクション

- ルールクエリステートメントではS3バケットへの振り分けと、バケットの中で格納するkeyを指定する。
- `your-project`ごとにルールクエリステートメントを作成して振り分けたいS3バケットをアクションで追加する。
- キーに`${topic()}`を指定することでトピック名をそのままS3格納先に指定することができる。Suffixを追加で付与することでタイムスタンプなどもつけることができる。

### AWS IoTのルールエンジンの設定
![スクリーンショット 2020-12-08 0.14.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/929659/2b5d042a-bbeb-3577-3b1c-7a98c942b9e3.png)

### S3の格納先
![スクリーンショット 2020-12-08 0.18.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/929659/d0e0d247-3b12-c43b-e071-0ac9f05d97fe.png)

# Athenaのクエリ
- テーブルを最初に作成する
- Hive形式部分に新規追加があればパーティションを更新する。本投稿の例では日付でパーティションを分けているので毎日更新する必要がある。また、デバイスやセンサの追加時にもパーティションの更新を実施する。パーティションの更新をしていないと検索してもデータがヒットしない。
- 検索クエリではHive形式で指定した部分を検索条件にすると良い。

テーブルの作成

```
CREATE EXTERNAL TABLE IF NOT EXISTS your-project (timestamp string,Value1 string)
    PARTITIONED BY(device string,sensor string,year int,month int,day int)ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' 
    LOCATION 's3://your-s3-bucket/your-project/';
```

パーティション更新

```
MSCK REPAIR table your-project;
```

データの検索

```
SELECT * FROM your-project
            WHERE device='sample_device'
              AND sensor='sample_sensor'
              AND year=2020
              AND month=12
              AND day=08;
```
Windows10へのAndroid Studio のインストールでHAXM インストールが失敗する

Windows10にAndroid Studioのインストールを行った所、HAXMインストールが失敗しました。

```
Parsing C:\Users\607\AppData\Local\Android\Sdk\tools\package.xml
Android SDK is up to date.
Running Intel® HAXM installer
Failed to install Intel HAXM. For details, please check the installation log: "C:\Users\607\AppData\Local\Temp\haxm_log.txt"
Intel® HAXM installation failed. To install Intel® HAXM follow the instructions found at: https://software.intel.com/android/articles/installation-instructions-for-intel-hardware-accelerated-execution-manager-windows
Installer log is located at C:\Users\607\AppData\Local\Temp\haxm_log.txt
Installer log contents:
=== Logging started: 2020/12/07  23:25:57 ===
This computer does not support Intel Virtualization Technology (VT-x) or it is being exclusively used by Hyper-V. HAXM cannot be installed. 
Please ensure Hyper-V is disabled in Windows Features, or refer to the Intel HAXM documentation for more information.

=== Logging stopped: 2020/12/07  23:25:57 ===
Creating Android virtual device
Android virtual device Pixel_3a_API_30_x86 was successfully created
```

Hyper-Vを有効にするとHAXMインストールが失敗するという過去の記事がいくつか出ましたが、私Dockerを使う人はHyper-Vを無効にできないんでDockerとAndroid Studioって共存できないってことか？！と思ったら、以下の記事

- [Windows Hypervisor PlatformによるアクセラレーションでAVDを動かす](https://qiita.com/keicha_hrs/items/455ee2f2cef36e9c6e1c)でHyper-Vが有効でもAndroid Studio
- [Hyper-VAndroidエミュレーターのサポート
](https://devblogs.microsoft.com/visualstudio/hyper-v-android-emulator-support/)

からHyper-V有効でも使えそうということがわかりやってみました。

## 条件
Windowsの機能でWindowsハイパーバイザープラットフォームを有効にして[OK]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178016/0c568fe4-b903-46bd-8088-708ee8d87c9d.png)

OS再起動してから再度Android Studioのインストールを実施することで解消しました。
複数のInspectorウインドウを一斉に操作する機能を作成する

[PONOS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ponos)の7日目の記事です。

昨日は@nissy_gpさんの[Node.js+Sequelize+MySQLでプライマリーキーをUUIDにする](https://qiita.com/nissy_gp/items/7ab29e82479a3fd27007)でした。

# はじめに

[前回の記事](https://qiita.com/e73ryo/items/f9224efea6be25b525e0)で複数のInspectorウインドウを一度に開く機能を実装しました。
今回は開かれているすべてのInspectorウインドウに対して一括で処理を実行する方法を紹介します。

# 実装

## すべてのInspectorウインドウを取得する

現在Unityエディタ上で開かれているすべてのInspectorウインドウを取得するためには`InspectorWindow.GetAllInspectorWindows()`メソッドを利用します。

[UnityCsReference/InspectorWindow.cs at master · Unity-Technologies/UnityCsReference · GitHub](https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/Inspector/InspectorWindow.cs)

UnityEditorにinternalとして定義されている `InspectorWindow`クラスの機能を直接呼び出すことはできないため、前回の記事と同様にリフレクション機能を使ってメソッド実行します。

```c#
var inspectorWindowType = Assembly.Load("UnityEditor").GetType("UnityEditor.InspectorWindow");
var mathodInfo = inspectorWindowType.GetMethod("GetAllInspectorWindows", BindingFlags.NonPublic | BindingFlags.Static);
var inspectorWindows = mathodInfo.Invoke(null, null) as EditorWindow[];
```

これで、開いているInspectorウインドウの配列を取得することができました。
なお、その後のウインドウ操作を行いやすいように、`EditorWindow`の配列として取得しています。

あとはこの配列内の要素を操作をしていけばOKです。

## すべてのInspectorウインドウを閉じるサンプル

サンプルとして「開いているすべてのInspectorウインドウを閉じる機能」のコードを掲載します。

```c#
static void CloseAllInspector()
{
    var inspectorWindowType = Assembly.Load("UnityEditor").GetType("UnityEditor.InspectorWindow");
    var mathodInfo = inspectorWindowType.GetMethod("GetAllInspectorWindows", BindingFlags.NonPublic | BindingFlags.Static);
    var inspectorWindows = mathodInfo.Invoke(null, null) as EditorWindow[];

    foreach (var inspectorWindow in inspectorWindows)
    {
        inspectorWindow.Close();
    }
}
```

# まとめ

今回紹介した`InspectorWindow.GetAllInspectorWindows()`メソッドを利用することで、開いているInspectorウインドウを一括で操作する機能を容易に作成することができます。
開発中、オブジェクトの比較用に頻繁に追加 / 削除されるウインドウなので、こういった機能を利用して効率的に操作していきたいですね。

明日は@nissy_gpさんです！
[Django] ManyToManyフィールドのオブジェクト操作

#実行環境
実行環境は以下の通りです。
Python3 -- Python 3.9.0
Django -- 3.1.3

#DjangoでのManyToManyFieldのオブジェクト操作について
今回、Djangoでwebアプリを作成していく内にハマったオブジェクト操作についてメモがてらに記述しておきます。

また、Djangoの学習を始めたばかりで非効率的なコードばかりですが、何かあればご指摘いただければ幸いです。

##シチュエーション
ユーザー(User)とスケジュール（Schedule）をManyToManyFieldで紐付けるような構成のモデルを作成しました。「マイページにその人のスケジュールのみを表示させる」という実装を行いました。

ちなみに、Userはデフォルトのユーザモデルを使用しており、Scheduleのモデルを以下に示します。

```models.py
class Schedule(models.Model):
    """スケジュール"""
    summary = models.CharField('概要', max_length=50, help_text="○年○月")
    description = models.TextField('詳細な説明', blank=True)
    date = models.DateField('日付')
    members = models.ManyToManyField(User, blank=True)
```

このScheduleのmembersにログイン中のユーザが含まれているもののみ表示させる、ということを実装したくて、以下のようなオブジェクト操作をしましたが、エラーが出てしばらくハマってしまいました。

```views.py
def mypage(request):
    login_user_id = request.user.id
    who = User.objects.filter(id=login_user_id)
    data = Schedule.objects.filter(members=who)
    params = {'id':login_user_id,'who':who,'data':data}
    return render(request, 'YukaSite/mypage.html',params)
```

エラーメッセージは以下です。

```
The QuerySet value for an exact lookup must be limited to one result using slicing.
```

要するにフィルターの条件がリストになっていなかったため、エラーが出ているとのことでした。

○○__in=リスト
の形にすることで、「ある値がリストに含まれているか」で検索を行えます。

よって上記のview.pyのdataのフィルター操作（4行目）を以下のように変え、解決しました。

```
data = Schedule.objects.filter(members__in=who)
```

そもそもデフォルトのユーザ操作もよくわかっておらず無駄な記述が多いと思いますが、
何かあればご指摘いただけると幸いです。
AWSのcloud９でPHPのバージョン古い件

![スクリーンショット 2020-12-06 11.11.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/19e3de79-36c9-2cf5-b941-cd382aff5d9d.png)
WordPressのカレンダープラグインを使ってウェブサイトのカスタマイズの案件を受注したので、久々にAWSで開発環境を作ろうとしました。

でも、ネットで書かれているWordPressの開発環境の手順で行っても、VFS connecion does not existとエラーになってしまいプレビューができない状態です。

![スクリーンショット 2020-12-06 11.11.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/953cbbf2-5649-4d2b-1369-89ebf1398c6f.png)

そのため、色々とネットで調べたのですが、EC2インスタンスの再起動しか方法が見つからず、途方にくれていました。

こちらに記録しましたが、AWSのWordPressのサンプルのドキュメントを参考にして、設定作業を行っていました。

https://teratail.com/questions/308472
テラテイルの回答を見ていて、私のPHPのバージョンが古いことに気がつきました。
そのため、こちらの記事を基に、PHPの7.3をインストールしました。
https://qiita.com/gomiryo/items/28c07d5ee9afd1c325b0

私がWordPressの開発環境作りに参考にした記事は、こちらです。
https://upd.world/wordpress-cloud9/

https://skillhub.jp/blogs/197

https://qiita.com/acecrc/items/a72992a17968d3d9bc00

https://laboratory.kazuuu.net/what-to-do-when-oops-vfs-connection-does-not-exist-is-displayed/

PHPのバージョンを上げたらWordPressのインストールは、できました。
でも、管理画面へのログインができない状態です。
そのため、もう一度環境を作り直そうと思っています。

クライアントの作業のこともあり、cloud９で開発環境作りばかりできないので、断続的に調査復旧を行っていきたいと思っています。

cloud９のIDEの中でタグを使ってアプリケーションの表示ができても、ブラウザにタグを追加して表示ができない場合もあります。
AWSのインターネット共有のドキュメントを読み、設定の確認を行っていきたいと思っています。
なぜリポジトリのインターフェースを UseCase/Application 層に置きたいと考えるか？ (Advent Calendar 2020 アンサー編) 

本記事は、[DDD-Community-Jp Advent Calendar 2020](https://qiita.com/advent-calendar/2020/dddcj) の8日目で、
5日目に @jnuank さんが投稿した [『リポジトリのインターフェースはどこに置く？』](https://qiita.com/jnuank/items/8f86c4661ac126adbd1a) に対して、自分なりに回答したものとなります。

-------

## ■ はじめに

まず「リポジトリのインターフェースをどの層に置くべきか？」という問いに対しては、
その前提として、

- そもそも「ドメイン」とは何であり、
- どんなアーキテクチャを前提としていて(どんな層があって)、
- だからどの層にどんな役割があるか

といった前提を明らかにした上で、「結果として何をどこに配置するのか」を話す必要があるように思います。
これらの概念がずれていると、お互いの話がすれ違う原因となるためです。

次章より、現時点の私が考えている前提と、なぜ UseCase/Application 層に置くか？ という理由について、言語化を試みてみようと思います。

-------

## ■ 前提(アーキテクチャ)

まずは先に前提とするアーキテクチャから。

自分の考え方は、ベースに **クリーンアーキテクチャ** や **ヘキサゴナルなどのオニオン系アーキテクチャ**、ひいては **Port & Adapter パターン** があり、**『いかにドメインを守るか？』** という事を強く意識しています。

詳しい理由については後述しますが、**この「ドメインを守る」という考え** から、
自分は **「リポジトリのインターフェースは UseCase/Application 層に置くべきだ」** と考えています。

　
ただしこれは絶対にという話ではなく、「私はそう考えている」というだけなので注意してください。
一般的には Domain 層に置くパターンが比較的多いように思います(根拠なし)。

また **Domain 層に置くパターンを否定するものではありません。**
何らかのアーキテクチャに則って **皆の意識が統一されていれば何処に置いても構いません。**

----------

## ■ 前提(ドメインと言う言葉と、ドメイン層について)

現時点での自分なりのドメイン、ドメインオブジェクト、ドメイン層に関する考えを以下のように纏めました。

- **ドメイン** とは、**「何らかの活動における知識や体系、それらの領域」** のこと。
- **ドメイン層** とは、**外界から完全に遮断されており、ドメインを形作る小さなルールや「最小単位の仕事(集約)」**を扱う場所。
- **ドメインオブジェクト** とは、**ドメインを形作る「小さな閉じたルール」** のこと。
    - 大小様々な閉じたルールを組み合わせた、**最小単位の閉じた仕事が「集約」** 。
    - 「○○Id」や「××Name」といったクラス(値オブジェクト)が、**「最も小さな閉じたルール」**。

　
**「閉じた」** という言葉を使っているのは、外界の様々なものから隔離されたピュアなルールである事を表すためです。
また **「小さな」** という言葉を使っているのは、ドメイン層に存在するものは、
**「究極に昇華された個々のピュアなビジネスルール/仕事になっていてほしい」** という思いがあるからです。

----------

## ■ だからどうなる？

#### 「永続化はドメインに閉じたルールではない」 ので、ドメイン層ではなく「ユースケース層に置く」。

この考え方のポイントは、**ドメイン層を「外部から閉じて守られ安全になった世界」として扱う** 事です。
そのため、**外部の世界へのやり取りに関わるリポジトリのインターフェースは、ドメイン層に配置したくない** のです。

もしもそれがビジネスのルールだと思うのであれば、それは集約の範囲が間違っているのでは？という感覚(暴論) です。
あくまでも、ユースケース層ですべてをお膳立てしたうえで、閉じた知識群を使って安全にビジネスを駆動したいという考えに則っています。

　
したがって **ユースケース層の役割** は、

- 小さな仕事を連結して、大きな仕事をさせること
- 小さな仕事の準備
- 小さな仕事の結果を何らかの形で取り扱う

となります。

また実際の処理の流れは以下のようなイメージになります。

- ユースケース層で集約を取ってきたりと準備する
- ドメイン層にある集約を介して、ピュアなビジネスルールを組み合わせて小さな仕事をする ==> 集約に変更が発生する
- ユースケース層で集約に起きた変更を永続化する
　

-----------------

## ■ 今後の展望

ドメイン層は閉じたピュアで守られた世界だから、外とつながるリポジトリのインターフェースはユースケース層に置くんだ！
という形になるのですが、最近ではユースケース層とドメイン層とは異なる層がどこかにあって、
そこへインターフェースを置くべきかもしれない、という思いが沸いています。

それは「ユースケース層」という名前から、そこに置くのが本当に最適解なのだろうか？ という点にうっすらとした違和感を覚えているためです。
ドメイン層を閉じたものとできますし、依存関係を外から内のみにも出来てはいるのですが、どうにも理由が後ろ向きでありもう一押しほしい感じがしています。

新しく層を作るべきなのか、それとも Port のような名前でユースケース層に入れるべきなのか・・・
などなど、これらの部分についてはもう少し検討が必要そうです。

改めて何か思いついたら、再度記事にしてみようと思います。
Systemdに環境変数を設定しTomcat起動時にVMのメモリサイズを設定する

#はじめに
以前Tomcatの自動起動の記事を記載したが、メモリをうまく設定できていなかったので調べて対応した時のメモ

#環境
- CentOS8
- OpenJDK8
- Tomcat8.0

#方法

以下のようにEnvironmentを使って、環境変数JAVA_OPTにVMに渡したい引数を指定すればよい。

```/etc/systemd/system/tomcat.service
Environment='JAVA_OPTS=-Xmx1536m -Xmx1536m'
```
CloudWatch Eventsを利用してCodeBuildの環境変数をOverrideし定期実行する方法

この記事は、CloudWatch Eventsを利用し、CodeBuildの環境変数を上書きしつつ定期実行する方法についてまとめたものです。

## アーキテクチャ
シンプルな図になるのですが今回作成したいものは、このような構成を想定しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/c6293d9f-8462-5142-60c3-75c41d6b31f7.png" width="400px">

## やり方
* CloudWatchのコンソールを開き、[イベント]、[ルールの作成]の順に選択します。
* スケジュールから、Cronを選択し、Cron式指定します。
* [ターゲット]より、[ターゲットの追加、CodeBuildプロジェクト]を選択します。
* プロジェクトARNには、ビルドプロジェクトのARNを入力します。
* **CodeBuildに環境変数などのパラメータを渡すには、[入力の構成]、[定数（JSONテキスト）]を選択します。**

## 環境変数をOverrideするにはどうするか
上記の最後に記載した、入力構成から、json形式でパラメータをCodeBuild側に渡すことができます。
実際に渡せるパラメータは、こちらを参照してください。[CodeBuildに渡せるパラメータ](https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/run-build-cli.html)

今回注目するのは、**environmentTypeOverride:**です。
こちらを使用することで、環境変数の上書きができます。
**注意点**
現在(2020/12/8 時点)では、公式のドキュメントのサンプルが**オブジェクトを要素にもつ配列**として書かれていない為、そこが注意点です。
下記のような形式だとうまくいきました。

```Sample.json
{
    "projectName": "Test-Project",
    "environmentVariablesOverride": [
        {
            "name": "testName",
            "value": "testValue",
            "type": "PLAINTEXT"
        }
    ]
}
```

## terraformで実装する場合
上記の設定をterraformで実装する場合は、こちらを参照してください。[Terraformでの実装方法](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target)

実装としては、aws_cloudwatch_event_targetを利用します。また、上記のjsonを定義する方法は、**input**に記載することで適用されます。


```sample.tf

resource "aws_cloudwatch_event_target" "ecs_scheduled_task" {
  target_id = "run-scheduled-task-every-hour"
  arn       = aws_ecs_cluster.cluster_name.arn
  rule      = aws_cloudwatch_event_rule.every_hour.name
  role_arn  = aws_iam_role.ecs_events.arn

  ecs_target {
    task_count          = 1
    task_definition_arn = aws_ecs_task_definition.task_name.arn
  }

  input = <<DOC
{
  "containerOverrides": [
    {
      "name": "name-of-container-to-override",
      "command": ["bin/console", "scheduled-task"]
    }
  ]
}
DOC
}
```

## 参照
[CloudWatch Eventsの設定](https://docs.amazonaws.cn/en_us/AmazonCloudWatch/latest/events/CloudWatch-Events-tutorial-codebuild.html)
[CodeBuildに渡せるパラメータ](https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/run-build-cli.html)
[Terraformでの実装方法](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target)
百聞は一見に如かず、Kubernetes の基礎を学ぼう！

この記事は、[求ム！Cloud Nativeアプリケーション開発のTips！【PR】日本マイクロソフト Advent Calendar 2020](https://qiita.com/advent-calendar/2020/azure-cloudnative) の 3 日目です（後から追っかけで書いています）。

----

Azure Kubernetes Service を始める際、以下の公式ドキュメントが役に立ちます。

* [クイックスタート](https://docs.microsoft.com/ja-jp/azure/aks/kubernetes-walkthrough/?WT.mc_id=AZ-MVP-5001601): クラスターの作成からアプリのデプロイまで
* [チュートリアル](https://docs.microsoft.com/ja-jp/azure/aks/tutorial-kubernetes-prepare-app/?WT.mc_id=AZ-MVP-5001601): クイックスタートの中身をより詳細に説明したもの

どちらも初心者がまず試すには非常に重宝するものですが、Kubernetes 自体やコンテナ技術についての基礎知識がないと手順を実行できても、一体自分は何を実行したのか？ということを理解できないまま終わってしまいます。

Azure Kubernetes Service の実務ではまだ遭遇したことがないですが、基礎を学ばずにただ言われるまま、教わった手順をただ実行しただけでいると、Kubernetes なのにクラスターになっていないとか、用途に応じて柔軟に対応させられないといった状態になります。

そのため、基礎知識を習得しつつ、ハンズオン形式で学ぶことができる以下のコンテンツがおすすめです。

## Kubernetes 自体が初めてという人向けのドキュメント（知識習得）

[Kubernetes 入門](https://docs.microsoft.com/ja-jp/learn/modules/intro-to-kubernetes/?WT.mc_id=AZ-MVP-5001601)

日本語で図示されているので、理解し易いと思います。理解できたら以下のコンテンツをやってみてください。

## Kubernetes は知っているけど、 Azure Kubernetes Service が初めてという人向けのドキュメント（知識習得＆ハンズオン形式で学習）

[Azure での Kubernetes 入門](https://docs.microsoft.com/ja-jp/learn/paths/intro-to-kubernetes-on-azure/?WT.mc_id=AZ-MVP-5001601)

こちらのドキュメントを一通り読むと分かり易いと思います。各モジュール単位で知識チェックがあるので、自分の理解度を客観的に把握もできます。

## 基礎を学んだ後の人向けのドキュメント（知識習得＆ハンズオン形式で学習）

[Azure Kubernetes Service ワークショップ](https://docs.microsoft.com/ja-jp/learn/modules/aks-workshop/?WT.mc_id=AZ-MVP-5001601)

こちらのコンテンツはワークショップ形式で Azure Kubernetes Service の構築を行うので、理解を深めることができるかと思います。

**4 日目は @changeworld の「[Kubernetes 上でイベント駆動処理を実現する KEDA のご紹介！](https://qiita.com/changeworld/items/6d12ab3b047a3f5ae494)」です。引き続きお楽しみください。**
GoogleAppScriptからSlackにグラフ画像をPostする自分用メモ

# 目的など
- Slackのスラッシュコマンドを打つと、スプレッドシートにある某センサーデータのグラフをSlackに返したい
- スラッシュコマンドからの呼び出しは、[こちら](https://qiita.com/Quikky/items/9de56c049304885a4f4f)が参考になった
- Slackに画像をPostする際に、FetchUrlを使ったり、incomingWebhookを使ったものはありましたが、SlackAppライブラリを使ったものが見つけられなかったので、、、（探し方が悪かったかも）
- 初アプリで試行錯誤した（最終的にはとてもシンプルだった）ので、未来の自分宛てのメモです

# GetGraph()
- 特定のスプレッドシートから決めうちグラフを作成する
- チャートを返却
- [この内容をそのまま](https://qiita.com/rf_p/items/0480d85325811017b715)

```
function getGraph(){
  var sheet = SpreadsheetApp.openById(SPREADSHEET_KEY).getSheetByName(SPREADSHEET_SHEETNAME);
  var range = sheet.getDataRange();
  var chart = sheet.newChart().addRange(range).setPosition(1, 3, 0, 0).build();
  sheet.insertChart(chart);
  return chart
}
```
# sendSlack(chart)　
- Slackに画像を送ってレスポンスをログに保存
- 色々試行錯誤した（GoogleDriveに溜めてlinkのURLをメッセージPostしたけど展開されない等等、、、）けれど、[SlackApp](https://qiita.com/soundTricker/items/43267609a870fc9c7453)使ったらとてもシンプルでした、、、、

```
function sendSlack(chart) {
  
  var slackApp = SlackApp.create(SLACK_ACCESS_TOKEN);

  // 対象チャンネル
  var channelId = "#sandbox";
  
  var options = {
    "channels" : channelId,
    'text' :"グラフ",
    'filename' :"chart.jpg"
  };
  var resp = slackApp.filesUpload(chart.getBlob(), options);
  
  console.log(resp);
}

```


# testSlackPost()
- GASからテスト実行をするためのMain文

```
function testSlackPost(){
  var chart = getGraph()
  sendSlack(chart);
}
```
# デバッグのコツ
- いきなりGASから叩かずに、[公式のAPIリファレンス](https://api.slack.com/methods/files.upload)のcurlでSlack側の権限設定が正しいかを確認してから投げるとより良いと思います。

```
curl -F file=@filename.png -F "initial_comment=Shakes the cat" -F channels=#sandbox -H "Authorization: Bearer xoxb-xxxxxxxxxxxxxxxxxxxxxx" https://slack.com/api/files.upload

```
PicoLispをビルドしてみた

PicoLispというLisp処理系があるのですがちゃんと触ったことがなかったので、本記事ではまずビルドをしてみました。

## PicoLispとは

[PicoLisp](https://picolisp.com/)はAlexander Burger氏によって開発されたLisp処理系です。シンプルかつ軽量、クリーンさを奨励し、簡潔なコードが特徴[^1]のようです。また設計目標として「シンプルであること」「制限がないこと」「動的であること」「実践的であること」があったようです[^2]。で組込みのデータベースエンジンやGUIライブラリも標準で含まれており、実用指向でもあるようです。[英語版Wikipediaのページ](https://en.wikipedia.org/wiki/PicoLisp)によると1988年から存在するようで、同ページにあるLisp処理系年代表に拠ればChez Scheme、Emacs Lisp、AutoLISPと同じ時期に生まれた、わりと古くからあるLisp処理系のようです。2016年からPilBox (PicoLisp Box)というPicoLispでAndriodアプリを開発するプロジェクトがスタートしたりと、まだまだ発展しつづけているようです。あとGitHubのorganizationを眺めていたら[LLVM版PicoLispのプロトタイプ](https://github.com/picolisp/pil21)とかありました。

## ビルドする

x86-64アーキテクチャのGNU/Linuxを仮定して話を進めます。ubuntuにおけるbuild-essential相当のパッケージは導入しておいてください。

### ソースをもってくる

まずはダウンロードページ https://software-lab.de/down.html から最新のソースコードを手に入れましょう。本記事執筆時点ではpicoLisp-20.6.tgzが最新でした。`tar xf picoLisp-20.6.tgz`で展開してできたディレクトリ`picoLisp`に移動しましょう。

### ブートストラップに必要なファイルを持ってくる

次に、おそらくVMのコアであると思われる、各64ビットアーキテクチャ向けのアセンブリのソースコードを取得します。https://software-lab.de/x86-64.linux.tgz をwgetして、`picoLisp`ディレクトリ内で展開します。

ちなみに展開して出てくるアセンブリ言語のファイルは、PicoLisp自身を用いて生成されているようでした。そして見直すと処理系のソースコードのほとんどがPicoLispで書かれているので、セルフホストを達成しているのですね。ひえー。

## ビルドする

`src64`ディレクトリに64ビット環境用のソースコードがあるので、これを`make`でビルドします。

これで完了です。~~ちょっと簡単すぎたか~~すごく簡単ですね。

## 起動してみる

ビルドが済んでいれば、picoLispディレクトリにある`pil`コマンドで起動できるようになります。ここでは文法などには踏み込みませんが、以下のようにするとHello Worldできます。

```shell
picoLisp$ ./pil
: (print "hello")
"hello"-> "hello"
```

## 余談、あるいは今後？

PicoLisp自体は「仮想機械の最小かつ有用なアーキテクチャは何か？」という問いに対する答えとして、プログラミング言語設計の研究を行ったその成果物だそうです[^3]。[リファレンスマニュアル](https://software-lab.de/doc/ref.html)にはPicoLispの下にある仮想機械のアーキテクチャについて詳しくドキュメントされているのですが、PicoLispのVMが直接扱えるデータ型は3つ(数値、シンボル、そしてリスト)しかないようです。そしてそれらの3つはVMのもっとも基本的なデータである「セル」(それぞれ64bitのcar部とcdr部のペア)で構成されます。これだけでもおもしろそうなのですが、リファレンスマニュアルではこれらのことについてデータ型のビット表現を例示しながら説明されるので、読むだけで汗が滲んできます。このあたりを掘り下げていきたいところですね。

そしてどうもPicoLisp、ラムダ式がないようです。Wikipediaをいま眺めていたら「クオートされた関数 (quoted function)」なるものがあるのでラムダ式がいらないようです。よくわからないので調べたら["Even small details make a difference!"](https://picolisp.com/wiki/?articlequote)なるドキュメントをみつけました。`quote`の挙動がふつうのLispとは異なるようです。これも気になりますね。

しかも[コルーチンもあるんかーい](https://software-lab.de/doc/ref.html#coroutines)。

[^1]: https://picolisp.com/ のトップページより。
[^2]: https://software-lab.de/doc/ref.html#intro より。
[^3]: https://software-lab.de/doc/ref.html#intro に拠った。
エラー"No space left on device"の対処(linuxのゴミ箱の空にしかた)

このエラーは容量不足が原因である。
ファイルを削除しても空き容量が増えずエラーが解消されないと思ったら、削除したファイルがゴミ箱に残っていた。
ゴミ箱を空にすることで解決した。

```
ゴミ箱(trash)を見つける
[hoge@localhost ~]$ find /home/hoge/ -name “*trash*”

ファイルの削除
[hoge@localhost ~]$ rm -f /home/hoge/.local/share/Trash/files/*
```


`Is a directory`と表示される場合は、`-f`を`-rf`に変更。

参考: [linuxのゴミ箱（trash）はどこにある](https://www.shinbo.org/archives/3756)
【Swift】繰り返し文について〜for-in文〜

#繰り返し文の種類
繰り返し処理を行う代表的な制御構文には、`for-in文`と`while文`が存在します。

**for-in文はシーケンスの要素数によって、
while文は継続条件の評価によって繰り返しの終了を決定します。**

また、`repeat-while文`という制御構文も存在します。
repeat-while文は実行文の初回実行を保証する制御構文になります。

##for-in文
for-in文は、Sequenceプロトコルに準拠している型の要素にアクセスするための制御構文です。

Sequenceプロトコルに準拠している代表的な型には、
**Array\<Element>型**、**Dictionary\<Key, Value>型**などがあります。

for-in文は次のように記述します。
要素名は基本的になんでも構いませんが、
意味のある分かりやすい要素名にした方が分かりやすくなります。

```swift

for 要素名 in シーケンス {
   要素ごとに繰り返し実行される処理
}
```

###Array\<Element>型

**Array\<Element>型の要素をfor-in文で列挙する場合、要素の型はElement型になります。**
つまり、Array\<Int>型の要素をfor-in文で取り出す場合の要素の型はInt型になります。

```swift
let arrayInt = [1, 2, 3, 4, 5]
var count = 0

for int in arrayInt {
    count += int
}

print(count)

実行結果
15
```

`arrayInt`の中に格納されている要素を先頭から順に取り出して、
`for int in arrayInt`のintの中に代入しています。

for-in文の中の処理を全て終えるとarrayIntの次の要素にアクセスしintに入れる。
それをarrayIntの先頭から末尾まで繰り返していきます。


###Dictionary\<Key, Value>型

**Dictionary\<Key, Value>型の要素をfor-in文で列挙する場合、
要素の型は、(Key, value)型のタプルとなります。**

例えば、Dictionary\<String, Int>型の値をfor-in文に渡すと、
要素は(String, Int)型になります。

なお、**Dictionary\<Key, Value>型は要素の順序を保証していない**ため、
環境によっては実行結果の順序が異なるかもしれません。

```swift

let dictionary = ["a": 1, "b": 2]

for (key, value) in dictionary {
    print("Key: \(key), Value: \(value)")
}

実行結果
Key: a, Value: 1
Key: b, Value: 2
```

###Range\<Bound>型

また、範囲型についてもfor-in文で回すことが可能です。

今回は、1から10までの値を順にitemに代入しそれらを足す処理を行っています。


```swift
var count = 0

for item in 1...10 {
    count += item
}

print(count)

実行結果
55
```


これらが代表的なfor-in文になります。

個人的にはif文より使用頻度は低いと思いますが、
かなり重要な制御構文なので絶対に覚えた方が良いと思います。


以上、最後までご覧いただきありがとうございました。
AWSWAFを運用してわかった攻撃手法



## zgrab
- UserAgent
- ブルートフォース攻撃
- `uri": "/owa/auth/logon.aspx"`などのExchangeOnline?を狙っている


```
      {
        "name": "User-Agent",
        "value": "Mozilla/5.0 zgrab/0.x"
      },
```
ユーザ目線でNutanixあれこれ

# これ

[Nutanix Advent Calendar 2020](https://adventar.org/calendars/4998)の8日目の投稿です。
普段Nutanix＋ESXiを運用していて、ふとした瞬間に(3Tierと)視線がぶつかるので
どうにかな
らん
るかなーとおどけた内容をお届けします。
ESXiでなんか書きますって言っちゃったけどユーザ目線でこういうとこいいわよ
って内容になりました。反省はしていない。

※なお本記事はあくまで個人の主観に基づくものであり所属先の団体の意思とは全く関係ございません。
本記事はあくまで1ユーザ(個人の主観)であることにご注意ください。
※宣伝料とかそういった某や忖度もありません。

# ぶっちゃけなにがいいの

### ◯ ファシリティの節約(特にラック本数)

 - 3Tierでいるもの:ノードサーバ、ストレージ、SAN
値
スイッチ
 - Nutanixでいるもの:ノードサーバ、ストレージ、Nutanixライセンス

…ラックって意外とお金かかるんですよね。本数増えると全部使っていなくても
本数(1/2とかあったりもするけども)単位で課金されるので節約が難しい。
※逆に詰め込みすぎると冷却性能だとかにも関わるのでなおややこしい

SANスイッチだけが大きな差分に見えますが相互に配線必要になりますし、
なによりストレージ筐体って大抵(物理的に)大きいですよね(偏見)
※DCで使うのに小さいの買うケースってあんまし見かけないような

更にSANスイッチを経由してノードサーバとストレージ組むので
物理設計も論理設計も大きくなりがちに(＝覚えることが多すぎる…！)
※シンプルな構成っていいですよね

#### イメージ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84344/4d2b915f-adb8-997f-63b0-94e44b97c461.png" width="480px">
※Nutanixの場合、storage controllerが仮想マシン(CVM)としてノード単位に配置されるので
NoisyNeighbor問題や障害時の性能影響もある程度抑えられますね。

### ◯ 学習コスト

3Tierで構成した場合、SANスイッチとストレージレイヤについて更に覚えることが増えますよね。
エンジニアとしてスキルを身に着けるのは大切ですが運用体制を維持するにあたって
学習コストは低いほうが良いはずです。(人の入れ替わりや意思疎通の迅速性などで)
当然Nutanixも学習コストが0ではないものの、[Nutanix Bible](https://nutanixbible.jp/)とかいう<strong>THE 虎の巻</strong>が
平然と公開されているので敷居は断然低いのではないでしょうか。
※よく分からんなぁ…と思われる方はとりあえず読んでみると良いと思います。(読んでるうちに雰囲気がつかめると思います。)

### ◯ 回復力

ファシリティのところでも書きましたが、Nutanixではstorage controllerは
ノードごとに仮想マシン(CVM)として存在するため、storage controller(CVM)の障害時に
ユーザの仮想マシン(UVM)へ与える影響は3Tierの場合よりも分散されます。
また、CVMがなんらか障害のため機能しなくなると自動的にノードごとクラスタから切り離されますが
UVMはネットワーク経由で他のノードのCVMを経由してデータアクセスして動作し続けます。
CVMが障害から復帰するとふんわりと戻り、そのうちUVMも同じノード内のデータにアクセスするようになります。
※データローカリティとデータの再分散(再配置)って実際に運用してると有り難みがすごいです。
(RAIDのリビルドとかもう考えたくもない)

# ESXi(vSphere)ならではという点

- 仮想マシン管理をvCenterからできる
    - コンポーネントや考慮することは増えるけど便利
    - Prism(Element/Central)で良くない？
        - はい…仰る通り…
        - (ただまぁRBACだとかコンピュート面でのクラスタ管理はまだvCenter優位…?)
    - マルチクラスタ構成の管理
        - いま時点(<= AOS 5.18)だとクラスタ間マイグレーション(要はStorage vMotion)がない
        - 逆にシングルクラスタなら別にいいのでは？(StoragevMotionはライセンスがよいお値段)
- NSX(-T)が使える
    - Flowもできること増えてきたけどNSXの成長が最近激しい
    - ネットワーク仮想化の機能がESXi(vmkernel)へオフロードされる
        - CVMへの負荷が減る(が、ESXi側の負担が増える)
        - マイクロセグメンテーションがしたいならAHVでも十分では？

# まとめ

Nutanixの外の人が普段触ってる感触として

- とにかく運用は楽
- ライセンスは高い(と感じる)かもしれない
    - 実際にはハードウェアの価格だけで比較しているケースが大半
    - ファシリティ(ラック維持費とかケーブルとか)や運用面までちゃんと見ましょう
    - リビルドとかリストアって待ち時間多かったり、作業順番がややこしかったり…
    - (なのにやるのは大抵夜中だよね！眠いわ！ミスりそうで怖いわ！！)
- 触ってて楽しい
    - 楽しいよ！
(おめめぐるぐる)

    - 便利機能多い
        - Moveとかクロスハイパーバイザ関連の機能が割とある 
        - DRとかバックアップにも使えるスナップショットが標準装備(ちゃんと考えるとお得)
- 中の人が近い
    - ツイッタにいる(夜中でもいる)
        - 普通にどうでもいいツイートもふぁぼってくる
    - コミュニティまったりしてる
        - 中の人も知らないネタが出てくる(しかもよくある)
        - もはや一種の風物詩

CE版でもESXi使えるようになったそうなので
もっとコミュニティ広がるといいな

おしまい
転職して管理職の同僚ができ1年が過ぎました / 社内読書会のご紹介

いきなりのアドベントカレンダー失礼します。
昨日の記事は @aminkgw さんの [QAの大学生アルバイトが入社1年を振り返る
](https://qiita.com/aminkgw/items/3a73da9c44ce5d7341eb) でした。

岡本浩治(@motchang)と申します。グロービスには2018年の3月からフリーランスの業務委託としてジョインし、その後ちょうど1年前2019年の12月に正社員としてジョインしました。2018年にフリーランスになるまでは、会社員としてテックリードやエンジニアリング・マネージャと呼ばれるような仕事から、小さめのフェーズでのCTOという肩書きまで、様々な仕事に従事してきました。

今これまでのキャリアを思い返してみても、かなり幸せな方なのではないかと思っています。もちろん幸せ一辺倒ではありませんでしたが、しっかりテイク・リスクしてキャリアを積み重ねてきた結果はあったなと感じています。

## フリーランスから再度会社員に

上記の通り、2018年からフリーランスとしてグロービスにジョインしました。これまで新規システムや新規サービスの立ち上げに関わることが多かった事も買われてか、グロービスにジョインした直後から新規サービスの開発を担当し、2019年春にリリース。2019年の夏からまた新しいサービスの開発に着手しています。

この新しいサービスの開発について、さらに社内との連携を密にするためにジョインする事に決めました。

このシステムは Kubernates (AWS EKS), MySQL, Ruby on Rails, GraphQL / TypeScript, React.js というスタックを採用しました。この構成については詳しい記事が数日後のアドベントカレンダーで公開される見込みです。

## 新しい同僚

これまでのキャリアでは、エンジニア、かつ管理職の同僚の同僚という存在は希有なものでしたが、グロービスには現在エンジニアリング・マネージャに相当する人員が複数存在します。これは管理職経験経験者としてはかなり嬉しい環境なのですが、自分と１人目のエンジニアの末永以外は皆管理職経験がなく、管理職として仕事に従事するのはグロービスが初めてというメンバーが半数ほどいます。

グロービスには管理職向けの研修ももちろん存在し、プロフェッショナルな講師がそれぞれの専門分野についてワークショップを交えて講義し、管理職としての立ち上げをサポートしています。が、あくまで一般的な会社員としての管理職研修になってしまいます。

エンジニア以外のどんな職業であれ必要だとは思いますが、エンジニアリング・マネージャーとしての実務を担当するにあたっては、一般的な管理に加えエンジニア特有の問題に向き合っていかねばなりません。そこで「[エンジニアのためのマネジメントキャリアパス](https://www.oreilly.co.jp/books/9784873118482/)」の読書会を提案し、マネージャ同士で仕事内容の目線合わせ、また管理職経験者からの知見共有の場としました。


## 読書会のご紹介

グロービスでは様々な読書会・勉強会が行われていますが、自分が参加する読書会は以下の様な流れで行われることが多いです。

### 準備

日付を見出しにし、次回開催時の範囲の目次を書き出しておきます。

### 勉強会まで

参加者は、勉強会が始まるまでに範囲の内容を予習し、気になった箇所についての感想を記名の上書き出さす。

### 当日

当日参加者は、自分が書いた感想を元に章の内容を議論します。この議論がこのスタイルの勉強会の重要なところ、かつ面白い部分なので、予習重要です。

### 実際の模様

グロービスでは社内の情報ツールとして Notion を利用しているので、ここに書き出しを行いました。実際のログは以下のような感じになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9811/24119c28-6471-4fc2-7045-0ae768d569db.png)

## まとめ

社内読書会の模様を共有させていただきました。同僚と知識レベルや業務にあたる心がけの目線合わせを行うのは大変有意義です。アジャイルサムライにも「みんなを同じバスに乗せる」って書いてあるしね！

[PR] [株式会社グロービスでは一緒に教育に向き合ってくれるエンジニアを積極採用中です。](https://recruiting-tech.globis.co.jp/)
【UE4】VRM4Uを用いてVRMをUE4でインポートする

# 最初に

どうも、ろっさむです。
今回はVRMをUE4でインポートする手順を自分用にまとめていこうと思います。

環境は

- Windows 10
- Unreal Engine 4.26

となっております。

# VRMをUE4にインポート？

こちらはエンジン側でデフォルトで用意しているわけではなく、**[はるべえ haru](https://twitter.com/ruyo_h)さんという方が作成しているプラグインを導入することで可能**になります。



以下が今回使用させて頂く「VRM4U」のGithubのページです。

https://github.com/ruyo/VRM4U

また、公式でも手順はがっつりまとめられているため、インポート後の絵作りなど、公式の手順に従って進めるのがベストかと思います。

https://ruyo.github.io/VRM4U/01_quick-start/

じゃあなぜQiitaにまとめたかというと、自分なりにVRM4Uについての情報をまとめておきたい、ということと、多少オプション回りで気を付けておきたい部分があったのが理由です。

# 手順

まずは「VRM4U」のGithub上のリリースページを開きます。

https://github.com/ruyo/VRM4U/releases

最新の「VRM4U_4_26_20201204.zip」をDLして任意の場所に解凍します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36899/18d745f6-d0e8-ba4e-9217-aa5768330741.png)

今回はヒストリアさんから出ているVR音ゲーム「Airtone」のメインキャラクター「ネオンちゃん」のモデルデータが等が含まれているプロジェクトをアニメーションリターゲットのテストも兼ねて使用しています。
http://airtone-vr.com/news/hp0001/index00130000.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36899/745fdc55-959e-abfa-cf6e-b54f5f27571c.png)

解凍したPluginを任意のゲームプロジェクトのディレクトリ内にコピーか移動を行ってください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36899/be9cb2a1-8ef0-f578-5df4-048b748fee42.png)

その後、上部メニューの `Edit > Plugin`でプラグインウィンドウを表示し、検索窓に `vrm` と打ち込むと「VRM4U」が表示されます。
このプラグインの `Enabled`にチェックマークをつけて、UE4プロジェクトをいったん閉じてから再度起動させましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36899/d0bb84c5-74e6-d1af-286f-2596bd773211.png)


これで有効となりました。
あとはvrm形式のファイルをコンテンツブラウザにDrag&Dropするだけでインポートが可能となります。

今回は `Character`フォルダをコンテンツ下に作成して、cluster.用に用意していたVRMをimportしてみます。

表示されるオプションについて必要そうなものを見ていきます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36899/38c90714-4d33-cd3f-ae13-618e8b840717.png)

| 項目 | 備考|
|------|------|
|VRM Title / Author|VRMの方で持っているVRMの制作者情報などがここに入ります。|
|A-pose(Off to T-pose)|Aポーズにするかどうかです。アニメーションリターゲットを行うのであれば、予め**元々のスケルトンのポーズがAかTかを確認**しておくと良いでしょう。今回はネオンちゃんがTポーズなのでoffにしておきます。|
|Material Type|マテリアルタイプがもう決まっているのであればここで指定することができます。|

他は一旦そのままにして、importボタンを押してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36899/e4d81602-3335-680c-536f-84a77a3c15e7.png)

無事マテリアルなどが自動生成されました。
あとはこちらを `Materials`フォルダなど作成してまとめておきましょう。

明日はこのインポートしたVRMのモデルを使用してアニメーションリターゲットを行います。
業務でチーム開発をしていて思うこと

#チームで開発するのって難しい。。。

Webサービス開発を業務でやっていて大変に思うことが色々あります。
特にチーム開発で進めるときには細心の注意を払います。
（上手くいかないとお互いにストレス溜まりますよね）

今後のためになんとなく現段階で気をつけようと思う点をメモしておきます。

<b>言い方って大事</b>
　⇨　何かお願いすることの連続
　⇨　教えてもらったり教えたり
　⇨　自分の知っている部分は他の人は知らなかったり知っていたり
　　　↪︎誰が上で誰が下かがあまりないかもしれない
　⇨　開発している人は詳しいが、他の人はそのファイル回りをあまり見てないので詳しくない
　⇨　指示が不明確だとかなり困る
　⇨　横柄な態度はよくない
　⇨　指示なのかお願いなのか

<b>何を話したか曖昧になる</b>
　⇨　言った言ってないの問題になる
　　　↪︎メモとるの大事
　⇨　同じイメージをちゃんと共有できているか

<b>人によって開発スピードや順序が違う</b>
　⇨　統一するべき？
　⇨　ペースを合わせるのが大事だし大変

<b>どこまでテキトーにやるか、どこまで厳密にやるか</b>
　⇨　クオリティかスピードか
　⇨　質か量か
　⇨　難しい、日頃からすり合わせするべきかもしれない
　⇨　性格が出る、亀裂を生む可能性も

#今日の名言

お前のためにチームがあるんじゃねぇチームの為にお前がいるんだ!!

-安西先生（湘北高校バスケットボール部顧問）