Posted at

Jenkinsに設定しているSlave NodeのIPアドレスとAWS Elastic IPが一致しているか確認する方法

More than 3 years have passed since last update.

皆さん、JenkinsでSlave,Master構成していますか?

Master側のjobをバコバコぶっこんでるとそのうちJenkinsが重くなって「ヒィーー」ってなるので、先におすすめしておきます。

ところでJenkinsのNode設定なのですが、IPアドレス設定ですよね。

EC2インスタンスの場合、Elastic IPで固定すれば、まあ変わることはあんまりないと思いますが、クラウドサーバーの場合、基本

「IPアドレスは変わる」が前提だと思います。

そこで、jenkinsのNode情報からIPアドレスをぶっこ抜いて(JenkinsのリモートAPI)、AWS CLIで設定したNodeのIPアドレスが一致しているか確認するJobをつくってみました。


環境


  • MacOSX(El Capition)


    • Jenkins 2.7




参考にしたサイト


事前準備に必要なもの



  • jenkins


    • OSXの方は brew install jenkins でOK




  • AWS CLI



    • pip install awscli --upgrade --ignore-installed six を打とう




  • jq


    • jsonパーサー

    • OSXな方は brew install jq でOK




  • xmlint


    • OSXなら最初から入ってるはず




JenkinsのNode設定


  • Jenkinsの管理 => ノードの管理

でノード一覧に行きます。

ノードを定義していない場合は、新規ノード作成でノードを作成してください。

その際に

ノード名 = EC2インスタンスのタグName

でノード名とAWS側Nameを一致させといてください。


Jenkins リモートAPIで定義されているノード一覧を取得する


  • jq オプション --raw-output はjqで整形しないレスポンスを返すオプション


/path/to/hoge

bash -lc "curl -s -u ${username}:${password} http://${jenkins url}/computer/api/json | jq --raw-output '.computer[] | .displayName'"


上記を実行すると下記のようなノード名一覧のレスポンスが帰ってきます。

master

{node名1}
{node名2}
{node名3}


各ノードから設定されているIPアドレスをぶっこ抜く

xmllintとsedを使ってIPアドレスだけの状態にしておきます。


/path/to/hoge

curl -s -u "${username}":"${password}" "${jenkins_url}"/computer/"${node}"/config.xml |xmllint --format --xpath '//host' - | sed -e "s/^.*<host.*>\(.*\)<\/host>.*$/\1/")



AWS CLIでパブリックIPをぶっこ抜く

Elastic IP 設定されているインスタンス前提でお話は進めています。


/path/to/hoge

aws ec2 describe-instances \

--filters \"Name=tag:Name,Values=${node}\" \
--query \"Reservations[0].Instances[0].PublicIpAddress\"" \
| sed -e 's/[^"
]*"\([^"]*\)".*/\1/')

sed でダブルコーテーションを除去しています。


上記3つのJOBをつなげるとこんな感じ


/path/to/job

#!/usr/bin/env bash

set -e

username="your username"
password="your password"
jenkins_url="http://{jenkins URL endpoint}"
is_success=0

# jenkins nodeのリストを取得
nodes=$(bash -lc "curl -s -u "${username}":"${password}" ${jenkins_url}/computer/api/json | jq --raw-output '.computer[] | .displayName'")

for node in `echo "${nodes}"`
do
# masterの整合がいらない場合
if [ "${node}" = "master" ]; then
continue
fi

# jenkinsのnode IPアドレスを調べる
jenkins_ip_address=$(curl -s -u "${username}":"${password}" "${jenkins_url}"/computer/"${node}"/config.xml |xmllint --format --xpath '//host' - | sed -e "s/^.*<host.*>\(.*\)<\/host>.*$/\1/")

# AWSのPublic IPを取得
aws_ip_address=$(bash -lc "aws ec2 describe-instances \
--filters
\"Name=tag:Name,Values=${node}\" \
--query
\"Reservations[0].Instances[0].PublicIpAddress\"" \
| sed -e 's/[^"]*"\([^"]*\)".*/\1/')
fi

if [ "${jenkins_ip_address}" != "${aws_ip_address}" ]; then
echo "[FATAL] mismatch node:${node}"
is_success=1
else
echo "[SUCCESS] match node:${node}"
fi

echo "================ jenkins node IP Address ==================="
echo "${jenkins_ip_address}"
echo "================ AWS public IP Address ==================="
echo "${aws_ip_address}"
done
# これでjenkinsのsuccess failureを出し分け
exit $is_success


コレをjobでぶっ込んでおけば、


  • jenkins slave nodeのIPアドレスを間違えてかえてしまった

  • EC2 インスタンスのIPアドレスが変わっちゃった

上記2つをjenkins自信が検知できます。


最後に

以外とすんなりできたので思わず書いてしまった。。。