無印吉澤

Site Reliability Engineering(SRE)、ソフトウェア開発、クラウドコンピューティングなどについて、吉澤が調べたり試したことを書いていくブログです。

Amazon Linux 2 に awscurl を安全にインストールする簡単な方法

f:id:muziyoshiz:20201129180845p:plain

この話の背景

以前のブログ記事で、Amazon Elasticsearch Service を awscurl(AWS 署名に対応した curl ライクなコマンド)経由で管理する方法をまとめました。

muziyoshiz.hatenablog.com

自分が扱っている環境では、管理用サーバ(Amazon Linux 2)に awscurl をインストールして使ってます。

この管理用サーバで使う Python 製のツールは awscurl だけだったので、Amazon Linux 2 標準の Python 2 に pip install awscurl して使ってたんですが、そしたら yum update を実行するたびに urllib3 のアップデートと衝突して使えなくなることが頻発。

まあ、Python 知っている人にしたら「それはそう」って話なんですけど、awscurl を使いたいだけだからいいか、とサボってたんですよ……そしたら案の定という感じ。このためだけに pyenv 入れるのは面倒だなあと悩んでいたら、同僚にいい方法を教えてもらって解決したのでまとめておきます。

結論:pipx 経由で awscurl をインストールする(ただし Python 3 が必要)

pipx とは、Python で書かれたエンドユーザーアプリケーションを、独立した環境で動かすことができるツールです。

github.com

コマンド名からお察しの通り、pipx は pip と同じく The Python Package Index (PyPI) を使えます。それに加えて、pipx はインストールしたツールが依存するパッケージを、ツールごとに独立した環境にインストールしてくれます。アップグレードやアンインストールも、同様にクリーンな環境で行なえます。

サイト内の説明を借りると、いわば pipx は PyPI を Python アプリケーションのための巨大な app store にしてくれる(In a way, it turns Python Package Index (PyPI) into a big app store for Python applications.)というわけです。いいですね。

ただし、pipx の動作には Python 3 が必須です。しかし Amazon Linux 2 に標準添付されているのは Python 2.7 だけ。amazon-linux-extras に Python 3 系があるので、細かいことを考える必要がないなら、これで Python 3 系を入れてしまうのが一番楽でした。

以下、awscurl のインストールが完了するまでの具体的な手順です。

インストール手順

Python 3 のインストール

amazon-linux-extras に関する説明はこちら。これは AWS が Amazon Linux 2 用に管理している yum リポジトリを有効にするコマンドです。ソフトウェアのインストール自体は yum コマンドで行います。

aws.amazon.com

amazon-linux-extras 自体が未インストールの場合は、まず以下のコマンドでインストール。

$ sudo yum install -y amazon-linux-extras

amazon-linux-extras コマンドで、現在利用できるリポジトリ(amazon-linux-extras の用語ではトピック)の一覧が確認できます。現時点では python3.8 が利用できることがわかります。

$ amazon-linux-extras | grep python
 44  python3.8=latest         available    [ =stable ]

そこで、今回は python3.8 のリポジトリを有効にしてから、yum コマンドでインストールします。将来、Python のバージョンが上がったら、python3.8 の部分は読み替えてください。

$ sudo amazon-linux-extras enable python3.8
$ sudo yum install python3.8

pipx のインストール

pipx のインストールは、pipx サイト内の手順 のコマンド名を python3 から python3.8 に置き換えれば OK です。

$ python3.8 -m pip install --user pipx
$ python3.8 -m pipx ensurepath

これで、そのユーザー(EC2 だと ec2-user)は特別なパス指定なしで pipx を使える状態になりました。pipx のインストール先は ~/.local/bin/pipx です。

pipx 経由での awscurl のインストール

awscurl のインストールは、従来の pip を pipx に置き換えるだけで OK です。

$ pipx install awscurl

awscurl のコマンドは ~/.local/bin/awscurl にインストールされますが、awscurl が依存するパッケージ一式は ~/.local/pipx/venvs/awscurl/ 以下にインストールされます。このように、ツールごとに環境が分離されるわけですね。

注意点:シェル変数の扱いが変わる

コマンドごとに環境が分離されるためか、シェル変数の扱いが変わるようです。

以前のブログ記事 では、awscurl コマンドへ自動的に認証情報を渡す awscurl-on-ec2 というシェルスクリプトを紹介しました。

#!/bin/env bash

ROLE_NAME=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/`
CRED=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE_NAME}`
AWS_ACCESS_KEY_ID=`echo $CRED | jq -r ".AccessKeyId"`
AWS_SECRET_ACCESS_KEY=`echo $CRED | jq -r ".SecretAccessKey"`
AWS_SESSION_TOKEN=`echo $CRED | jq -r ".Token"`

awscurl "$@"

pipx でインストールした awscurl には、この方法ではシェル変数が渡されませんでした。以下のように、export を使って環境変数にすれば問題なく渡されました。

#!/bin/env bash

ROLE_NAME=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/`
CRED=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE_NAME}`
export AWS_ACCESS_KEY_ID=`echo $CRED | jq -r ".AccessKeyId"`
export AWS_SECRET_ACCESS_KEY=`echo $CRED | jq -r ".SecretAccessKey"`
export AWS_SESSION_TOKEN=`echo $CRED | jq -r ".Token"`

awscurl "$@"

awscurl の場合はコマンドライン引数を使って、これらの認証情報を明示的に渡すこともできます。環境変数を増やしたくなかったので、自分はこちらの方法で対応しました。

#!/bin/env bash

ROLE_NAME=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/`
CRED=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE_NAME}`
AWS_ACCESS_KEY_ID=`echo $CRED | jq -r ".AccessKeyId"`
AWS_SECRET_ACCESS_KEY=`echo $CRED | jq -r ".SecretAccessKey"`
AWS_SESSION_TOKEN=`echo $CRED | jq -r ".Token"`

awscurl --access_key $AWS_ACCESS_KEY_ID --secret_key $AWS_SECRET_ACCESS_KEY --session_token $AWS_SESSION_TOKEN "$@"