LoginSignup
0
2

TerraformでS3ゲートウェイ型VPCエンドポイントを導入した

Posted at

最近、サービスインフラのセキュリティやコストを最適化する過程で、プライベートサブネットに配置されたアプリケーションからS3へのアクセス方法を見直しました。これまでのアクセスはインターネット(NAT Gateway)経由でしたが、ゲートウェイ型VPCエンドポイントを導入することで、より安全かつコスト効率的なプライベートアクセスを実現しました。

ディレクトリ構成

Terraformのディレクトリ構成は、モジュール化された構造をとっており、それぞれの環境(dev, stg, prod)ごとに設定を分けています。
modulesディレクトリに、プロジェクトで使用されるTerraformのモジュール(VPCエンドポイント、ルートテーブルなど)を格納しています。

-- terraform-project/
   -- environments/
      -- dev/
         -- backend.tf
         -- main.tf
      -- stg/
         -- backend.tf
         -- main.tf
      -- prod/
         -- backend.tf
         -- main.tf
   -- modules/
      -- vpc_endpoint/
         -- main.tf
         -- variables.tf
         -- outputs.tf
         -- provider.tf
         -- README.md
      -- route_table/
         -- main.tf
         -- variables.tf
         -- outputs.tf
         -- provider.tf
         -- README.md
      -- ...other…
   -- docs/
      -- architecrture.drowio
      -- architecrture.png

実装

エンドポイントの設定

まず、modules/vpc_endpoint/main.tfにVPCエンドポイントの設定を記述します。

modules/vpc_endpoint/main.tf
data "aws_ssm_parameter" "app_vpc_id" {
  name = "/vpc/id/app"
}

resource "aws_vpc_endpoint" "s3" {
  vpc_id            = data.aws_ssm_parameter.app_vpc_id.value
  service_name      = "com.amazonaws.ap-northeast-1.s3"
  route_table_ids   = [var.route_table_app_endpoint_id]
  vpc_endpoint_type = "Gateway"

  policy = <<POLICY
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Action": "*",
      "Effect": "Allow",
      "Resource": "*",
      "Principal": "*"
    }
  ]
}
POLICY

  tags = {
    Name = "app-vpce-s3"
  }
}
  • VPC IDの取得
    vpc_idには、S3へのアクセス元となるアプリケーションが配置されているVPCのIDを指定します。今回はVPCのIDはSSMパラメータストアから取得しています。該当のVPCがTerraform導入以前に手動で作成されたものであるため、直接の変数としての管理ではなく、SSMからの取得を選択しました。

  • ルートテーブルの指定
    route_table_idsには、作成するVPCエンドポイントと関連付けるルートテーブルのIDを指定します。このルートテーブルはTerraformで既に管理下にあるため、変数を介してIDを読み込む形となります。

modules/vpc_endpoint/variables.tf
variable "route_table_app_endpoint_id" {
  description = "The ID of the route table"
  type        = string
}
  • エンドポイントポリシー
    エンドポイントポリシーは、エンドポイントを経由したS3へのアクセスを制御するためのツールです。ポリシーを使用して、特定のバケットや特定のアクションにのみアクセスを許可するなど、細かいアクセス制御を実施できます。

以下は、エンドポイントポリシーを使って特定のS3バケット(my-allowed-bucket)へのGETアクションのみを許可する例です。

policy = <<POLICY
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Action": "s3:GetObject",
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::my-allowed-bucket/*",
      "Principal": "*"
    },
    {
      "Action": "s3:*",
      "Effect": "Deny",
      "Resource": "arn:aws:s3:::my-allowed-bucket/*",
      "Principal": "*",
      "Condition": {
        "StringNotEquals": {
          "s3:action": "s3:GetObject"
        }
      }
    }
  ]
}
POLICY

my-allowed-bucketバケットに対するs3:GetObjectアクションを許可しています。これにより、このバケット内のオブジェクトを読み取ることが可能です。また、同じバケットに対して、s3:GetObjectアクション以外の全てのアクションを拒否しています。これにより、オブジェクトの追加や削除など、その他の操作はできません。

  • タグ付け
    タグName = "app-vpce-s3"は、リソースを管理する際の識別やフィルタリングのために役立ちます。特に大規模な環境や複数のエンドポイントを管理する場合には、適切な命名規則とタグ付けが重要となります。
    これでNAT Gateway経由のコストやオーバーヘッドを回避しながら、プライベートなアクセス経路でS3に接続することができます。
0
2
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
0
2