🔐

ECSで動くgolangアプリにタスク定義から環境変数を注入する

に公開

背景

開発環境でのシンプルな環境変数管理

Goアプリケーションで、データベース接続情報(ID、パスワードなど)を.envファイルで管理しています。

開発環境では以下のようなシンプルな認証情報を使用:

DB_HOST=localhost
DB_USER=testuser
DB_PASSWORD=testpass
DB_NAME=testdb
DB_PORT=5432

本番環境での課題

このシンプルな設定をそのままECS on Fargateで動かす際、以下の問題があります:

課題 内容
セキュリティリスク 認証情報が平文でコード管理される
環境の違い DB_HOSTなど、AWSのエンドポイントに変更が必要
運用の難しさ 認証情報の変更時にコンテナイメージの再ビルドが必要

解決方法

ECSのタスク定義で環境変数を注入します。

ここでは触れませんが、さらにAWS Secrets Managerで暗号化した認証情報を使用することで、安全に本番運用できます。

Goアプリケーション側の実装

データベース接続コード

Go言語ではos.Getenv()で環境変数を取得します:

package main

import (
	"fmt"
	"os"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

func connectDB() (*gorm.DB, error) {
	// 環境変数からデータベース接続情報を取得
	dsn := fmt.Sprintf(
		"host=%s user=%s password=%s dbname=%s port=%s sslmode=require TimeZone=Asia/Tokyo",
		os.Getenv("DB_HOST"),
		os.Getenv("DB_USER"),
		os.Getenv("DB_PASSWORD"),
		os.Getenv("DB_NAME"),
		os.Getenv("DB_PORT"),
	)

	db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
	if err != nil {
		return nil, fmt.Errorf("failed to connect database: %w", err)
	}

	return db, nil
}

ポイント:

  • os.Getenv(): 環境変数から値を取得
  • 環境変数名は慣習的に大文字とアンダースコアで記述(DB_HOST, DB_USERなど)
  • sslmode=require: RDSへの接続はSSL/TLSを使用

ローカル開発環境での.envファイル

開発環境では.envファイルで環境変数を定義します:

DB_HOST=localhost
DB_USER=testuser
DB_PASSWORD=testpass
DB_NAME=testdb
DB_PORT=5432

.envファイルを読み込むには、godotenvなどのライブラリを使用します:

import "github.com/joho/godotenv"

func init() {
	// 開発環境でのみ.envを読み込む
	if os.Getenv("APP_ENV") != "production" {
		godotenv.Load()
	}
}

ECSタスク定義での環境変数注入

基本的な環境変数の設定(非推奨)

ECSタスク定義で環境変数を平文で設定する方法です。なお、セキュリティ上の理由から本番環境でパスワードなどの値を直接書くことは非推奨です。

{
  "containerDefinitions": [
    {
      "name": "app",
      "image": "your-ecr-repo/app:latest",
      "environment": [
        {
          "name": "DB_NAME",
          "value": "proddb"
        },
        {
          "name": "DB_HOST",
          "value": "proddb.xxxxxx.ap-northeast-1.rds.amazonaws.com"
        },
        {
          "name": "DB_PORT",
          "value": "5432"
        },
        {
          "name": "DB_USER",
          "value": "produser"
        },
        {
          "name": "DB_PASSWORD",
          "value": "prodpass"
        }
      ]
    }
  ]
}
GitHubで編集を提案

Discussion