AWSを用いたGoの開発環境構築でWindowsユーザがMacユーザに歩み寄るナレッジ

# はじめに

チームの開発環境の構築手順って、みなさまどうしていますか？多くのチームはリポジトリ内のREADMEや、チームWikiに準備することが多いのではないでしょうか？

その際、そのリポジトリ固有のBuild & Deploy & Release手順は記載することは普通だと思いますが、ここで問題になるのは、開発者の環境がWindows, Macなどで割れている場合です。全員Windows or Macで揃えろよってことですが、今の自分のチームはMac:Windows=7:3くらいです。ハードやライセンスの問題から自分たちと同じ用に完全に開発環境を揃えるのも難しいチームも多いでしょう。Amazon Workspacesは一つの解には間違いないですが、なるべく既存の資産を有効活用したいPJも多いと思います。

私のチームの話ですがWindowsは参画したてのメンバーや、アルバイトer社員の方が多く、事実上スキルが低いメンバーが多いのですが、環境構築手順がMacに比重高めなので脳内翻訳が大変な場合があります。

ここではなるべくWindowsユーザがMacユーザ用に書かれた環境構築手順書でも対応できるようなTipsをまとめていきたいと思います。


## 1. 環境構築の設定

WindowsとMacで揺れやすいところです。

* **Windows**: `set AWS_REGION=ap-northeast-1`
* **Mac**: `export  AWS_REGION=ap-northeast-1` 

毎回、exportをsetと入力してもらうのは大変ですが、ここで朗報です。Windowsでも export のコマンドで環境変数を設定できます(!)

```dos
doskey export=set $*
```

上記を実行すると、export を setのエイリアスのように認識してくれます。
これを永続化するためには以下のサイトにあるように、macroファイルを準備し、ショートカットの引数に追加すると良いようです。

https://ricecake362865159.wordpress.com/2019/05/16/cmd%E3%81%A7%E3%82%A8%E3%82%A4%E3%83%AA%E3%82%A2%E3%82%B9%E7%9A%84%E3%81%AA%E3%82%82%E3%81%AE%E3%82%92%E3%81%A4%E3%81%8F%E3%82%8B/

## 2. パスの指定

自分たちのチームでGo系だとよくあるのが、 `cd ${GOPATH}/src/github.com/future-architect/<Repository>` みたいな指定を書かれることです。

Windowsだと `%GOPATH%` と書き換える以外なく、早くも脱落感があります。次の3,4,5のようにWSLをうまく活用しましょう。



## 3. Makeコマンド

特にGoだとMakefileでビルドスクリプトを用意する文化があるので、Windowsユーザはちょっと対応が大変です。Makeコマンド自体は、Windowsでも追加でインストールできるものの、その内部でgrepコマンドなどを利用されたり、shellスクリプトを実行されるとお手上げです。とはいえ、このMakefileをWindows用も用意するのはダブルメンテですし、MacユーザはWindows側の実行テストするのがハードルが高いので、即座に腐っていきそうです。バッドスメルです🐙。

というわけで、WSL一択になります。この時点で1の環境変数設定もWSL側でやったほうが良いという結論になりがちですが、環境構築手順のレベル感を見てどこからWSLを使うかは個別判断になると思います。

Windows標準のコマンドプロンプトから、 `wsl` または `bash` と入力するとコンソールがそのまま切り替わり、 `exit` を打つとWindows側に戻れるので便利です。

ワンラインで処理したい場合は `bash` コマンドだと以下のように実行できます。

```bash
bash -c "ls -la /c/mnt/Users/laqiiz/go/src | grep github"
```

というわけで、Makeコマンドを実行したい場合は以下のように実行できます。

```bash
bash -c "make"
```

WSLを利用したワンラインでの実行方法は以下で詳しく説明されていておすすめです。

https://docs.microsoft.com/ja-jp/windows/wsl/interop

## 4. GOPATHの設定

