プチコード

どこかの誰かの役に立つかもしれないTips的なコードを載せています

HULFT10 Container ServicesのWebAPIを使って配信 / 集信管理情報一括登録

HULFT10 Container Services(Fargate) のお話し。
搭載されているWebAPIを使って、配信 / 集信管理情報を一括登録するbashを作成した。

www.hulft.com

前提

・HULFT10 Container Services Fargate版を使用
・バージョンは10.5.0
・コントロールセンター(管理画面)にアクセス可能な環境であること
・管理情報を登録するJSONを作成済みであること

10.5.0未満のバージョンでは登録APIが実装されていないので使用できない。
慌てず騒がずアップデートした方が幸せになれる。

以降はHULFT10 Container Services Fargate版をコンテナ版HULFTと記載することにする。

難しい点

特にない。
強いて言えば「登録用のJSON作るのメンドクセ」ぐらいである。
JSONは別途作成したCSVを読み込んで、そこから生成するようにした。
JSON作成は大した処理ではないので割愛している。

備考

以降で紹介するbashは自分のローカル環境から実行するものとしている。
これはテスト時に配信 / 集信データを環境に応じて洗い替えする必要があったため。
洗い替えなのでDELETE-INSERTになるのだが、削除用のbashは作成しなかった。
コントロールセンター側で一括削除できるため、どうせテスト用だからと端折ったのが理由。

注意点

コンテナ版HULFTのWebAPIは管理画面へのログインを前提としているので、流れはこのようになる。

  1. HULFTへログイン
  2. WebAPI実行
  3. HULFTからログアウト

よくあるAPIトークンを発行してというものではない。
上記のような流れになるので、WebAPI実行部分はループ処理とした。

配信管理情報一括登録シェル

以下のように実装した。

#!/bin/bash
set -euo pipefail

# ===========================================================
# HULFT配信 / 集信管理データ登録シェル
#
# コンテナHULFTに配信管理データを一括登録
# ENDPOINTの値を変更することで集信管理データ登録可能
#
# arg1:パスワード(管理画面にログインするユーザのパスワード)
# arg2:登録データJSONパス
# ===========================================================

## HULFTログインパスワード
PASSWORD=$1

## 登録データJSONパス
JSON_FILE=$2

LOGIN_URL="https://external-control-xxxx.example.com/api/login"
LOGOUT_URL="https://external-control-xxxx.example.com/api/logout"
ENDPOINT="https://external-control-xxxx.example.com/api/v1/managements/sendings/detail"
COOKIE_FILE="/tmp/hulft_cookie.txt"

## HULFTログイン実行
curl -i -X POST -c $COOKIE_FILE \
    -H 'Content-Type: application/json' \
    -d "{\"user_id\":\"ユーザ名\",\"password\":\"$PASSWORD\"}" \
    $LOGIN_URL

## JSONファイルを1行ずつ読み込みAPI実行
jq -c '.[]' "$JSON_FILE" | while IFS= read -r payload; do
    curl -i -X POST -b $COOKIE_FILE \
        -H 'Content-Type: application/json' \
        -d "$payload" \
        $ENDPOINT
    echo
done

echo "配信管理情報を登録しました"

## HULFTログアウト実行
curl -i -X POST -b $COOKIE_FILE $LOGOUT_URL
exit 0

至ってシンプルである。
bashで書いたので上記のようにしているが、ドメイン部分を別データ(定数やらDBデータやら)で管理して実行APIエンドポイントをアタッチするような書き方の方が都合がいいと思う。
コンテナ版HULFTのWebAPIはエンドポイント内にバージョン情報を持っているので、ここは外から注入してもいいかもしれない。

実行していることは単純で、API実行ユーザのパスワードとJSONファイルをパラメータ指定して実行。
API実行ユーザと書いてはいるが、ログインが必要になるのでrootユーザを使っている。

HULFT管理画面にログイン後、jqを使ってJSONファイルをループ処理。
行毎に取得したJSONデータを配信管理情報として登録。
全て処理が終わったらログアウトして終了。

集信管理情報を登録する場合は、ENDPOINTの値を変更すればいい。
自分は配信用と集信用でbash自体を別にした。

配信登録:api/v1/managements/sendings/detail
集信登録:api/v1/managements/receivings/detail

まとめ

