🔐
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"
}
]
}
]
}
Discussion