LoginSignup
3
1

More than 3 years have passed since last update.

ECSの環境変数に悩んだ末の結論

Posted at

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を設定する方法

ssm.tf
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

.env(tf)
TF_VAR_DB_PASSOWRD = <DBパスワード:****>
variabes.tf
#.envで指定したTF_VAR_がとれて代入される
variable "DB_PASSOWRD" {}
main.tf
DB_PASSOWRD = var.DB_PASSWORD

CI/CDに必要な環境変数

CodeBuildのパラメータはTerraformのvariables.tfで設定する

codebuild.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を呼びだして設定する

taskdef.json
#SSMで指定したkey名を見に行ってくれる。(同一アカウント同一リージョンの場合)
#secret情報、config情報関わらずSSMから値を取得する場合は"secret"内に定義する
"containerDefinitions": [
  {
    "secrets": [
        {
            "name": "DB_PASSOWRD",
            "valueFrom": "SSM_DB_PASSOWRD"
        },
        {
            "name": "DB_HOST",
            "valueFrom": "SSM_DB_HOST"
        }
  }
]

サービスに必要な環境変数

.envに記載する

.env(app)
DB_CONNECTION=mysql
DB_HOST=<taskdefで値を上書き>
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=app-user
DB_PASSWORD=<taskdefで値を上書き>
3
1
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
3
1