目的
AWS SAM を使って Go 言語でサーバーレスアプリケーションを開発するための、環境構築の手順をまとめます。個人的な備忘録を兼ねているため、必須ではない細かな設定なども記載しています。Lambda でサーバーレスアプリケーションの開発をはじめようと思っている方の参考になれば幸いです。
当記事に含まれる内容
当記事に含まれる内容は下記の通りです。ソフトウェアのインストールなどは既にわかりやすい記事があるので、そのリンクを貼っています。
- Hello World アプリケーションについて
- WSL2 の設定
- Docker の設定
- AWS CLI の設定
- Session Manager プラグインの設定
- SAM と Go のインストール
- Ubuntu の環境変数設定の自動化
- VSCode の設定
- SAM プロジェクトの新規作成
- SAM プロジェクトのデプロイ
- AWS コンソールから各サービスを確認
Hello World アプリケーションについて
Hello World アプリケーションは、SAM プロジェクトを新規作成するときに便利なサンプルプロジェクトです。クライアントが API Gateway のエンドポイントにリクエストすると、「Hello, xxx.xxx.xxx.xxx(Lambda の IP アドレス)」とレスポンスを返す、シンプルなアプリです。はじめは、このアプリに変更を加えながらオリジナルのサーバーレスアプリケーションを開発していくと、楽だと思います。
Hello World アプリケーションの AWS 構成
構成図上のサービスの概要をひと言でまとめました。詳細が知りたい方はサービス名のリンクを参照してください。
- Amazon API Gateway:API の開発や公開などが簡単に行えるサービスです。
- AWS Lambda:サーバーレスで小さなプログラムを実行できるサービスです。
- Amazon CloudWatch Logs:AWS リソースのログをモニタリングできるサービスです。
WSL2 の設定
WSL2 (Windows Subsystem for Linux 2) は、Windows 10 上で Linux を動作させるための仕組みです。サーバーレスアプリケーションをローカル環境でテストする際に、SAM は Lambda ファンクションを実行するための Docker コンテナを立ち上げます。Windows 上で Docker を利用するとエラーにハマることが多いので、WSL2 上に環境構築しています。WSL1 だと裏で動いているのは Windows なので、Docker をはじめとする一部のソフトウェアでは不具合が生じます。そのため WSL2 を利用しています。
WSL2 のインストール
インストールがまだの方は、下記のサイトなどを参考にインストールをお願いします。
インストールが終わったら PowerShell を開き、 wsl --list --verbose
コマンドで WSL のバージョンを確認してください。下記のように VERSION が 2 と表示されていれば大丈夫です。
[win] wsl --list --verbose
NAME STATE VERSION
* Ubuntu Running 2
docker-desktop Running 2
docker-desktop-data Running 2
WSL に Windows の PATH を引き継がないように設定する
WSL はそのまま利用すると Windows の環境変数の PATH を引き継ぎます。WSL 上の /etc/wsl.conf
ファイルを編集すると、Windows の PATH を引き継がないように設定できます。
# WSL 上の /etc/wsl.conf ファイルを編集
$ sudo vim /etc/wsl.conf
# wsl.conf がない場合は新規作成
$ sudo touch /etc/wsl.conf
wsl.conf に下記の文言を追記してください。
[interop]
appendWindowsPath = false
以上で WSL の設定は完了です。
参考サイト:WSLでWindowsのPATHを引き継がないようにする方法
Docker の設定
1. WSL に Docker と docker-compose をインストール
Docker の公式サイトなどを参考に、WSL に Docker や docker-compose をインストールします。
Windows に Docker Desktop をインストール
Windows に Docker Desktop をインストールして、Docker Desktop を WSL バックエンドで使えるように設定します。下記のサイトなどを参考に、Docker Desktop のインストールをお願いします。
インストールが完了したら、Dokcer Desktop を開いて以下の設定を行います。
- Settigs > General を開き、Expose daemon on tcp://localhost:2375 without TLS にチェックをつける
- Apply & Restart を実行する
- PC を再起動する ※一度再起動しないと VSCode から WSL に接続した際に Dokcer を起動できないようです。
以上で Docker の設定は完了です。
AWS CLI の設定
AWS CLI は AWS をコマンドラインで操作・管理するためのツールです。インストールがまだの方は、下記のサイトなどを参考にインストールをお願います。
インストールが完了したら aws configure
コマンドを実行して、AWS Access Key ID、AWS Secret Access Key、Default region name、Default output format を入力します。
$ aws configure
AWS Access Key ID [None]: XXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json
設定が完了したら、aws sts get-caller-identity
コマンドで IAM ユーザーアクセス権があることを確認してみます。
$ aws sts get-caller-identity
{
"UserId": "XXXXXXXXXX",
"Account": "XXXXXXXXXX",
"Arn": "arn:aws:iam::XXXXXXXXXX:user/XXXXXXXXXX"
}
以上で AWS CLI の設定は完了です。
Session Manager プラグインの設定
Session Manager プラグインをインストールしておくと、プライベートサブネットの EC2 に SSH で接続したり、SCP で EC2 - ローカル間でファイル転送ができるようになり便利です。興味のある方は、下記のサイトなどを参考にインストールしてみてください。
インストールにあたり WSL の CPU 情報が不明な場合は、sudo lshw -class processor
コマンドで確認できます。
$ sudo lshw -class processor
[sudo] password for funaki:
*-cpu
product: Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz
vendor: Intel Corp.
physical id: 1
bus info: cpu@0
width: 64 bits
capabilities: ...
インストールが完了したら、~.ssh\config
にある SSH 設定ファイルに下記の文言を追記して、Session Manager を通した SSH 接続を有効にします。
# SSH over Session Manager
host i-* mi-*
ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
以上で Session Manager プラグイン の設定は完了です。
プライベートサブネットにある EC2 に SSH や SCP でアクセスする方法について、下記の記事にまとめています。興味のある方はぜひご覧ください。
SAM と Go のインストール
続いて、SAM と Go のインストールです。SAM をインストールする前に Python のパッケージマネージャをインストールする必要があります。以下の順番でコマンドを実行してください。
※Delve という Go のデバッグツールもインストールしていますが、インストールしなくても問題ありません。
1. sudo apt update # Ubuntu のローカルキャッシュ済みパッケージ一覧を更新
2. sudo apt install python3-pip # SAM をインストールするため、Python のパッケージマネージャをインストール
3. sudo pip3 install aws-sam-cli # SAM をインストール
4. sudo apt install golang-go # Go をインストール
5. go install github.com/go-delve/delve/cmd/dlv@latest # Go のリモートデバッグ用に Delve をインストール
※2021年7月の SAM CLI の重要なアップグレードにより、バージョン 1.25 以上へのアップデートが必要になりました。もし古いバージョンをお使いでしたら、下記のコマンドで SAM CLI をアップデートしてください。
sudo pip3 install -U aws-sam-cli # SAM CLI をアップデート
下記のコマンドで Python、SAM、Go がインストールされていることを確認できます。
$ pip3 --version
pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)
$ sam --version
SAM CLI, version 1.21.1
$ go version
go version go1.13.8 linux/amd64
$ dlv version
Delve Debugger
Version: 1.6.0
Build: $Id: 8cc9751909843dd55a46e8ea2a561544f70db34d
以上で SAM と Go のインストールは完了です。
Ubuntu の環境変数設定の自動化
export
コマンドで GOPATH や PATH などの環境変数を設定しても、Ubuntu ターミナルを閉じると初期化されてしまいます。Ubuntu ターミナルを起動する度に環境変数を設定するのは面倒なので、起動時に環境変数が自動で設定されるよう、下記のコマンドで ~.profile
に export
コマンドを追記しておきます。
$ cd # HOME ディレクトリに移動
$ sudo echo export GOPATH=$HOME/go >> .profile # GOPATH の設定
$ sudo echo export PATH=$PATH:$GOPATH/bin >> .profile # PATH の設定
~.profile
ファイルに下記の 2 行が追記されていれば設定完了です。
export GOPATH="Path to Go"
export PATH="Path to Go"/bin
参考サイト:【Linux】環境変数の確認・設定・削除・永続化について
VSCode の設定
Go で開発するときの IDE は VSCode を利用しています。VSCode の設定内容について、備忘録として残しておきます。
1. 拡張機能と依存パッケージをインストール
下記の記事の以下 2 項目を実行します。
-
Go言語の拡張機能をインストール
-
拡張機能の依存パッケージをインストール
以上です。
2. VSCode のフォーマットツールを gofmt に設定
VSCode のフォーマットツールを (1) でインストールした gofmt に設定します。
メニューから File > Preferences > Settings > Extensions > Go > Format Tool の順に開き、gofmt を選択します。
以上です。
gofmt がインストールされているかどうかは、下記のコマンドで確認できます。
$ which gofmt
/usr/bin/gofmt
3. VSCode のリントツールを golangci-lint に設定
VSCode のリントツールを (1) でインストールした golangci-lint に設定します。
メニューから file > Preferences > Settings > Extensions > Go > Lint Tool の順に開き、 golangci-lint を選択します。
以上です。
golangci-lint がインストールされているかどうかは、下記のコマンドで確認できます。
$ golangci-lint --version
golangci-lint has version 1.33.0 built from b90551c on 2020-11-23T05:15:36Z
4. VSCode から WSL に接続
VSCode から WSL に接続する方法は、下記の記事を参考にしました。
上記サイトの以下 2 項目を実行します。
-
Visual Studio Code を WSL へ接続する
-
Ubuntu から Visual Studio Code を起動する
以上です。
SAM プロジェクトの新規作成
ここからは SAM プロジェクトの新規作成に入ります。冒頭で説明した通り、ここでは Hello World アプリケーションを作成していきます。
まず、WSL2 を起動して、サンプルプロジェクトをクローンするディレクトリに移動します。
$ cd /path/to/dir
サンプルプロジェクトを作成するにはsam init [OPTION]
コマンドを使用します。オプションをつけて sam init --runtime go1.x --name プロジェクト名
として、ランタイムとプロジェクト名を指定します。すると、コマンド入力後にテンプレートについて聞かれるので、(1) の「クイックスタートテンプレート」を選択します。
$ sam init --runtime go1.x --name SamTest
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1 # 1 を選択
使用しているコマンドのオプションの解説です。
オプション | 説明 |
---|---|
--runtime | アプリケーションのランタイムを指定します。言語設定のようなものです。 |
--name | プロジェクトディレクトリに任意の名前をつけることができます。 |
その他のオプションが知りたい方は、AWS デベロッパーガイド をご参照ください。
次に、パッケージタイプを聞かれるので、(1) の「Zip」を選択します。
What package type would you like to use?
1 - Zip (artifact is a zip uploaded to S3)
2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 1 # 1 を選択
Cloning from https://github.com/aws/aws-sam-cli-app-templates
最後に、クイックスタートテンプレートの種類を決めます。ここでは、(1) の「Hello World Example」を選択します。
AWS quick start application templates:
1 - Hello World Example
2 - Step Functions Sample App (Stock Trader)
Template selection: 1 # 1 を選択
-----------------------
Generating application:
-----------------------
Name: SamTest
Runtime: go1.x
Dependency Manager: mod
Application Template: hello-world
Output Directory: .
Next steps can be found in the README file at ./SamTest/README.md
以上でサンプルプロジェクトが作成されます。
プロジェクトの内容は下記の通りです。
.
├── Makefile <-- 自動ビルドや自動デプロイなどの設定を記載
├── README.md <-- プロジェクトの説明ファイル
├── hello-world <-- Lambda ファンクションのコードを格納するディレクトリ
│ ├── main.go <-- Lambda ファンクションのコード
│ └── main_test.go <-- ユニットテスト
└── template.yaml <-- SAM テンプレート
template.yaml
ファイルは SAM テンプレートと呼ばれるもので、CloudFormation を拡張したものになっています。SAM テンプレートのリソースには Lambda ファンクション(AWS::Serverless::Function)しか記載されていませんが、暗黙的に以下のリソースが作成されます。各サービスの当アプリでの役割も簡単に記載しておきます。
- Amazon API Gateway:API Gateway が提供するエンドポイントへのリクエストをトリガーに Lambda が起動します。
- IAM ロール:Lambda にアタッチされる IAM ロールです。Lambda に各 AWS サービスへのアクセス権を与えます。
- Amazon CloudWatch ロググループ:Lambda のログをモニタリングするためのロググループです。
SAM プロジェクトのデプロイ
では、サンプルプロジェクトの Hello World アプリケーションを、このまま AWS にデプロイしていきたいと思います。
1. プロファイルの設定
デプロイする前に、デプロイ先の AWS アカウント を確認しておきましょう。僕の場合は、名前付きプロファイル を設定して、プロファイルを切り替えることでデプロイ先を指定しています。
プロファイルを設定済みの方は、aws configure list
コマンドで現在使用中のプロファイルを表示できます。
$ aws configure list
Name Value Type Location
---- ----- ---- --------
profile Name manual --profile
access_key ****************XXXX shared-credentials-file
secret_key ****************XXXX shared-credentials-file
region ap-northeast-1 config-file ~/.aws/config
まだ IAM ユーザーのアクセスキーとシークレットアクセスキーを作成していない方は、下記の記事を参考に作成してください。
プロファイルの設定がまだの方は、aws configure --profile プロファイル名
で設定できます。
$ aws configure # デフォルトのプロファイルを設定
$ aws configure --profile Name # 名前付きプロファイルを設定
2. ビルド
デプロイ先の AWS アカウントのプロファイルの設定が完了したら、sam build
コマンドでビルドします。
$ sam build
Building codeuri: /path/to/project/dir/SamTest/hello-world runtime: go1.x metadata: {} functions: ['HelloWorldFunction']
Running GoModulesBuilder:Build
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
以上でビルド完了です。
3. デプロイ
はじめてデプロイする場合は、sam deploy --guided
コマンドを利用し、スタック名やリージョンなどを指定します。
$ sam deploy --guided
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Not found
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]: SamTest
AWS Region [ap-northeast-1]:
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]: y # Yes を選択
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: Y # Yes を選択
HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]: # Yes を選択
SAM configuration file [samconfig.toml]: # デフォルトの samconfig.toml で作成
SAM configuration environment [default]: # デフォルトの default で設定
~省略~
Successfully created/updated stack - SamTest in ap-northeast-1
下記に、質問される内容を記載しておきます。
- スタック名:CloudFormation にデプロイするスタックの名前。これはアカウントと地域に固有である必要があります。プロジェクト名から始めるとわかりやすいです。
- AWSリージョン:アプリをデプロイする AWS リージョンを指定します。
- 展開前に変更を確認する:Yes に設定すると、デプロイするときにリソースの変更内容を確認できます。No に設定すると、リソースの変更内容が表示されないまま自動的にデプロイされます。
-
SAM CLI IAMロールの作成を許可する:AWS SAM テンプレートは、作成された Lambda ファンクションが他の AWS サービスにアクセスするために必要な IAM ロールを作成します。デフォルトでは、最低限必要な権限を持つIAMロールが作成されます。Lambda にアタッチする IAM ロールを自分で作成する場合には、オプションで
--capabilities CAPABILITY_NAMED_IAM
を指定する必要があります。 -
引数をsamconfig.tomlに保存:Yes に設定すると、選択した内容がプロジェクト内の samconfig.toml ファイルに保存されます。samconfig.toml を作成しておくと、次回以降のデプロイは
sam deploy
コマンドだけで実行することが可能です。
質問にひと通り回答したら、ビルドしたプログラムが S3 にアップロードされ、template.taml で定義した AWS リソースが作成されていきます。
"Successfully created/updated stack" というメッセージが表示されたら、デプロイ完了です。
ターミナルに表示されている Outputs に、デプロイされた Lambda ファンクションのエンドポイント(Value)が記載されています。
Key HelloWorldAPI
Description API Gateway endpoint URL for Prod environment for First Function
Value https://xxxxxxxx
ブラウザからエンドポイントにアクセスしてみます。
以上のように表示されれば、デプロイ成功です。
ここから少しずつコードに変更を加えたり、SAM テンプレートに変更を加えたりしていくと、オリジナルのサーバーレスアプリケーションを開発することができます。
AWS コンソールから各サービスを確認
最後に、AWS のコンソールから作成したアプリの各サービスを見てみます。なお、各サービスには自動で名前がつけられていますが、SAM テンプレートを使って任意の名前をつけることができます。
CloudFormation
CloudFormation > スタック の順に開くと、sam deploy --guided
で指定したスタック名でスタックが作成されていることがわかります。スタック名をクリックすると詳細を確認できます。SAM CLI を使ってデプロイした場合、SAM テンプレートの内容をもとに CloudFormation で各リソースが作成されることがわかると思います。2 回目以降のデプロイでは、このスタックを更新して各リソースに変更を加えていくことができます。
AWS Lambda
Lambda > 関数 の順に開くと、新たに Lambda ファンクションが作成されていることがわかります。関数名から詳細を確認できます。
API Gateway
API Gateway を開くと、新たに API が作成されていることがわかります。API 名から詳細を確認できます。
CloudWatch ロググループ
CloudWatch > ロググループ の順に開くと、新たにロググループが作成されていることがわかります。ロググループ名から Lambda のログファイルを見ることができます。
以上で当記事の内容は終了です。お疲れさまでした!
おわりに
説明が簡単になってしまったところや、今回書ききれなかった内容などは、時間を見つけて修正したり続編の記事などを書いていけたらと思っています。
最後までお読みいただき、ありがとうございました!