はじめに
先日、AWS CloudShell が利用できるようになりました。
とても気軽に使えて良いなと思ったので Ansible をインストールして、AWS 上のリソースを操作できるか使えるか試してみました。
Playbook の実行、ad-hoc コマンドのの実行、ダイナミックインベントリを試しました。
クレデンシャルを別途設定しなくて良いのが AWS CloudShell ならではの特徴かと思います。
インストール
Ansible はデフォルトでインストールされていないので、別途 pip でインストールする必要があります。
まず、venv を作成して有効にします。
python3 -m venv ansible source ansible/bin/activate
続いて、ansible
と、AWS リソースの操作に必要な boto3
をインストールします。
pip install ansible boto3
インストールされたことをバージョン表示をもって確認します。
$ ansible --version ansible 2.10.4 ...(略)...
無事にインストールできました。
Playbook の実行
まず、インベントリファイルを作成します。大した内容はないのですが、ここで変数の定義をしておくとあとで便利です。
inventory.ini
[local] localhost [local:vars] ansible_connection=local ansible_python_interpreter=~/ansible/bin/python
次に Playbook を作成します。ここでは、VPC を作成するだけのごく簡単なものにします。
vpc.yml
--- - hosts: localhost gather_facts: false tasks: - name: create VPC amazon.aws.ec2_vpc_net: name: sakana_vpc_test1 cidr_block: 10.0.0.0/16 region: ap-northeast-1
Playbook を実行します。なお、他に明示的にクレデンシャルの設定はしていません。
$ ansible-playbook -i inventory.ini vpc.yml PLAY [localhost] *********************************************************************************************************************** TASK [create VPC] ********************************************************************************************************************** changed: [localhost] PLAY RECAP ***************************************************************************************************************************** localhost : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
無事作成されました。
ad-hoc コマンドの実行
今度は Playbook を作成せずに、ad-hoc コマンド ansible
を試します。
ここでは、VPC の情報を取得し、先程作った VPC があることを確認します。
$ ansible -i inventory.ini local -m amazon.aws.ec2_vpc_net_info -a "region=ap-northeast-1" ...(略)... { "cidr_block": "10.0.0.0/16", "cidr_block_association_set": [ { "association_id": "vpc-cidr-assoc-XXXXXXXXXXXX", "cidr_block": "10.0.0.0/16", "cidr_block_state": { "state": "associated" } } ], "classic_link_dns_supported": false, "classic_link_enabled": false, "dhcp_options_id": "dopt-XXXXXX", "enable_dns_hostnames": true, "enable_dns_support": true, "id": "vpc-XXXXXXXXXXXX", "instance_tenancy": "default", "is_default": false, "owner_id": "XXXXXXXX", "state": "available", "tags": { "Name": "sakana_vpc_test1" }, "vpc_id": "vpc-XXXXXXXXXXXX" }, ...(略)...
無事に先ほど作成した、 VPC sakana_vpc_test1
が表示されました。
ダイナミックインベントリの表示
Ansible には、クラウドリソースなどをダイナミックなインベントリとして利用できる機能があります。
EC2 の情報をインベントリとして利用するには aws_ec2
インベントリプラグイン を利用します。
まず、aws_ec2
インベントリプラグインを利用するためのインベントリファイルを作成します。ファイル名の最後は aws_ec2.yml
または、aws_ec2.ymal
である必要があります。
inventory_aws_ec2,yml
--- plugin: aws_ec2 regions: - ap-northeast-1 hostnames: - tag:Name
aws_ec2
インベントリプラグイン では、フィルターなどの様々な指定ができますが、ここでは リージョンの指定と、Name
タグをホスト名として利用するしていのみで試します。
ansible-inventory
コマンドでダイナミックインベントリを確認します。まずは --graph
オプションで、グループとホストの関係を表示してみます。
$ ansible-inventory -i inventory_aws_ec2.yml --graph @all: |--@aws_ec2: | |--sakana_server1 | |--sakana_server2 | |--same1 |--@ungrouped:
それとなくホストが表示されました。特に指定がなくとも aws_ec2
というグループにまとめられます。
つづいて、--list
オプションで詳細な情報を表示します。
$ ansible-inventory -i inventory_aws_ec2.yml --list { "_meta": { "hostvars": { "sakana_server1": { "ami_launch_index": 0, "architecture": "x86_64", "block_device_mappings": [ { "device_name": "/dev/sda1", "ebs": { "attach_time": "2020-12-29T04:38:07+00:00", "delete_on_termination": true, "status": "attached", "volume_id": "vol-XXXXXXX" } } ], ...(略)...
無事に表示できました。
今回は ansible-inventory
コマンドによる表示だけでしたが、ansible-playbook
コマンドの -i
オプションに YAML を指定することで、Playbook の実行対象として利用できます。
復帰直後はエラーになることがある [2021/01/02 追記]
CloudShell は、一定期間何もしないとスリープのような状態になります、復帰直後は、クレデンシャル情報が取得できないためか、以下のよいうなエラーが発生することがあります。
botocore.exceptions.CredentialRetrievalError: Error when retrieving credentials from container-role: Error retrieving metadata: Received non 200 response (500) from ECS metadata: <?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n <head>\n <title>500 - Internal Server Error</title>\n </head>\n <body>\n <h1>500 - Internal Server Error</h1>\n </body>\n</html>
数分待つと正常に戻ります。
おわりに
AWS CloudShell に Ansible をインストールして、Playbook の実行、ad-hoc コマンドの実行、ダイナミックインベントリの表示を試しました。
いくつか制約はあるものの、クレデンシャルを仕込まなくて利用できるのは便利だと思いました。