CSA Data UploaderをAmazon Linux 2023で起動するためのCloudFormationを作成しました

CSA Data UploaderをAmazon Linux 2023で起動するためのCloudFormationを作成しました

Clock Icon2025.07.07

はじめに

クラスメソッドが展開しているデータ統合基盤サービス『CSアナリティクス』(以降"CSA")のプロダクト群の1つ、『Data Uploader』を、Amazon Linux 2023 で簡単に起動できるCloudFormation テンプレートを作成しましたので、その内容をご紹介します。

『Data Uploader』については以下のリンクを参照してください。
CSアナリティクス Data Uploader

背景

『Data Uploader』は、さまざまなデータソースからデータを取得し、指定したDWHやストレージにアップロードするための軽量なバイナリアプリです。

これまでは手動でEC2を立ち上げて、任意のフォルダに配置して所定のコマンドを実行することでセットアップしていましたが、自動化して環境構築の手間を減らしたいと思うことがあり、CloudFormationで構築作業を自動化することにしました。

このテンプレートでできること

このCloudFormation テンプレートを使うことで、以下の構成を自動で構築できます。

  • 最新の Amazon Linux 2023 を使用した EC2 インスタンスの起動
  • 指定した VPC / サブネット上に EC2 を配置
  • S3 から Data Uploader のバイナリをダウンロードして起動
  • Session Manager 経由でのログインを可能にする VPC エンドポイントの構築
  • セキュリティグループで Data Uploader へのアクセス元を制限

テンプレートと構成

今回作成したテンプレートとなります。

template.yml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Data Uploader EC2 Instance Template'

Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: VPC ID where the EC2 instance will be launched

  SubnetId:
    Type: AWS::EC2::Subnet::Id
    Description: Subnet ID where the EC2 instance will be launched

  AllowedIpAddress:
    Type: String
    Description: IP address allowed to access the EC2 instance (e.g., 192.168.1.1/32)
    AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$'
    ConstraintDescription: Must be a valid IP CIDR range of the form x.x.x.x/x

  DuS3Bucket:
    Type: String
    Description: S3 bucket name containing the Data Uploader binary
    AllowedPattern: '^[a-zA-Z0-9.-]+$'
    ConstraintDescription: Must be a valid S3 bucket name

  DuS3Key:
    Type: String
    Description: S3 key (path) to the Data Uploader binary (e.g., du/csa_du-latest-linux_x64.tar.gz)
    AllowedPattern: '^.*\.tar\.gz$'
    ConstraintDescription: Must be a valid S3 key ending with .tar.gz

  LatestAmiId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64
    Description: Latest Amazon Linux 2023 AMI ID

Resources:
  # Security Group for VPC Endpoints
  VpcEndpointSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub '${AWS::StackName}-vpc-endpoint-sg'
      GroupDescription: Security group for VPC endpoints
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          SourceSecurityGroupId: !Ref DataUploaderSecurityGroup
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0

  # Security Group for EC2 instance
  DataUploaderSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub '${AWS::StackName}-data-uploader-sg'
      GroupDescription: Security group for Data Uploader EC2 instance
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: !Ref AllowedIpAddress
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref AllowedIpAddress

  # VPC Endpoint for SSM
  SSMVpcEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssm'
      VpcEndpointType: Interface
      SubnetIds:
        - !Ref SubnetId
      SecurityGroupIds:
        - !Ref VpcEndpointSecurityGroup
      PrivateDnsEnabled: true

  # VPC Endpoint for SSM Messages
  SSMMessagesVpcEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssmmessages'
      VpcEndpointType: Interface
      SubnetIds:
        - !Ref SubnetId
      SecurityGroupIds:
        - !Ref VpcEndpointSecurityGroup
      PrivateDnsEnabled: true

  # VPC Endpoint for EC2 Messages
  EC2MessagesVpcEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ec2messages'
      VpcEndpointType: Interface
      SubnetIds:
        - !Ref SubnetId
      SecurityGroupIds:
        - !Ref VpcEndpointSecurityGroup
      PrivateDnsEnabled: true

  # IAM Role for EC2 instance to access S3 and Session Manager
  DataUploaderInstanceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Policies:
        - PolicyName: S3AccessPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                Resource: !Sub 'arn:aws:s3:::${DuS3Bucket}/${DuS3Key}'
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                Resource: !Sub 'arn:aws:s3:::${DuS3Bucket}/${DuS3Key}/*'

  # IAM Instance Profile
  DataUploaderInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref DataUploaderInstanceRole

  # EC2 Instance
  DataUploaderInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: t3.micro
      SubnetId: !Ref SubnetId
      SecurityGroupIds:
        - !Ref DataUploaderSecurityGroup
      IamInstanceProfile: !Ref DataUploaderInstanceProfile
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          yum update -y
          yum install -y aws-cli tar
          yum install -y unixODBC-devel
          aws s3 cp s3://${DuS3Bucket}/${DuS3Key} /tmp/du-binary.tar.gz
          tar -axvf /tmp/du-binary.tar.gz -C /usr/local
          echo 'export PATH=$PATH:/usr/local/csa_du/bin' >> ~/.bash_profile
          source ~/.bash_profile
          which csa_du
          setcap 'cap_net_bind_service=+ep' /usr/local/csa_du/bin/csa_du
          /usr/local/csa_du/bin/csa_du webserver --service install
          sed -i '/^EnvironmentFile=-\/etc\/sysconfig\/csa_data_uploader$/a Environment=HOME=/root' /etc/systemd/system/csa_data_uploader.service
          systemctl daemon-reload
          /usr/local/csa_du/bin/csa_du webserver --service start
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-data-uploader'

