AWS/Terraform

【Terraform】踏み台ホストをコンテナ(ECS on Fargate)で構築してみた

今回は、Terraformを用いたECS on Fargateの踏み台ホスト(Bastion)の構築方法をご紹介します。

Fargateの踏み台ホストは、AWSのコンテナ利用者には必読といっても過言ではない書籍「AWSコンテナ設計・構築[本格]入門」でも紹介されている構成です。
この構築をTerraformで(できるだけ)自動化してみました。

ECS on Fargateの踏み台ホストとは

ECS on Fargateの踏み台ホストとは、その名の通りコンテナで動作する踏み台ホスト(データベース保守などの作業用環境)で、EC2インスタンスと同様にセッションマネージャーで接続して使用します。
仮想マシン(EC2インスタンス)と比較して、OSレイヤーの管理が不要であったり、必要な時間のみリソースを消費するコスト効率に長けています。
コンテナを中心としたクラウドネイティブな環境で、作業用環境もコンテナで統一したい、なんてケースにも最適です。

構成図

今回構築する構成は以下です。

Terraformのバックエンド用S3バケット・DynamoDB、作業用のCloud9についてのみ、手動で構築します(詳細は「構築手順」で後述)。
今回は設定の便宜上、踏み台ホストをパブリックサブネットに構築します。
プライベートサブネットに配置したい場合は、SSMのVPCエンドポイントもしくはNATGatewayが必要です。

Terraformのバージョン

筆者が使用したTerraformのバージョン情報は以下です。

Terraformのバージョン 1.1.5
AWSプロバイダのバージョン 3.74.0

構築手順

TerraformでECS on Fargateの踏み台ホストを構築する手順です。
※上から順に実施していきます。

Terraformのバックエンド構築

TerraformのバックエンドとなるAWSリソースを手動で構築します。

  • AWSマネジメントコンソールにログイン。
  • Terraformバックエンド用のS3バケット・DynamoDBを手動で構築。

参考:Terraform公式ドキュメント

作業用Cloud9の構築

Terraform実行やコンテナイメージ作成を行う環境として、Cloud9を構築します。
Cloud9用のVPC・サブネットは別途準備してから進めてください(デフォルトVPCでも可)。

  • AWSマネジメントコンソールにて、作業用のCloud9を手動で構築。
  • Cloud9起動後、画面左上の「Preferences」>「AWS SETTINGS」>「AWS managed temporary credentials」の項目をクリックして無効化。
  • IAMロールを任意の名前でEC2用IAMロールとして作成し、AWS管理のIAMポリシーAdministratorAccessをアタッチ。
  • 作成したIAMロールをCloud9の実体であるEC2インスタンスにアタッチ。
  • Cloud9の実体EC2を再起動。

※Cloud9のデフォルト権限ではAWSの操作範囲が制限されているため、IAMロールで広い権限を付与します。
参考:Cloud9からIAM Roleの権限でAWS CLIを実行する

Terraformのコード準備

Terraformおよびコンテナイメージのソースコードが格納されているリポジトリをクローンして、一部のコードを書き換えます。

  • Cloud9上での以下コマンドを実行し、GitHubリポジトリをクローン。git clone https://github.com/dogharasu/terraform-ecs-bastion.git
  • クローンしたリポジトリのファイルterraform/terraform-config.tfにて、あらかじめ手動で作成していたS3バケット名およびDynamoDBテーブル名に書き換える。
    書き換える箇所は以下を参照。

▼terraform/terraform-config.tfの抜粋

############################################################################
# バックエンド設定
############################################################################
terraform {
  backend "s3" {
    bucket         = "dev-s3-terraform-ecs-bastion-20220206" # 手動で作成したバックエンド用バケット名に書き換える
    key            = "state/terraform.tfstate"
    encrypt        = true
    region         = "ap-northeast-1"
    dynamodb_table = "dev-dynamodb-terraform-ecs-bastion" # 手動で作成したバックエンド用テーブル名に書き換える
  }
}

Terraformでデプロイ①

Terraformのデプロイは2回に分けて実施します。
この時点でコンテナイメージ未作成であるため、ECS以外のAWSリソースをデプロイします。

  • Cloud9にてリポジトリのディレクトリterraformへ移動。
  • コマンドterraform init を実行。
  • コマンドterraform applyを実行。
  • AWSリソースのデプロイ完了まで待機。

コンテナのイメージ作成

踏み台ホストとなるコンテナのイメージを作成します。

  • AWSマネジメントコンソールにて、Terraformで作成されたECRのログインコマンドをコピー。
  • Cloud9にてリポジトリのディレクトリdockerへ移動し、コピーしておいたECRのログインコマンドを実行。
  • 同ECRのbuild用コマンドをコピーして実行。
  • 同ECRのタグ付け用コマンドをコピーして実行。
  • 同ECRのpush用コマンドをコピーして実行。

※DockerfileではMySQLクライアントのインストールエラーを回避するめにGPGインポートも記述しています。
参考:MySQLのGPGキー有効期限が切れて、公式リポジトリからインストール出来なくなった話
※セッションマネージャーでコンテナに接続できるようにするため、アクティベーションを実行するようにイメージを作成しています。
参考:AWS公式ドキュメント

Terraformでデプロイ②

手動構築したコンテナイメージを用いて、TerraformでECS on Fargate(踏み台ホスト)を構築します。

  • Cloud9にてリポジトリのディレクトリterraformへ移動。
  • ecs.tf中のコメントアウト(/**/)の記述を削除。
  • terraform applyを実行。
  • AWSマネジメントコンソールにて、ECSタスクが起動完了するまで待機。

Fargateの踏み台ホストへログイン

踏み台ホストへのログイン・踏み台ホストからデータベースへの接続をテストします。

  • AWSマネジメントコンソールにて、セッションマネージャーの画面へ移動。
  • Terraformでデプロイしたコンテナ「Bastion」へ接続。
  • Terraformで構築済みのAuroraクラスターのリーダーエンドポイントをコピーし、以下コマンドを実行して接続できるか確認。
    mysql -h <コピーしたAuroraのエンドポイント> -u admin -p
    ※パスワード:password
  • セッションマネージャーの接続を終了。

Fargateの踏み台ホストを終了

TerraformからECSサービスを更新してタスクを終了

  • Cloud9にて、リポジトリのファイルecs.tfで定義しているECSサービスのdesired_countのパラメータを10に書き換え。
  • terraform applyを実行して、ECSのタスクを終了。

後片付け

今回作成した環境の削除手順です。

  • Cloud9にてリポジトリのディレクトリterraformへ移動。
  • terraform destroyを実行。
  • AWSマネジメントコンソールにて、Cloud9、Cloud9にアタッチされていたIAMロールを削除。
  • Terraformのバックエンド用に作成していたS3バケット、DynamoDBテーブルを削除。
  • CloudwatchLogsにて今回作成されたロググループを削除。

まとめ

今回は、TerraformでECS on Fargateの踏み台ホスト(Bastion)を構築する方法をご紹介しました。
踏み台ホストは作業時のみ起動しておけばいいので、サービスの起動数は普段0で問題ありません。
サービスを作らず直接タスクを作成するでも問題ありませんが、サービスであればタスク数だけ更新すればいいので起動が楽です。
この記事を通して、少しでもECSやTerraform利用のお役に立てれば幸いです。

参考情報