2021年6月9日水曜日

AWS EC2(Amazon Linux 2 AMI)でよく行う設定をシェルスクリプトにしてみました | ライタス株式会社

お世話になります。 新入社員の田所です。

最近AWSでの構築のお仕事が重なり、「これ前もやった設定だな・・・」なんてことをSSHで設定する度に感じました。

なので最低限これはレシピとして持っておいて正解かな?っていう内容をシェルスクリプトにしてみました。
Amazon Linux 2 AMIでの方法ですのでご了承ください。
また、これだけではCloudWatch等サービスとの連携はできず、適切なIAMロールをEC2に適応する必要があります。
今回はEC2側の設定のみです。
※あくまで参考程度にして頂き、細かい設定は各環境に合わせて変更、運用してください。

今回は下記のような設定をスクリプトにしています。
  • 日本時間に設定
  • CloudWatchAgentのインストール、起動
  • ec2-userのロック、新規ユーザーの作成
  • CloudWatchLogsのインストール、設定、起動

↓が作成したものです。

#!/bin/bash

# =====①アップデート======
yum -y update

# =====②インスタンス名を環境変数に定義しておく======
echo "export INSTANCE_NAME='product-ec2-web-1a'" >> /etc/profile
source /etc/profile

# =====③日本時間に設定======
cp -p /usr/share/zoneinfo/Japan /etc/localtime
cat << EOF > /etc/sysconfig/clock
ZONE="Asia/Tokyo"
UTC=true
EOF

# =====④amazon-cloudwatch-agentの設定======
yum install -y amazon-cloudwatch-agent
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s

# =====⑤新規ユーザーを作成し、ec2-userを使用不可にする======
USER_NAME="new_user"
groupadd -g 1010 $USER_NAME
useradd -u 1010 -g 1010 -G 10 $USER_NAME
echo "$USER_NAME ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
cp -R -p /home/ec2-user/.ssh/ /home/$USER_NAME/.ssh/
chown -R $USER_NAME:$USER_NAME /home/$USER_NAME/.ssh/
usermod -s /bin/false ec2-user

# =====⑥CloudwatchLogsの設定======
yum install -y awslogs
cat << 'EOF' > /etc/awslogs/awscli.conf
[plugins]
cwlogs = cwlogs
[default]
region = ap-northeast-1
EOF

# Logsに送信するログの定義
cat << 'EOF' > /etc/awslogs/awslogs.conf
[general]
state_file = /var/lib/awslogs/agent-state
[/var/log/messages]
datetime_format = %b %d %H:%M:%S
file = /var/log/messages
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = EC2-syslog-/var/log/messages
[/var/log/cron]
datetime_format = %b %d %H:%M:%S
file = /var/log/cron
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = EC2-syslog-/var/log/cron
[/var/log/secure]
datetime_format = %b %d %H:%M:%S
file = /var/log/secure
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = EC2-syslog-/var/log/secure
[/var/log/yum.log]
datetime_format = %b %d %H:%M:%S
file = /var/log/yum.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = EC2-syslog-/var/log/yum.log
EOF
sed -i "s/{instance_id}/$INSTANCE_NAME/g" /etc/awslogs/awslogs.conf
systemctl start awslogsd.service
systemctl enable awslogsd.service


補足


  • ②インスタンス名を環境変数に定義しておく
      複数のインスタンス識別しやすくするため環境変数に任意の名前を設定しています。(⑥で使用します)
  • ④amazon-cloudwatch-agentの設定
  • ⑤新規ユーザーを作成し、ec2-userを使用不可にする
      ec2インスタンスはデフォルトユーザーとしてec2-userを生成しますが、セキュリティ的には使用しないことが良いとされていますので、ec2-userをロックし、代わりの新規ユーザー(例ではnew-user)を作成します。
      今後は作成したユーザーでSSH接続できるようになります。
      echo "$USER_NAME ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
      上記コマンドについてはパスワード確認無しで管理者権限のコマンドを実行できてしまいますので、運用にはご注意ください。
  • ⑥CloudwatchLogsの設定
      /etc/awslogs/awslogs.confでどのログファイルを送信するのか定義します。
      書き方の詳細は↓公式ドキュメントを参考
      https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AgentReference.html

      今回は最低限見れるべき状態にしておきたい[/var/log/messages],[/var/log/cron],[/var/log/secure],[/var/log/yum.log]に絞っています。
      webサーバー(apache等)を稼働させている場合はそのログファイルも追加します。
      sed -i "s/{instance_id}/$INSTANCE_NAME/g" /etc/awslogs/awslogs.conf
      上記コマンドは①で定義した環境変数INSTANCE_NAMEの値をログストリーム名にしています。
      こうすることで、CloudWatchLogsで確認すると
      このようにインスタンスを一目で識別できます。

最後このスクリプトをEC2起動設定の「ステップ 3: インスタンスの詳細の設定」の「高度な詳細」の「ユーザーデータ」に張り付けるだけで一気に構築時に実行してくれます。
別の方法としてAnsibleとかで構成管理をすることも可能ですが、他で流用しにくいので、
今回のようにシェルスクリプトで持っておいてユーザーデータに流しこむ方が個人的には好きです!!
Terraformではユーザーデータを使用できるので、これをそのまま使えますね!


では、これからも精進致します!

0 件のコメント:

コメントを投稿