前提
AWS SAM を用いてAWSのリソースをコードで管理できるようにしています。(Infrastructure as Code)
今回はSAMでAWS lambdaを作成し、その上でGoで書かれた関数を実行できるようにしております。
また、今回利用するSAMはAWS SAM テンプレートを使用してサーバーレスアプリケーションを作って作成しました。
環境はdefault
環境のみで動作させてます。
結論
ローカル起動時(sam local start-api / sam local invoke)とデプロイ時(sam deploy)とで、環境変数の読み込み方法には違いがあります.
ローカル起動時に環境変数を読み込むには
1. env.jsonを利用する方法
- ルートディレクトリに
env.json
の配置 -
template.yaml
にて、Globalsセクション、あるいは、ResourcesセクションのEnvironment > Variables 配下に環境変数のKeyを設置 - local起動時に、
env.json
を読み込んでもらうオプションを指定する
が必要になります。
- ルートディレクトリに
env.json
の配置
{
"Parameters": {
"DB_USERNAME": "ユーザー名",
"DB_PASSWORD": "パスワード",
"HOSTNAME": "ホスト名",
"PORT": "ポート名",
"DB_NAME": "DB名"
}
}
-
template.yaml
にて、Globalsセクション、あるいは、ResourcesセクションのEnvironment > Variables 配下に環境変数のKeyを設置
Globals:
Function:
Timeout: 5
Environment:
Variables:
DB_USERNAME:
DB_PASSWORD:
HOSTNAME:
PORT:
DB_NAME:
- local起動時に、
env.json
を読み込んでもらうオプションを指定する
> sam local start-api --env-vars env.json
これであとはコード内で環境変数を読み込めばOKです!
func Connect() *sql.DB{
db_source_name := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", os.Getenv("DB_USERNAME"), os.Getenv("DB_PASSWORD"), os.Getenv("HOSTNAME"), os.Getenv("PORT"), os.Getenv("DB_NAME"))
log.Print(db_source_name)
db, err := sql.Open("mysql", db_source_name)
または、次のような方法もあります。
2. samconfig.tomlを利用する方法
sam deploy --guided
を行うことで作成されるsamconfig.toml
にstart-api
あるいはlocal-invoke
をする際に送られるパラメーターを上書きする方法になります。
version = 0.1
[default]
# start-apiする場合
[default.local_start_api.parameters]
parameter_overrides = "DbUsername=DB名 DbPassword=パスワード Hostname=ホスト名 Port=ポート名 DbName=DB名"
# local invokeする場合
[default.local_invoke.parameters]
parameter_overrides = "DbUsername=DB名 DbPassword=パスワード Hostname=ホスト名 Port=ポート名 DbName=DB名"
[default.deploy]
[default.deploy.parameters]
parameter_overridesに、上書きしたいパラメーターを記述します。
注意として、この上書きしたいパラメーターを記述する際のKey名はキャメルケースでないと正常に環境変数を読み込んでくれません。
次に、template.yaml
に、パラメータを渡します。
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 5
Environment:
Variables:
DB_USERNAME: !Ref DbUsername
DB_PASSWORD: !Ref DbPassword
HOSTNAME: !Ref Hostname
PORT: !Ref Port
DB_NAME: !Ref DbName
任意のFunction内でのみ環境変数を渡したいときは以下のようにResourcesの中に書いてあげてください。
Globalsに書くと全てのFunctionsに環境変数が適用されます。
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: go1.x
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
Variables:
DB_USERNAME: !Ref DbUsername
DB_PASSWORD: !Ref DbPassword
HOSTNAME: !Ref Hostname
PORT: !Ref Port
DB_NAME: !Ref DbName
これであとはコード内で環境変数を読み込めばOKです!
func Connect() *sql.DB{
db_source_name := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", os.Getenv("DB_USERNAME"), os.Getenv("DB_PASSWORD"), os.Getenv("HOSTNAME"), os.Getenv("PORT"), os.Getenv("DB_NAME"))
log.Print(db_source_name)
db, err := sql.Open("mysql", db_source_name)
デプロイ時に環境変数を読み込むには
-
samconfig.yaml
にパラメーターを上書きするための記述をする
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
parameter_overrides = "DbUsername=DB名 DbPassword=パスワード Hostname=ホスト名 Port=ポート名 DbName=DB名"
次に、template.yaml
に、パラメータを渡します。
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 5
Environment:
Variables:
DB_USERNAME: !Ref DbUsername
DB_PASSWORD: !Ref DbPassword
HOSTNAME: !Ref Hostname
PORT: !Ref Port
DB_NAME: !Ref DbName
次に渡すパラメーターの型をParametersセクションに追加します
Parameters:
DbUsername:
Type: String
DbPassword:
Type: String
Hostname:
Type: String
Port:
Type: String
DbName:
Type: String
Globals:
Function:
Timeout: 5
Environment:
Variables:
DB_USERNAME: !Ref DbUsername
DB_PASSWORD: !Ref DbPassword
HOSTNAME: !Ref Hostname
PORT: !Ref Port
DB_NAME: !Ref DbName
これであとはコード内で環境変数を読み込めばOKです!
func Connect() *sql.DB{
db_source_name := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", os.Getenv("DB_USERNAME"), os.Getenv("DB_PASSWORD"), os.Getenv("HOSTNAME"), os.Getenv("PORT"), os.Getenv("DB_NAME"))
log.Print(db_source_name)
db, err := sql.Open("mysql", db_source_name)