😀

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

2022/11/28に公開

皆さん、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自信が検知できます。

最後に

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

Discussion