本エントリは、Ansible Advent Calendar 2023の8日目の記事です。
昨日のAnsibleアドカレ7日目で id:usagi_automate さんがAWXで作成したテキストファイルをZipに固めて手元に持ってきたい - うさラボという記事で「バイナリデータもBase64でテキスト化して転送やログ記録する」という内容を紹介していたので、本記事ではアプローチを変えて、クラウドサービスでよく使用するS3互換オブジェクトストレージに対してAnsibleを使ってデータをやり取りする方法について紹介します。
確認した環境は以下の通り。
ちなみに本記事ではS3とのデータのやり取りについて説明しており、S3自体の管理(バケットを作成したり等)は扱いません。予めS3バケットは存在し、適切な権限設定が行われているものとしています。
(12/13追記) Amazon S3以外の例としてOCIのオブジェクトストレージについて追記
amazon.aws.s3_objectモジュール
Amazon S3とデータのやり取りを行うにはこのモジュールを使用します。
実行にはPythonパッケージのboto3
とbotocore
が必要なのでpip install
でインストールしておきます。
書き込み
ローカルにあるlocal.txt
というファイルを、S3のsample-bucket
バケットの/path/to/sample.txt
にアップロードします。
--- - hosts: localhost tasks: - name: put file amazon.aws.s3_object: bucket: sample-bucket object: path/to/sample.txt src: local.txt region: ap-northeast-1 mode: put access_key: <AWS_ACCESS_KEY_ID> secret_key: <AWS_SECRET_ACCESS_KEY>
例えばジョブの実行で生成した結果のファイルをS3に保存したりする場合に使用できます。
読み込み
S3のsample-bucket
バケットの/path/to/sample.txt
にあるファイルを、ローカルにdownload.txt
としてダウンロードします。
- hosts: localhost - name: get file amazon.aws.s3_object: bucket: sample-bucket object: path/to/sample.txt dest: download.txt region: ap-northeast-1 mode: get access_key: <AWS_ACCESS_KEY_ID> secret_key: <AWS_SECRET_ACCESS_KEY>
例えば何かのアプリケーションをセットアップするジョブで、S3にインストーラを保存しておいてそれを利用する、みたいなことに使用できます。
Appendix
ディレクトリのアップロード/ダウンロード
ディレクトリを再帰的に…みたいな処理は対応していないので、複数ファイルのアップロード/ダウンロードが必要な場合は個別にタスクを実装します。
ダウンロードファイルしたい場合のS3上のファイル一覧はmode: list
を指定すれば取得できるので、これとloop
併用するなどして処理します。
prefix
でパス指定もできます。(未指定の場合はルートから全てリストアップされるます)
- name: list files amazon.aws.s3_object: bucket: sample-bucket prefix: path/ region: ap-northeast-1 mode: list access_key: <AWS_ACCESS_KEY_ID> secret_key: <AWS_SECRET_ACCESS_KEY> register: s3_files_list
このタスクの実行結果は以下の通り。
ok: [localhost] => changed=false msg: LIST operation complete s3_keys: - path/to/files/files/file1.txt - path/to/files/files/file2.txt - path/to/sample.txt
Ansibleバージョンが古い場合
Ansibleバージョンというよりamazon.aws
コレクションのバージョンが、という感じだけど、古い環境だとamazon.aws.s3_object
モジュールは存在せず、amazon.aws.aws_s3
という名前でタスクを実装します。
また、アクセスキーとシークレットの指定は以下のようにaws_
が付与されたキーを使います。
aws_access_key: <AWS_ACCESS_KEY_ID> aws_secret_key: <AWS_SECRET_ACCESS_KEY>
警告
object
にフルパスの要領で/path/to/filename
と先頭に/
を付与すると下記警告が出るので現バージョンでは不要です。
[DEPRECATION WARNING]: Support for passing object key names with a leading '/' has been deprecated. This feature will be removed from amazon.aws in a release after 2025-12-01. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
Amazon S3以外 (12/13追記)
例えばOracle Cloud Infrastructure(OCI)のオブジェクトストレージはS3互換なので、このモジュールでやり取りが可能です。
アクセスキーとシークレットは「顧客秘密キー」で取得できます。
また、endpoint_url
は上記の通り書式は$namespace.compat.objectstorage.$region.oraclecloud.com
となります。
- name: put file amazon.aws.s3_object: bucket: <バケット名> object: path/to/sample.txt src: local.txt mode: put access_key: <アクセスキー> secret_key: <シークレット> endpoint_url: https://<namespace>.compat.objectstorage.<region>.oraclecloud.com
docs.public.oneportal.content.oci.oraclecloud.com
使いどころ
サーバー上でCLIでansible-playbook
コマンドを実行する際はその環境のファイルシステム上にあるファイルにアクセスできるので、大容量ファイルをあらかじめ配置してそれを参照、とか、自動化の実行後に生成するファイルを後から確認、みたいなことは従来通り容易ですが、AAPやAWXからジョブを実行する際はコンテナ環境の実行になることで「あらかじめファイルを配置しておく」「実行後にファイルを確認する」が基本的に出来ません(ジョブ完了後は実行環境は消えるため)。
そこでリモートからファイルをgetしたりputするという手順が必要になるため、S3のようなオブジェクトストレージを使うことで比較的簡単にファイルのやり取りが可能になります。
レガシーな環境であればHTTPやFTPの方が良かったりするかもしれないので、環境に合わせて実装してみましょう。