オンプレミス エッジデバイス サポート
モチベーション: 顧客に送ったエッジデバイスのドライバとかを一括でアップデートしたい
やりたいこと
- 顧客ネットワーク上のオンプレミスサーバーの管理
- Ansibleによる一括管理
- プロキシ環境サポート
- リモートシェルサポート
やったこと
AWS System Manager Session Manager を使って、自宅外から自宅内のデバイスをAnsibleで一括アプリバージョン更新。
検証
やったことの詳細を書いていく。
準備物
- Mac x 1 (ラップトップ (Ansible実行) PC)
- Raspberry Pi x 1 (管理対象エッジデバイス1)
- Jetson Nano x 1 (管理対象エッジデバイス2)
手順
基本的には 公式のSystems Managerセットアップ を行ったのみ。
0. (コンソール) AWSへの登録
AWSを使ったことがない場合は、まずはAWSへのサインアップから。
1. (ラップトップ) Macに AWS CLI導入
AWS CLIを使ったことがない場合は、まずはMacへのCLI導入。公式からpkgファイルをダウンロードし実行するだけ。
2. (コンソール) Systems Manager用のIAMユーザーグループ作成
<設定セクション: AWS IAM - グループ>
公式手順 に従い、IAM コンソール にて、IAMユーザーグループ SSMUserGroup
を作成する。
3. (コンソール) Systems Manager用のIAMユーザー作成
<設定セクション: AWS IAM - ユーザー>
公式手順 に従い、IAM コンソール にて、IAMユーザー SSMUser
を作成する。★ Access Key
と Secret Access Key
をメモしておく。
- 注意1: 手順2で作ったユーザーグループに所属させること
- 注意2: [Programmatic access (プログラムによるアクセス)] をチェックすること
4. (ラップトップ) IAM権限をMacのAWS CLIで登録
以下の通り、手順3でメモした情報を登録する。
$ aws configure
AWS Access Key ID [None]: ???
AWS Secret Access Key [None]: ???
Default region name [None]: us-east-2
Default output format [None]: JSON
5. (コンソール) Systems Managerのアクティベーションを作成する
<設定セクション: AWS Systems Manager - ハイブリッドアクティベーション>
公式手順 に従い、Systems Manager コンソール にて、アクティベーションを作成する。★ 作成される activation Code
, activation ID
をメモしておく。また、
- 注意: [Use the system created default command execution role] (システムの作成したデフォルトコマンド実行ロールを使用) を選択したので良い。
6. (デバイス) SSM エージェントをインストール
公式手順 に従い、エージェントをインストールする。Raspberry Piは以下のように設定する。手順5でメモしたactivation-code, activation-idがちゃんと設定されるように注意。
$ mkdir /tmp/ssm
$ sudo curl https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/debian_arm/amazon-ssm-agent.deb -o /tmp/ssm/amazon-ssm-agent.deb
$ sudo dpkg -i /tmp/ssm/amazon-ssm-agent.deb
$ sudo service amazon-ssm-agent stop
# 手順5でメモしたactivation-code, activation-idを設定する
$ sudo -E amazon-ssm-agent -register -code "activation-code" -id "activation-id" -region "region"
$ sudo service amazon-ssm-agent start
プロキシ環境の場合は、公式手順 に従い、以下のように設定しておく。
# HTTP プロキシサーバーの場合
export http_proxy=http://hostname:port
export https_proxy=http://hostname:port
# HTTPS プロキシサーバの場合
export http_proxy=http://hostname:port
export https_proxy=https://hostname:port
7. (コンソール) advanced-instances tier へ変更
Systems Manager コンソール の フリートマネージャー
の 設定
から、 アカウント設定の変更
を選択し、高度なインスタンス
へ変更する。
8. (コンソール) インスタンスID を確認する
手順6まで完了すると、 Systems Manager コンソール の フリートマネージャー
に手順6でエージェントを起動したデバイスが接続されるインスタンスが表示される。★ mi-???
というインスタンスIDが表示されているのでメモする。また、この時点でリモートシェルが可能。インスタンスIDをクリックし、インスタンスアクション
-> セッションを開始
にて、リモートシェル実行され、コマンド実行可能になっている。
9. (ラップトップ) Macに Session Manager プラグインをインストール
公式の手順 に従い、インストールする。
$ curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
$ unzip sessionmanager-bundle.zip
$ sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin
10. (ラップトップ) セッション開始
target
に手順8でメモした インスタンスID
を設定し、セッションを開始する。この場合はラップトップの9090ポートとsshの22ポートをポートフォワーディングしている。Waiting for connections
となったら完了。
$ aws ssm start-session \
--target mi-??? \
--document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":["22"],"localPortNumber":["9090"]}'
Starting session with SessionId: SSMUser-???
Port 9090 opened for sessionId SSMUser-???.
Waiting for connections...
また、ラズベリーパイは自宅のセンサと繋がり、port3000でGrafanaを表示しているため、port3000でポートフォワーディングすると外部から自宅センサのGrafanaが見えたりする運用でも使える。
11. (ラップトップ+デバイス) Ansibleで sl
パッケージをインストールしてみる
対象エッジデバイスに sl
パッケージがないことを確認
pi@raspberrypi:~ $ sl
-bash: sl: command not found
以下のようにinventoryを設定する
[testServer1]
localhost
[testServer1:vars]
ansible_port=9090
ansible_ssh_user=pi
ansible_ssh_pass=???
ansible_sudo_pass=???
以下のような簡単なymlを作成
- hosts: all
become: true
gather_facts: no
tasks:
- name: Ansible動作開始
debug:
msg: "これから自動更新作業を開始します。"
- name: 必要なパッケージをインストールします (apt)
apt:
name:
- sl
state: present
- name: Ansible動作終了
debug:
msg: "対象ノードにて自動更新作業が終了しました。"
実行してみる
$ sudo ansible-playbook -vvv -i inventories/hosts site.yml
PLAYBOOK: site.yml **************************************************************************************************************************************************************
1 plays in site.yml
PLAY [all] **********************************************************************************************************************************************************************
META: ran handlers
TASK [Ansible動作開始] **************************************************************************************************************************************************************
task path: site.yml:6
ok: [localhost] => {
"msg": "これから自動更新作業を開始します。"
}
...(省略)
TASK [Ansible動作終了] **************************************************************************************************************************************************************
task path: site.yml:16
ok: [localhost] => {
"msg": "対象ノードにて自動更新作業が終了しました。"
}
META: ran handlers
META: ran handlers
PLAY RECAP **********************************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
対象エッジデバイスにて確認してみる
pi@raspberrypi:~ $ sl
# slコマンドが正常実行されることを確認
神
続-検証 (なんかもっと良い方法があるらしい・・)
S3
+ コマンド実行機能
でもっと簡単にAnsible実行できるらしいことを後から知る・・。しかも、最初に書いた方法だと、advanced-instances tier
必須なので、若干費用がかかるが、今回の方法だと接続デバイス1000台まで無料。
手順 (最初の検証終わりから開始)
1. (コンソール) インスタンス設定変更
<設定セクション: AWS Systems Manager - フリートマネージャー>
advanced-instances tier
を解除する (解除しなくても使えるが、解除したら無料になるため解除。) アカウント設定の変更
を押すだけ。
2. (コンソール) S3 に Ansible Playbook ymlをアップ
以下のymlをS3にアップロードし、公開設定にしオブジェクトURLをメモ (https://ansible-on-premise.s3.us-east-2.amazonaws.com/ansible-on-premise.yml)。
- hosts: all
become: true
gather_facts: no
tasks:
- name: Ansible動作開始
debug:
msg: "これから自動更新作業を開始します。"
- name: 必要なパッケージをインストールします (apt)
apt:
name:
- sl
state: present
- name: Ansible動作終了
debug:
msg: "対象ノードにて自動更新作業が終了しました。"
- 注意: 今回は検証なので公開設定にしたが、基本的には権限付与して対応する
3. (コンソール) Ansible実行
<設定セクション: AWS Systems Manager - Run Command - コマンドの実行>
AWS Systems Manager -> ノード管理 -> Run Command
を開き、Run Command
をクリック。 AWS-ApplyAnsiblePlaybooks
をチェックし、Source Typeは S3
を選択し、手順1でメモしたURLをpathに設定する。
{
"path":"https://ansible-on-premise.s3.us-east-2.amazonaws.com/ansible-on-premise.yml"
}
Install Dependencies がTrueだと失敗した。なので手動でAnsibleを入れて実行。(後で分かったがデバイス側がメモリMax状態でinstallできていなかったっぽい。)
Playbook File には、ymlファイル名を入れておく。今回だと、ansible-on-premise.yml
。
ターゲットは インスタンスを手動で選択する
を選び、対象インスタンスにチェックを入れる。
出力オプションを設定しておくと、S3に出力ログを残すことができる。
上記設定終わったら、RUN
実行!
4. (コンソール) 実行結果確認
<設定セクション: AWS Systems Manager - Run Command - コマンドの実行>
コマンド履歴欄に、結果が表示される。
成功コマンドの詳細をみるとAnsible出力結果が・・・
...(省略)
TASK [Ansible動作終了] *********************************************************
ok: [localhost] => {
"msg": "対象ノードにて自動更新作業が終了しました。"
}
PLAY RECAP *********************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
エッジデバイスを見てみると、正常にパッケージがインストールされている。
これが無料・・・? 神
コスト
公式記載のコスト によると、advanced-instances
で1台1ヶ月起動し続けると 5.004 USD = (0.00695 USD * 30日間 * 24時間) となる。advancedでなくstandardの場合は、最大 1,000 インスタンスまで無料。
「アドバンスドオンプレミスインスタンスが 1 時間ずっと登録解除、シャットダウン、または削除されていた場合、その時間に対する料金は発生しません。
」と書かれているので、リモートシェル作業する時だけ advanced-instances
に変更する運用にすれば、ほとんどお金かからない見込み。
- 今回やったことの有料枠 ... リモートシェル, ポートフォワーディング
- 今回やったことの無料枠 ... リモートシェル, ポートフォワーディング以外全て