今日は、AWSでMySQL検証環境を最速構築の日。
目次
とある日
AWSで、MySQLの環境が検証用としてほしいなと思いました。
そうだ、CDKで作ろうと思い、以降錯誤しながら四時間ぐらいで作りました。
はじめに
想定読者
AWSをそこそこ勉強している人。
CDKをそこそこ使っている人。
注意
- 使用するAWSサービスについての詳細説明はしません
- CDK(Python)で開発しますが、プログラムの詳細説明はしません
- 別環境での構築をしたので、コンソール画面などはありません
- CDKの構築については言及しません
- 別環境から移植してるので間違っている部分があるかと思います
AWSでMySQL最速構築
概要
まず、検証用なので検証時のみ使用することとするので、繰り返し使用できようにする必要があります。
ということで、CDK(Python)でコード化を行います。
構築速度
cdk deploy
を実行してから時間を計測しています。
EC2インスタンスが、操作可能になるまでに約4分。
EC2に接続してMySQLの構築をして約2分。
合わせて、6分あればMySQLが触れる環境が作れます。
MySQL構築環境
理由としては、ユーザデータでコマンドを実行してMySQLをインストールが事前に行えること。
そして、デプロイまでが早いことです。
ほかにも、追加要件が発生した場合に、対応がしやすいことなどが挙げれます。
MySQLバージョン
今回はMySQL8.0を構築します。
CDK
ディレクトリ構造
cdk ├EC2mysql │ ├EC2mysql.py │ └userdata.sh └app.py
cdk synth`や
cdk deploy`はcdkのディレクトリで実行しています。
コード
EC2mysql.py
from aws_cdk import ( aws_ec2, core, aws_lambda as _lambda, aws_apigateway as _apigw, aws_iam as _iam, aws_ec2 as _ec2 ) import json class EC2inMySQL80(core.Stack): def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # VPC vpc_cidr = '10.0.0.0/16' subnet_mask = 24 vpc = _ec2.Vpc( self, id="updraft-cdk-dev-vpc", cidr=vpc_cidr, subnet_configuration=[ _ec2.SubnetConfiguration( cidr_mask=subnet_mask, name='public', subnet_type=_ec2.SubnetType.PUBLIC) ] ) # セキュリティグループ作成 security_group_ssh = _ec2.SecurityGroup( self, id='updraft-cdk-dev-sg', vpc=vpc, allow_all_outbound=True, security_group_name='updraft-cdk-dev-sg-vpc-ie', description='For MySQL validation environment by updraft' ) security_group_ssh.add_ingress_rule( peer=_ec2.Peer.ipv4("xxx.xxx.xxx/xx"), connection=_ec2.Port.tcp(22), ) security_group_ssh = _ec2.SecurityGroup.from_security_group_id( self, id="updraft-cdk-ec2", security_group_id=security_group_ssh.security_group_id ) # AMIイメージ amzn_linux = _ec2.MachineImage.latest_amazon_linux( generation=_ec2.AmazonLinuxGeneration.AMAZON_LINUX_2, edition=_ec2.AmazonLinuxEdition.STANDARD, virtualization=_ec2.AmazonLinuxVirt.HVM, storage=_ec2.AmazonLinuxStorage.GENERAL_PURPOSE ) # userdata 処理 userData = _ec2.UserData.for_linux(shebang='#!/bin/bash') file = "" with open("./EC2mysql/userdata.sh", encoding="utf-8") as t: file = t.readlines() file = "\n".join(file) # ↓が文字列を要求するので改行を追加して配列を文字列に変換処理 userData.add_commands(file) # EC2 ec2 = _ec2.Instance( self, id='updraft-dev-ec2', machine_image=amzn_linux, instance_name="updraft-dev-mysql", instance_type=_ec2.InstanceType("t2.micro"), key_name='updraft-web-ec2-01', security_group=security_group_ssh, # 配列定義するとエラーになる vpc=vpc, user_data=userData ) # EIPの付与 ec2eip = _ec2.CfnEIP( self, id="updraft-ec2eip", instance_id=ec2.instance_id )
EIPについて
peer=_ec2.Peer.ipv4("xxx.xxx.xxx/xx")
:接続するIPを指定してください。
EC2セキュリティグループ
security_group=security_group_ssh, # 配列定義するとエラーになる security_group=[security_group_ssh], # 配列定義するとエラーになる
例とかみても、配列だったので配列にしていたのですがうまく行かず。
初めは、下のように配列で定義していたのですが、エラーが起きうまくできないので配列じゃなくしたらできた。
app.py
import os from aws_cdk import core as cdk from EC2mysql.cdk_stack import EC2inMySQL80 app = core.App() EC2inMySQL80(app, "EC2inMySQL80") app.synth()
EC2mysqlをインポートして呼び出します。
ユーザデータ
概要
MySQLインストールをインストールするのは、EC2のユーザデータでコマンドを実行して行います。
更に、MySQL8.0からはrootのパスワードを初期化しないといけないので、
その処理を自動化するのは難しそうなので。
シェルスクリプトで初期化コマンドを実行して初期パスワードを自動で入力が行われるまでを行います。
それと、MySQLにログインする際にコマンドを打つのはめんどくさいので、それも自動化するシェルスクリプトを作成します。
スクリプト
sudo yum -y remove mariadb - libs sudo rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm sudo yum -y install mysql - community - server mysql - devel sudo systemctl start mysqld.service sudo systemctl enable mysqld.service sudo cat /var/log/mysqld.log | grep 'temporary password' sudo yum -y install expect echo "#!/bin/bash" > /home/ec2-user/mysql.sh echo 'expect -c "' >> /home/ec2-user/mysql.sh echo ' spawn sudo mysql_secure_installation' >> /home/ec2-user/mysql.sh echo ' expect \"Enter your name:\"' >> /home/ec2-user/mysql.sh temp = ' send \"' temp +=`sudo cat /var/log/mysqld.log | grep 'temporary password' | awk '{print $NF}'` temp += '\n\"' echo "$temp" >> /home/ec2-user/mysql.sh echo ' interact"' >> /home/ec2-user/mysql.sh chmod 777 /home/ec2-user/mysql.sh echo " mysql -uroot -p@a@1@2@3@4@55azA@" > /home/ec2-user/mylogin.sh chmod 777 /home/ec2-user/mylogin.sh
MySQLインストール
sudo yum - y remove mariadb - libs sudo rpm - ivh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm sudo yum - y install mysql-community-servermysql-devel sudo systemctl start mysqld.service sudo systemctl enable mysqld.service
手順としては下記のとおりです。
rpmでインストールするMySQLのURLは任意のOSバージョンを選択して下さい。
MySQL初期化
sudo yum - y install expect echo "#!/bin/bash" > /home/ec2-user/mysql.sh echo 'expect -c "' >> /home/ec2-user /mysql.sh echo ' spawn sudo mysql_secure_installation' >> /home/ec2-user/mysql.sh echo ' expect \"Enter your name:\"' >> /home/ec2-user/mysql.sh temp = ' send \"' temp +=`sudo cat /var/log/mysqld.log | grep 'temporary password' | awk '{print $NF}'` temp += '\n\"' echo "$temp" >> /home/ec2-user/mysql.sh echo ' interact"' >> /home/ec2-user/mysql.sh chmod 777 /home/ec2-user/mysql.sh
ここでは、シェルスクリプトを作成しています。
シェルスクリプトで、入力を自動化するのには、expect
が必要だったのでインストール。
expectの自動化については詳しく解説はしません。
もっと良い方法がありそうですが、echo
でmysql.shに出力してます。
sudo mysql_secure_installation
がMySQLの初期化コマンドです。
sudo cat / var / log / mysqld.log | grep 'temporary password' | awk '{print $NF}'
がROOTの初期パスワードがある場所です。
気をつけないといけないポイントしては、mysql.sh
の作成場所を絶対パスで指定しないと。
トップディレクトリで作成されます。
あとは、シェルスクリプトに実行権限を付与します。
MySQLログイン
echo " mysql -uroot -p@a@1@2@3@4@55azA@" > /home/ec2-user/mylogin.sh chmod 777 /home/ec2-user/mylogin.sh
これは単純で、MySQLコマンドを指定しているだけです。
ちゃんと実行権限を付与するだけです。
EC2作成後
cdk deploy
してEC2が作成されたことが確認できたら次のステップに移ります。
EIPが付与されているので、マネージドコンソールでターミナルで接続します。
ec2-userのホームディレクトリに作成したシェルスクリプトがあるので順番に実行します。
- mysql.sh実行
- rootパスワードを”@a@1@2@3@4@55azA@”に設定
あとは、全部Yesでいいと思います。
そのあとは、mysqllogin.sh
を実行してMySQLへアクセスができます。
〆
コード化は便利だと思う今日このごろ。