Go自体は[golang/go Ubuntu](https://github.com/golang/go/wiki/Ubuntu)の手順に従いインストールします。

> sudo add-apt-repository ppa:longsleep/golang-backports
> sudo apt update
> sudo apt install golang-go

sudo する際にProxyオプションが引き継がれない場合は上記に `sudo -E` などのオプションもお試しください。


さて、パスの話です。2で動けば良いですが、おそらく課題として、内部で `go build` する時にWindows側とWSL側で`GOPATH` が異なるのでうまく動かないことも多いと思います。少しややこしいことになりました。対応としてはオススメは Windows側に WSL側の `GOPATH` を寄せることです。

```bash
bash # WSL側へ移動
export GOPATH=/mnt/c/Users/<ユーザ名>/go
exit # Windows側へ戻る
```

これで go build も問題なく動くと思います。

しかし、go generate系も動かない可能性があるので、PATHにも追加します

```bash
export PATH=${PATH}:${GOPATH}/bin
```

Windows側で `go get -u` などでインストールした実行ファイルは `.exe` なのでそのまま使えませんので、WSL側でも実行ファイルを作成する必要がありますが、MakefileにInstall手順も書かれている場合は問題にならないと思います。


## 5. GoアプリのBuild

Goはクロスコンパイルできますので、Windowsでも問題なくLinux用の実行ファイルを作成できます。
しかし、環境手順には以下のようなワンラインで書かれていることも多いのではないでしょうか？

```go:ワンラインで書かれて辛いケース
GOOS=linux GOARCH=amd64 go build ./cmd/your-app/your-app.go
```

この場合、Windowsに翻訳すると以下のように分割する必要があります。

```bash:Windowsだとこれ
set GOOS=linux
set GOARCH=amd64
go build ./cmd/your-app/your-app.go
```

コレでも良いのですが、このまま `go test` すると内部でbuildされる実行ファイルがWindowsで実行できなくなるため、 `set GOOS=windows` と設定し直す必要があり非常にノイジーです。

というわけで、これもWSL側で実行するのがオススメです。

```bash
bash -c "GOOS=linux GOARCH=amd64 go build ./cmd/your-app/your-app.go"
```


## 6. AWSCLIのための設定

Goのよくある使い所の一つとして、サーバサイドのWebAPI開発があると思います。このときAWSにDeployする方も多いのではないでしょうか？ AWSCLIはWindowsでもMacでも公式で準備されているため、何も問題が無いことが多いですがいくつかのAWSコマンド実行する上で、ややこしいことがあります。

### AWS CLIの設定

WSL側へのAWS CLI自体は[公式の手順](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-linux.html)に従いインストールします。

さて、ここでAWSのProfileを利用しているチームも多いでしょう。このProfileをWindows側とWSL側でダブルメンテになるのは、設定漏れで作業効率を落とす原因になる事が多いので、なるべく避けた方が良いと思います。

方針としてはWSL側の設定をWindows側に寄せることにします。例によってWindows側のディレクトリにリンクを張ります。

```bash
ln -s /mnt/c/Users/<User-Name>/.aws ~/.aws
```

これでAWSCLIなどで利用する configやcredentialsをWindows側と共用できるようになりました。もちろん、credentialsは最上位の機密情報ですので、取り扱いはWindows側と同様に注意して取り扱いましょう。


### Lambdaのデプロイ

LambdaでGoアプリをデプロイするときは、以下のようにZIP化する必要があります。

```bash:Lambdaのデプロイ
GOOS=linux GOARCH=amd64 go build ./cmd/lambda/lambda.go

# ZIPファイルを作成
zip -j lambda.zip lambda

# Lambdaのコードデプロイ(Lambda関数自体はすでに作成されている前提)
aws --profile <YOUR_ENV> lambda update-function-code --function-name <YOUR_LAMBDA_NAME> --zip-file fileb://lambda.zip
```

この、 `zip` コマンドはWindowsに無いのですが、公式には `build-lambda-zip` ツールのインストールが推奨されています。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-go-how-to-create-deployment-package.html

これでももちろん良いですが、微妙にWindows側とコマンドが異なりややこしいです。ここでもWSLの出番となります。
複数ラインの場合は `bash -c "コマンド"` と渡すのではなく、bash + exit で切り替えがオススメです。

```bash
bash # Bashを起動
GOOS=linux GOARCH=amd64 go build ./cmd/lambda/lambda.go

zip -j lambda.zip lambda

aws --profile <YOUR_ENV> lambda update-function-code --function-name <YOUR_LAMBDA_NAME> --zip-file fileb://lambda.zip

exit # (必要に応じて)Windows側へ戻る
```


## 7. Docker(for Windwos)

DockerもVolume周りの設定をされていると、微妙にWindowsでうまく動かない可能性があります。[Docker Desktop for WSL 2](https://www.atmarkit.co.jp/ait/articles/2004/01/news008.html)でお試し中です。うまくいき次第追記予定です（2020/03/15）

現時点（2020/04/10）には WSL2 がまだプレビューのため、会社のポリシーによっては利用できない場合は、Windows側のDocker Daemonを、WSL側の docker clientから呼び出せるようにしておくと捗ります。

* [WSL(Bash on Windows)でDockerを使用する](https://qiita.com/yoichiwo7/items/0b2aaa3a8c26ce8e87fe) 

の記事でお手軽に実行できるのでオススメです。


**2020/04/13 追記**

Windows Version 10.0.19041.173]のUpdateが降ってきたので、WSL2を試しました。

* WSL2自体の有効化の手順
   * https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-install
   * 私は `Ubuntu 18.04.3 LTS` をWindowsアプリストアでインストールし、それをDefault設定にしました
    * `wsl --set-version Ubuntu-18.04 2`
    * `wsl --set-default-version 2`
    * `wsl -s Ubuntu18.04`
* Docker for WSL2の手順
    * https://docs.docker.com/docker-for-windows/wsl-tech-preview/
    * 手順に従いDocker for WSL2をインストールし、WSLを開くと以下の画面がでてきます。
    * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6463/408dfee2-bfcb-19b3-a17c-6352e8886e13.png)
    * Enable WSL2をクリックして有効化して設定は終了です
* Legacyの方のDocker設定はいったん残しておく（GolandのTerminalで利用するため）


# 設定について

説明の簡略化のため、今回はコンソール内でexportコマンドで済ましていますが、GoやAWSCLIを毎回利用する場合はWSL側の `~/.profile` などに記載して永続化することをオススメします。


# まとめ

* 環境変数設定くらいであればdoskeyで逃げられる
* それ以上になれば、WSLをうまく利用し逃げるのが楽。その際の設定周りはなるべくWindowsと共用し、ダブルメンテにならないようにするのがオススメ