ECSの環境変数(CI/CD,IaC含む)
これまでAKSやECS(Fargate、EC2)を構築してきてずっと悩んでいた環境変数の自分的結論を書こうと思います。
ご参考になったり、より良い方法を教えて頂ければ幸いです。
##◼️環境
サービス概念 | サービス |
---|---|
コンテナ環境 | ECSのFagate |
CI/CD | github,codepipeline(codebuild,codedeploy) |
IaC | Terraform |
##◼️環境変数には2つの考え方がある
環境変数にはconfigとsecretの考え方があると思います。
configは各環境によって変更する必要のあるパラメータのこと。
secretは各環境によって変更する必要のあるパラメータであり、セキュアな情報をして保護する必要のある情報のこと。
2つの考え方を基にしつつ、AWS特有のパラメータに対して個別対応していく必要があります。
大項目 | 中項目 | 説明 |
---|---|---|
環境変数 | Secret | パスワード類。セキュリティエンジニア、SRE、インフラエンジニアが守る |
環境変数 | Config | .envで設定。アプリケーションエンジニアが管理する |
環境変数 | Config | .envで設定できないAWSのパラメータ。例えばIaCで作成したRDSのHost情報などAWSリソースを作成した後に分かる情報。セキュリティエンジニア、SRE、インフラエンジニアが守る |
##■環境変数を設定できるのは3か所ある
- IaCに必要な環境変数 ⇨ TerraformやCDKで設定できる環境変数
- CI/CDに必要な環境変数 ⇨ CodebuildやGitAcrionで設定できる環境変数
- サービスに必要な環境変数 ⇨ .envに記載
##■ECSはTaskdefで環境変数をSSMから取得する
ECSはFargate,EC2に関わらず、taskdef.jsonでパラメータを設定できます。
Secretとenvironmentの二つの設定方法がありますが、configは.envに全て寄せてアプリケーション側管理とするため、Secretのみ設定をします。
SSMパラメータをしてするので実際の値は入らないため安心です。
#実行例
##IaCに必要な環境変数
###AWS自動パラメータはSSMで取得する(String,SecureString)
TerraformでSSMを設定する方法
locals {
secret_parameter = {
#Secret情報
"SSM_DB_PASSWORD" = var.DB_PASSWORD
}
config_parameter = {
#Config情報
"DB_HOST" = aws_rds_cluster.<自身のリソース定義名:main>.endpoint
}
}
resource "aws_ssm_parameter" "secure_string" {
for_each = local.secret_parameter
name = each.key
value = each.value
type = "SecureString"
overwrite = true
}
resource "aws_ssm_parameter" "string" {
for_each = local.config_parameter
name = each.key
value = each.value
type = "String"
overwrite = true
}
以下のようにTerraform環境を作っている。(exportでも同様に設定可能)
https://qiita.com/Tocyuki/items/0cb655e6357d9bf0c40f
TF_VAR_DB_PASSOWRD = <DBパスワード:****>
#.envで指定したTF_VAR_がとれて代入される
variable "DB_PASSOWRD" {}
DB_PASSOWRD = var.DB_PASSWORD
##CI/CDに必要な環境変数
###CodeBuildのパラメータはTerraformのvariables.tfで設定する
resource "aws_codebuild_project" "admin_project" {
'''
environment {
'''
#Codebuildはimageをインストールする場合エラーになることがあるため、Dockerアカウントを作成しておくこと。
#https://aws.amazon.com/jp/premiumsupport/knowledge-center/codebuild-docker-pull-image-error/
environment_variable {
name = "DOCKER_HUB_USER"
value = var.DOCKER_HUB_USER
}
environment_variable {
name = "DOCKER_HUB_PASSWORD"
value = var.DOCKER_HUB_PASSWORD
}
}
###TaskdefでSSMを呼びだして設定する
#SSMで指定したkey名を見に行ってくれる。(同一アカウント同一リージョンの場合)
#secret情報、config情報関わらずSSMから値を取得する場合は"secret"内に定義する
"containerDefinitions": [
{
"secrets": [
{
"name": "DB_PASSOWRD",
"valueFrom": "SSM_DB_PASSOWRD"
},
{
"name": "DB_HOST",
"valueFrom": "SSM_DB_HOST"
}
}
]
##サービスに必要な環境変数
###.envに記載する
DB_CONNECTION=mysql
DB_HOST=<taskdefで値を上書き>
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=app-user
DB_PASSWORD=<taskdefで値を上書き>