10.5.0以前は配信 / 集信登録APIがなかったので手動で1件ずつ登録していたため、悟りが開けそうな危険性すらあった。
が、WebAPIが実装されたので謎にスピリチュアルな方向へシフトすることもなく救われた。

これはあくまでテスト用なので雑に作っているが、実際は何かしらのフレームワーク(CakePHPとかLaravelとか)側からHTTPクライアントを使って実装する想定でいる。
bash自体の使い勝手としては悪くないが、実運用目線で考えると色々と微妙だとは思う。

ちょっとした処理ならbashで書くという自分がよくないのは承知している。

EC2にAWS SessionManagerインストール

EC2への接続と言えば鍵ファイル認証だったのは昔の話で、今はAWS CLI経由でのSessionManager接続がほとんどだと思う。
AmazonLinux2023になってから、そのAWS CLIも標準搭載されるようになった。

こんな手順が必要なのかどうかわからないが、備忘録として。

環境

AWS CLI バージョン2系

SessionManagerインストーラーをダウンロード

以下のコマンドで最新版を取得。
場所はどこでも構わない

curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"

ダウンロードしたパッケージを解凍

以下のコマンドを実行して解凍

unzip sessionmanager-bundle.zip

インストールコマンドを実行

以下のコマンドを実行してSessionManagerをインストール

sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin

接続確認

AWS CLI + AWSプロファイルを使用して、SessionManagerでEC2インスタンスにアクセスを実行する。

aws ssm start-session --profile 作成したプロファイル名 --target i-から始まるインスタンスID

以下は一例。

aws ssm start-session --profile dummy-profile --target i-01234567890abc

AWSプロファイル前提ではあるが好みもあると思うので、その際はオプションを変更してアクセスキーとシークレットキーでアクセスすること。

接続直後はrootユーザなので、以下のコマンドでec2-userに変更すること。

sudo su --login ec2-user

サーバのグローバルIPを調べるコマンド

バッチサーバから外部に接続する際、先方に蓋開けしてもらうためのIPアドレスが必要になった。
バッチサーバと言えどもVPCの中に存在しており、NATゲートウェイにアタッチしているIPアドレスが対象になる。
そこまではわかっているがコマンド実行した結果と確認したかったというのが背景。

以下のコマンドを実行することでグローバルIPが取得できる。

dig +short myip.opendns.com @resolver1.opendns.com

これだけも何なので簡単に解説を。

digは単純にdigコマンド。
掘るなどと言ったりもするが、Domain Information Groperの略である。

+shortは結果を短く出力するためのオプション。
ここではIPアドレスだけ結果表示させる意図がある。

myip.opendns.comは、OpenDNSが提供している自分のIPアドレスを返す特別なドメイン名。

@resolver1.opendns.comはOpenDNSの公開リゾルバを明示的に指定している。
ちなみにOpenDNSはCisco傘下である。

ざっくり何をしているのかは以下の通り。

  1. resolver1.opendns.com という公開リゾルバに対して、myip.opendns.com のDNSレコードを問い合わせ
  2. 公開リゾルバは「このリクエストを送ってきたIPアドレス」を検出して、それをDNS応答として返す
  3. dig +short 指定しているので、IPアドレスだけが表示される

などと長々書いたが、以下のコマンドの方がお手軽だと思う。

curl icanhazip.com

もちろん、EC2等ではなく自分のPC上でも実行できる。

AWS CLIでセキュリティグループのインバウンドルール一括登録

構築済みのセキュリティグループに対して、インバウンドルールを一括登録する必要があった。
Terraformで〜と思ったが、それも面倒だったのでbash経由でAWS CLIを叩いて登録した。

環境

AWS CLI バージョン2系

前提

自分はAWSプロファイル経由で接続する方式が好きなので、シェルもそのようにしている。
AccessKey + SecretKeyの運用の場合は読み替えること。

最近はあまり踏み台サーバを使わず、SSM経由でのアクセスが多いのでこのようになっている。

登録シェル

以下のシェルを便宜的に「bulk_insert_inbound_rule.sh」という名前にしておく。

#!/bin/bash

#######################################################
#
# AWS SecurityGroupインバウンド一括登録シェル
#
#######################################################

# 引数チェック
if [ "$#" -ne 2 ]; then
    echo "パラメータ不足: $0 <Security Group ID> <AWS Profile>"
    exit 1
fi

