
CSA Data UploaderをAmazon Linux 2023で起動するためのCloudFormationを作成しました
はじめに
クラスメソッドが展開しているデータ統合基盤サービス『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 へのアクセス元を制限
テンプレートと構成
今回作成したテンプレートとなります。
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のスタック作成画面にて実行できます。
- 事前にS3にData Uploaderのバイナリ(.tar.gz)をアップロードしておきます。
- このテンプレートをYAMLファイルとして保存します。
- 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を見直すなどで応用ができるかと思います。
何かのお役に立てば幸いです。