Outputs:
  InstanceId:
    Description: ID of the Data Uploader EC2 instance
    Value: !Ref DataUploaderInstance
    Export:
      Name: !Sub '${AWS::StackName}-InstanceId'

  PublicIpAddress:
    Description: Public IP address of the Data Uploader EC2 instance
    Value: !GetAtt DataUploaderInstance.PublicIp
    Export:
      Name: !Sub '${AWS::StackName}-PublicIp'

  SecurityGroupId:
    Description: ID of the security group
    Value: !Ref DataUploaderSecurityGroup
    Export:
      Name: !Sub '${AWS::StackName}-SecurityGroupId'

  SSMVpcEndpointId:
    Description: ID of the SSM VPC Endpoint
    Value: !Ref SSMVpcEndpoint
    Export:
      Name: !Sub '${AWS::StackName}-SSMVpcEndpointId' 

テンプレートの主な構成要素は以下の通りです。

1. パラメータ

テンプレートでは以下のパラメータを指定できます。

  • VpcId / SubnetId: EC2 を配置するネットワーク
  • AllowedIpAddress: SSH / HTTP アクセスを許可するIPアドレス
  • DuS3Bucket / DuS3Key: S3上のData Uploaderバイナリの場所

2. セキュリティグループ

EC2インスタンスに対して、指定されたIPアドレスからのSSHおよびHTTPアクセスを許可するセキュリティグループを作成します。これにより、Data Uploaderへのアクセス元を明示的に制御できます。

3. VPCエンドポイント

EC2インスタンスがSSM経由で操作できるよう、以下の3つのVPCエンドポイントを作成します。

  • com.amazonaws.<region>.ssm
  • com.amazonaws.<region>.ssmmessages
  • com.amazonaws.<region>.ec2messages
    これにより、Session ManagerでEC2に入ることができます。

4. IAMロールとインスタンスプロファイル

EC2インスタンスに以下の権限を付与しています。

  • S3からバイナリを取得するための AmazonS3ReadOnlyAccess
  • SSM経由でアクセスするための AmazonSSMManagedInstanceCore
    また、指定されたS3オブジェクトへの明示的なアクセス許可も付与しています。

5. EC2インスタンスとUserData

EC2インスタンスは t3.micro を使用しています。起動時にUserDataスクリプトが実行され、以下の処理が自動で行われます。

  • 必要なパッケージのインストール(aws-cli、tar、ODBC関連など)
  • 指定されたS3バケットからData Uploaderのバイナリをダウンロード
  • バイナリを展開し、実行パスに追加
  • 必要な権限の付与とサービスとしての起動
    これにより、インスタンス起動直後にData Uploaderが自動的に稼働する状態になります。

実行方法

このテンプレートは、AWS CloudFormationのスタック作成画面にて実行できます。

  1. 事前にS3にData Uploaderのバイナリ(.tar.gz)をアップロードしておきます。
  2. このテンプレートをYAMLファイルとして保存します。
  3. AWSマネジメントコンソールのCloudFormation画面から「スタックの作成」を選び、テンプレートをアップロードして、必要なパラメータ(VPC ID、サブネットID、S3バケット名など)を入力します。

スタックの作成が完了すれば、EC2インスタンスが自動的に立ち上がり、『Data Uploader』が起動します。

出力される情報

テンプレートの実行後、以下の情報が出力されます。

  • EC2インスタンスID
  • パブリックIPアドレス(SSH / HTTPアクセス用)
  • セキュリティグループID
  • SSM VPCエンドポイントID

パブリックIPにブラウザからアクセスすると『Data Uploader』の画面が表示される状態となります。
後日アクセス元のIPを増やしたい場合などは、セキュリティグループIDから該当のセキュリティーグループを特定し、アクセス元を追加します。

まとめ

このテンプレートを使うことで、『Data Uploader』を実行する環境を数分で構築できます。また今回は『Data Uploader』の実行環境を用意するためでしたが、シングルバイナリで動く他のアプリの場合でも、UserDataを見直すなどで応用ができるかと思います。

何かのお役に立てば幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.