# セキュリティグループIDとプロファイル名を引数から取得
GROUP_ID="$1"
PROFILE="$2"

# 登録するIPアドレスリスト(カンマは不要)
IP_ADDRESSES=(
    "xxx.xxx.xxx.xxx"
    "yyy.yyy.yyy.yyy"
    "zzz.zzz.zzz.zzz"
)

# IPアドレスをTCP:22でインバウンドルール追加
for ip in "${IP_ADDRESSES[@]}"; do
    aws ec2 authorize-security-group-ingress \
    --group-id "$GROUP_ID" \
    --ip-permissions IpProtocol=tcp,FromPort=22,ToPort=22,IpRanges="[{CidrIp=${ip}/32,Description='Sample Description'}]" \
    --profile "$PROFILE"
done

echo "インバウンドルール登録完了"
exit 0

実行コマンドは以下のような形になる。

sh bulk_insert_inbound_rule.sh sg-xxxxxxxxxxxx sample-profile

試してないが、CIDRはリストでセットする際に付与してもいいかもしれない。
コマンド実行時に付与しているのはこちらの都合なだけ。
FromPortとToPortを変えれば、様々な許可ルールが生成できると思う。

authorize-security-group-egressに変えればアウトバウンドルールだが、あまり設定することもなさそうな気がする。

EC2に構築したLet's Encryptの自動更新シェル

GitLabが昔から好きで、EC2に構築していわゆる社内オンプレ的に使うことが多い。
実際にオンプレ環境というわけではなく使い方という意味合いの話。
決してGitHubが嫌いという話ではないが、社内プロジェクトはクローズド環境でハンドリングしたいのが理由だったりする。

通常であればRoute53でドメイン取得、ACMSSL証明書発行してALBにアタッチという流れが多い。
が、GitLab構築する際にALBを使わないのでEC2側からLet's Encryptを使っている。
今時こんなことをするのはどうなんだろうと思わなくもないが、自動更新シェルを残しておく。

環境

AmazonLinux2023
AWS CLI バージョン2系

Let's Encryprを更新する際の前提

80番ポートが開いていないとそもそも更新ができない。
やり方はいくつかあると思うが、使用しているセキュリティグループに80番ポートのインバウンド許可をアタッチするのがやりやすいかと思う。

本ページでGitLabと書いてはいるが、通常80番ポートを閉じている環境で使っているLet's Encryptを更新する方法と考えてもらった方がいいかもしれない。
そういう運用をするしないという話はここでは割愛する。

更新シェル

以下のようなシェルを使っている。
とても単純でAWSセキュリティグループIDを指定して、80番ポートのインバウンド許可をアタッチしてLet's Encryptを更新。
更新終了後にインバウンド許可をデタッチするというシンプルなもの。

以下のシェルではログも一応出してはいるが、特に見てはいない。
念のためレベルなのでログ関連の部分は除外してもいいかと思う。

#!/bin/bash

##################################################################
# SSL証明書更新スクリプト
#
# 本スクリプトを実行することでSSL証明書を自動更新する
# 実行はcronから行うが手動でも実行可能だと思われる
##################################################################

# セキュリティグループIDを設定
SECURITY_GROUP_ID="sg-xxxxxxxxxxxxxxxxxxxx"

# ログディレクトリ
LOG_DIR="/home/ec2-user/tool/logs"

# ログファイル名を生成
LOG_FILE="$LOG_DIR/$(date +%Y%m%d%H%M%S)_renewal.log"

# ログファイルに出力設定
exec &> >(tee -a "$LOG_FILE")

# 80番ポートのインバウンド許可をアタッチ(必要あればプロファイル指定等をすること)
aws ec2 authorize-security-group-ingress --group-id "$SECURITY_GROUP_ID" --protocol tcp --port 80 --cidr 0.0.0.0/0

# SSL更新
sudo gitlab-ctl renew-le-certs

# GitLab再設定
sudo gitlab-ctl reconfigure

# 80番ポートのインバウンド許可をデタッチ(必要あればプロファイル指定等をすること)
aws ec2 revoke-security-group-ingress --group-id "$SECURITY_GROUP_ID" --protocol tcp --port 80 --cidr 0.0.0.0/0

exit 0

GitLabで更新用だが、セキュリティグループのインバウンドアタッチ / デタッチは他でも使い回せると思う。