LoginSignup
10
2

More than 1 year has passed since last update.

【AWS SAM Go】Go*SAM で環境変数を導入するには

Last updated at Posted at 2021-12-01

前提

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を利用する方法

  1. ルートディレクトリにenv.jsonの配置
  2. template.yamlにて、Globalsセクション、あるいは、ResourcesセクションのEnvironment > Variables 配下に環境変数のKeyを設置
  3. local起動時に、env.jsonを読み込んでもらうオプションを指定する

が必要になります。

  1. ルートディレクトリにenv.jsonの配置
{
    "Parameters": {
      "DB_USERNAME": "ユーザー名",
      "DB_PASSWORD": "パスワード",
      "HOSTNAME": "ホスト名",
      "PORT": "ポート名",
      "DB_NAME": "DB名"
    }
}
  1. template.yamlにて、Globalsセクション、あるいは、ResourcesセクションのEnvironment > Variables 配下に環境変数のKeyを設置
Globals:
  Function:
    Timeout: 5
    Environment:
      Variables:
        DB_USERNAME:
        DB_PASSWORD:
        HOSTNAME:
        PORT:
        DB_NAME:
  1. local起動時に、env.jsonを読み込んでもらうオプションを指定する
> sam local start-api --env-vars env.json

これであとはコード内で環境変数を読み込めばOKです!

main.go
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.tomlstart-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です!

main.go
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)

デプロイ時に環境変数を読み込むには

  1. 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セクションに追加します

template.yaml
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です!

main.go
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)

参照

パラメーターの上書きの仕方

AWS SAM CLI の設定ファイル

localで環境変数の読み込ませ方

sam local start-api

GLobalな環境変数の指定の仕方と、Resourcesごとの環境変数の指定の仕方

AWS SAM テンプレートの Globals セクション

10
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
2