🚪

AWS CloudFormation で踏み台サーバー構築

2023/02/08に公開

こんにちは、株式会社モリサワ システム開発部門の小室です。

株式会社モリサワはフォントの制作販売がメインの会社です。フォントの制作販売だけではなく、自社でフォント配信プラットフォームも作っていますが、開発部門があることはあまり知られていません。そのため、開発部門を少しでも知ってもらうためにテックブログを始めます!今後、フォントのツールや活用している技術スタック、AI の取り組みなど、システム開発部門が扱っている技術の記事を予定しています。

モリサワで提供している Web サービスは、クラウド型のフォントライセンスサービスの「Morisawa Fonts」や Web フォントサービスの「TypeSquare」などがあります。これらは AWS を中心に構築しており、私は AWS のインフラエンジニアなので、AWS 利用開始時によく作成する「踏み台サーバー」の構築の記事から始めたいと思います。

AWS CloudFormation で踏み台サーバー構築

さて、本題です。
AWS で VPC 環境を利用する場合は、作業用の踏み台サーバーを構築することがよくあると思います。踏み台サーバーはセキュアであることが求められ EC2 の場合は SSM の Session Manager 利用が推奨されています。Session Manager を利用すれば、ssh での接続も不要になり、CloudTrail などで監査ログも取りやすくなります。

以下の CloudFormation テンプレートを利用することで Session Manager で接続可能な EC2 の踏み台サーバーを構築することができます。

AWSTemplateFormatVersion: 2010-09-09
Description: Bastion

Parameters:
  ProjectName:
    Description: Project name
    Type: String
  InstanceType:
    Description: Instance type
    Type: String
    Default: t4g.nano
  VpcId:
    Description: VPC ID for bastion
    Type: String
    Default: vpc-xxxxxxxxxxxxxxxxx
  SubnetId:
    Description: VPC subnet ID for bastion
    Type: String
    Default: subnet-xxxxxxxxxxxxxxxxx

Resources:
  # セキュリティグループ
  BastionSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub ${ProjectName}-bastion
      VpcId: !Sub ${VpcId}
      Tags:
        - Key: Name
          Value: !Sub ${ProjectName}-bastion

  # アウトバウンド
  # Session Manager 向けに 443 を許可
  BastionSGEgressAllowHttps:
    Type: AWS::EC2::SecurityGroupEgress
    Properties:
      GroupId: !GetAtt BastionSecurityGroup.GroupId
      CidrIp: 0.0.0.0/0
      IpProtocol: tcp
      FromPort: 443
      ToPort: 443
      Description: Session Manager (https)

  # IAM ロール
  BastionInstanceRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${ProjectName}-bastion
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        # Session Manager 用
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

  # インスタンスプロファイル
  BastionInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles: [ !Ref BastionInstanceRole ]
      InstanceProfileName: !Sub ${ProjectName}-bastion

  # EC2 インスタンス
  BastionInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0dee43a4abd99c264
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: 8
            VolumeType: gp3
            DeleteOnTermination: true
            Encrypted: true
      EbsOptimized: true
      IamInstanceProfile: !Ref BastionInstanceProfile
      InstanceType: !Ref InstanceType
      CreditSpecification:
        CPUCredits: unlimited
      SubnetId: !Sub ${SubnetId}
      SecurityGroupIds: [ !Ref BastionSecurityGroup ]
      SourceDestCheck: true
      DisableApiTermination: false
      UserData: !Base64 |
        #!/bin/bash
        sudo yum -y update
      Tags:
        - Key: Name
          Value: !Sub ${ProjectName}-bastion

以降、テンプレート内容を補足します。

パラメーター

  • ProjectName : 適当な名称を設定ください
  • InstanceType : 必要に応じてスペック変更ください
    • インスタンスによっては AMI の変更が伴います
  • VpcId : 踏み台サーバーを構築する VPC ID を指定ください
  • SubnetId : 踏み台サーバーを起動するサブネットを指定ください
    • Session Manager での接続になるため、プライベートサブネットでも可能です
    • プライベートサブネットの場合は NAT Gateway または SSM 用 VPC エンドポイント作成が必要です

セキュリティグループアウトバウンド

  BastionSGEgressAllowHttps:
    Type: AWS::EC2::SecurityGroupEgress
    Properties:
      GroupId: !GetAtt BastionSecurityGroup.GroupId
      CidrIp: 0.0.0.0/0
      IpProtocol: tcp
      FromPort: 443
      ToPort: 443

Session Manager は、EC2 内の Agent で待ち受けており、接続には https を用いて通信をおこなうため、外向きに 443 ポートを開ける必要があります。

IAM ロール

Session Manager を利用するために、下記のロールを付与します。S3 などの別のリソースへのアクセスが必要な場合は、適宜ロールを追加します。

      ManagedPolicyArns:
        # Session Manager 用
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

AMI

利用する AMI は、あまり変更されないためパラメータではなく直接記載しています。

      ImageId: ami-0dee43a4abd99c264

最新の AMI は、公式ドキュメントを参考に以下のコマンドなどで取得して設定ください。

aws ssm get-parameter --name /aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.10-hvm-arm64-gp2 --region ap-northeast-1

AWS CLI を利用して接続

この CloudFormation で作成した EC2 には ssm start-session コマンドで --target にインスタンス ID を指定することで接続可能です。

aws ssm start-session --target i-xxxxxxxxxxxxxxxxx --region ap-northeast-1

まとめ

CloudFormation を利用して踏み台サーバーを構築するテンプレートの紹介でした。

ssh 含め、特にポートを開放せずに接続することができるのでセキュアに使うことができます。また Session Manager で接続すると CloudTrail のイベント履歴には、 StartSession のイベントが残りますので、監査ログにもなります。

運用時には常時起動が必要なければ Systems Manager Automation と EventBridge を利用して自動停止するなど業務にあわせて調整ください。

モリサワ Tech Blog

Discussion