Pythonスクリプトで作業を自動化
ユースケース
- Pythonスクリプト と シェルスクリプト を組み合わせる。
- Pythonのparamikoモジュールを使って、AWS VPC内の踏み台サーバに自動ログインする
- 自動ログイン後に、シェルスクリプトで対象のインスタンスに対して踏み台サーバからpingコマンドを複数回実行する
想定する環境
- AWSのVPCは以下のような構成
- VPC内はICMPが通るように、セキュリティグループを設定済み
- K-EC2-ProxyHost-1を踏み台としている
スクリプト実行環境
macOS Montrey (12.4)
Python 3.10.4
踏み台サーバ環境
Ubuntu jammy (22.04 LTS)
Bash 5.1.16
※ 以下の3つのファイルを同じディレクトリに保存してください
- ssh_ping_check.py
- ping_check.sh
- aws_instance.txt
AWS Instance List
aws_instance.txt
172.20.10.11
172.20.10.12
172.20.10.254
172.20.20.11
172.20.20.12
Python Script
ssh_ping_check.py
import paramiko
aws_host = 'k-ec2-proxyhost-1.sample.com'
aws_port = 22
aws_user = 'ubuntu'
aws_key_file = '/Users/mashcannu/.ssh/awskey.pem'
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(hostname=aws_host, port=aws_port,
username=aws_user, key_filename=aws_key_file)
except:
print('Error: Cannot connect to a target host.')
ping_script = open('./ping_check.sh').read()
stdin, stdout, stderr = client.exec_command(ping_script)
print(stdout.read().decode())
client.close()
del client, stdin, stdout, stderr
Shell Script
ping_check.sh
#! /bin/sh
input_file=aws_instance.txt
IFS=$'\n';
for target_ip in `cat $input_file`
do
ping $target_ip -c 1 -W 1 > /dev/null
if [ $? -eq '0' ]; then
echo "Host: $target_ip is reachable"
else
echo "Host: $target_ip is NOT reachable"
fi
done
実行結果
Host: 172.20.10.11 is reachable
Host: 172.20.10.12 is reachable
Host: 172.20.10.254 is NOT reachable
Host: 172.20.20.11 is reachable
Host: 172.20.20.12 is reachable
コード解説(Python)
line.py
import paramiko
aws_host = 'k-ec2-proxyhost-1.sample.com'
aws_port = 22
aws_user = 'ubuntu'
aws_key_file = '/Users/mashcannu/.ssh/awskey.pem'
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-
paramiko モジュールを読み込む
-
ホスト、ポート、ユーザ、鍵ファイル を変数として設定する
-
SSHClient()でインスタンスを作成
-
set_missing_host_key_policyは、ホスト鍵が不明なサーバーへの接続時に使用するポリシーの設定
line.py
try:
client.connect(hostname=aws_host, port=aws_port,
username=aws_user, key_filename=aws_key_file)
except:
print('Error: Cannot connect to a target host.')
+ try節のなかで以下を実施
+ "ssh -i /Users/mashcannu/.ssh/awskey.pem ubuntu@k-ec2-proxyhost-1.sample.com" を実行している
line.py
ping_script = open('./ping_check.sh').read()
stdin, stdout, stderr = client.exec_command(ping_script)
print(stdout.read().decode())
- シェルスクリプト ping_check.sh を開く
- client.exec_command(ping_script) でシェルスクリプトを実行 ※ここ重要
- 実行結果を表示
line.py
client.close()
del client, stdin, stdout, stderr
- sshセッションをクローズする。
- 最後の入れないと、色々メッセージが残るのでここで削除
※ 詳しくはこちら
コード解説(Shell)
line.sh
input_file=aws_instance.txt
IFS=$'\n';
for target_ip in `cat $input_file`
- インスタンスリストを呼び込む
+ IFSで、改行(\n)を指定
+バッククォート
ではさみcatコマンドを実行。リストを1行ずつ読み込みtarget_ipに代入する
line.sh
ping $target_ip -c 1 -W 1 > /dev/null
if [ $? -eq '0' ]; then
echo "Host: $target_ip is reachable"
else
echo "Host: $target_ip is NOT reachable"
fi
- forループでtarget_ipに対してpingを実行ubuntuでpingコマンドを実行している