💨

VPCエンドポイント経由でECRからイメージをプルする

2024/10/29に公開

はじめに

プライベートサブネットにいるFargate(ECS)がECRからイメージを取ってくる際に、NATゲートウェイを介さずに通信してくれるようになります。
NATゲートウェイは通過したbyte課金がかさみがちなので、コストダウンを図りましょう。

そのまんまのことをやる公式ドキュメントがありますが、これをを読んでもすんなりとは作れない自分のような人向けの記事です。
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/vpc-endpoints.html

VPCエンドポイントとは

VPCエンドポイントによってVPCとAWSサービスがダイレクトで接続され、インターネットゲートウェイ・NAT・VPNなどを使わなくても疎通ができるようになります。

  • インターフェイス
  • ゲートウェイロードバランサ
  • ゲートウェイ

の3タイプがあります。
記事タイトルの構成を実現するには、3つのVPCエンドポイントが必要です。

ECR用エンドポイントだけかと思いきや、ECRは中身がS3なのでS3用エンドポイントも必要なんですね。

CloudFormationでつくる

以下が出来上がったyamlです。

AWSTemplateFormatVersion: "2010-09-09"
Description: Create VPC Endpoint

Parameters:
  EnvironmentName:
    Description: An environment name that will be prefixed to resource names
    Type: String
    Default: dev
    AllowedValues:
      - stg
      - prd

Resources:
  # ---------------------------------------------------------------------- #
  #  VPC Endpoint
  #   - VPC Endpoint の定義
  # ---------------------------------------------------------------------- #
  ECRDkrEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      ServiceName: !Sub com.amazonaws.${AWS::Region}.ecr.dkr
      VpcEndpointType: "Interface"
      VpcId:
        Fn::ImportValue: !Sub "${EnvironmentName}-vpc"
      SecurityGroupIds:
        - Fn::ImportValue: !Join ["-", [!Ref "EnvironmentName", "sg", "vpcendpoint"]]
      SubnetIds:
        - Fn::ImportValue: !Sub "${EnvironmentName}-private-subnet1"
        - Fn::ImportValue: !Sub "${EnvironmentName}-private-subnet2"

  ECRAPIEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      ServiceName: !Sub com.amazonaws.${AWS::Region}.ecr.api
      VpcEndpointType: "Interface"
      VpcId:
        Fn::ImportValue: !Sub "${EnvironmentName}-vpc"
      SecurityGroupIds:
        - Fn::ImportValue: !Join ["-", [!Ref "EnvironmentName", "sg", "vpcendpoint"]]
      SubnetIds:
        - Fn::ImportValue: !Sub "${EnvironmentName}-private-subnet1"
        - Fn::ImportValue: !Sub "${EnvironmentName}-private-subnet2"

  S3GatewayEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
      VpcEndpointType: "Gateway"
      VpcId:
        Fn::ImportValue: !Sub "${EnvironmentName}-vpc"
      RouteTableIds:
        - Fn::ImportValue: !Sub "${EnvironmentName}-private-route-table-az-a"
        - Fn::ImportValue: !Sub "${EnvironmentName}-private-route-table-az-c"

Discussion