【Python3入門】boto3を使ってPython3とAWSに触れてみよう!【60分】

AWS運用自動化サービス「Cloud Automator」

こんにちは、CI部の柿﨑と申します。
私はサーバーワークスに入社して3週間ほどですが、とても馴染みやすく、毎日リラックスした状態で過ごせております。
このような環境で仕事ができることに感謝感激です!
そんなわけで、今回はブログ初投稿というところで、Python3入門を題材にしてみます。

さて、今この記事をご覧の方で、初めてプログラミングを勉強する際にこういったご経験はないでしょうか?

  • プログラミングを勉強したいけど、何となく難しそうだからやらない
  • 技術書などの内容が難しい (いきなり関数の話をされてもうまく想像がつかない)
  • 日本語の技術ブログを見るばかりで公式ドキュメントを見る気が起きない
  • Hello Worldを出力してみたものの、ここから先どうすればいいのか分からない

あると思います!

かくいう私も、入り口の部分でとても苦労しました。
プログラミングはあくまでも手段ですので、その先に実現したいことがなければ、なかなか事が運びません。
そのため、今回はboto3と呼ばれるライブラリを活用して、なるべくシンプルに分かりやすく、Python3についてお伝えできればと思います。

本記事の対象者

  • AWSおよびAWS CLIを触ったことがあり、何となくでもPython3が気になる方

本記事のコンセプト

  • シンプルな題材でPython3に触り、AWS上で簡単にできることからやる
  • boto3ドキュメントを活用する

前提条件

  • Windows 10にてAWS CLIの実行環境がある
  • Python3にてHello Worldを出力できる環境がある
    • 私はVSCodeを使いますが、適宜、やりやすい環境を使ってください
  • EC2をいつでも構築できる

目次

  1. Python3用のIAMユーザーを作成
  2. AWSの情報をPython3で取得してみよう
  3. Python3で取得する情報を見やすくしよう
  4. コードを改善してみよう
  5. さいごに

1.Python3用のIAMユーザーを作成

まずは、以下の画像に沿ってPython3を動かすためのIAMユーザーを作成します。
すでにご存じの方も多いと思われるので、ここはサラっといきます。
※権限の強いIAMユーザーをお持ちであれば、そちらを使っていただいても構いません。

コマンドプロンプトなどで、上記のアクセスキーID(以下アクセスキー)とシークレットアクセスキー(以下シークレットキー)をaws configureに入力後、
aws sts get-caller-identityコマンドにて、自身のIAMユーザー情報が出力されたら問題ありません。
※本記事のコンセプトに従って、独自profileを利用するパターンは記載しません。

2.AWSの情報をPython3で取得してみよう

手始めにVPC情報を出力してみます。
Python3でAWS環境を操作するには、boto3と呼ばれるライブラリが必要です。
boto3ドキュメント:https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html
このboto3をインストールし、Python3のコード内で呼び出してあげることで使えるようになります。
まずは下記コマンドを実行してインストールします。

pip install boto3

正常にインストールが完了したら、任意のフォルダに下記の内容でPython3ファイルを作成します。

上記コード内にアクセスキーおよびシークレットキーの記載はないですが、AWS CLIを使用するローカルユーザーのフォルダ配下にある
\.aws\config\.aws\credentialsからboto3が認証情報を読み取ってくれます。
この3行のコードを実行すると、以下のようなVPC情報が出力されます。
※私の環境にはDefault VPCのみ存在します。

上記コードの流れをドキュメントのトップページから照らし合わせると以下のようになります。


このページを少し下にスクロールすると、コマンド実行時に得られる返り値が以下のように記載されています。
基本的にはこの返り値を参照して、必要な情報があるのかを確認します。
もし、VPC IDを取得したい場合は、’VpcId’の項目で探してみると記載がありますね!
(以下の画像からさらに下へスクロールすると説明もあります。)
こうして実際に得られた結果と見比べてみると理解が深まるものです。
では、ここでEC2インスタンスのインスタンスIDを取得してみようと思います。
対象リージョンにEC2インスタンスがない場合は、適当なものを1台作ってください。
まずは、必要な情報を取得できそうなコマンドを以下のページから探してみます。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#client
すると、以下のような流れで目的の値が見つかると思います。

それでは、先ほどのコードを少し編集して実行してみます。


実行結果は記載しませんが、出力がバーっと流れたのではないでしょうか?
その中にインスタンスIDがあるはずです。
しかし、これでは要らない情報が多すぎます。どうにかしたいところです。

3.Python3で取得する情報を見やすくしよう

何も指定せずにコマンドを実行するだけでは、目的の情報は取得できているものの見づらいです。
どうにかしてインスタンスIDだけを出力したいと思うはずです。
そういった場合は、以下のように必要な情報だけを指定します。

早速、意味不明ですね。(初心者の頃の私ならそう思うはず。)
最後の行に着目しますと、ec2_client.describe_instances()コマンドのあとにいろいろとくっついていることが分かります。
あえてこのような書き方をしていますが、インスタンスIDが1つだけ出力されるはずです。
ここで、改めてboto3ドキュメントの返り値の項目を確認してみます。
すると、以下のような記載があるかと思われます。
これは返り値の型です。
dict型と呼ばれるものは、KeyとValueが組み合わさったデータ型の1種で、Keyを指定して呼び出すことで、Valueを取得することができます。
(AWSリソースに付けるタグを思い浮かべていただければと思います。)
このコードでは、以下のように考えるとインスタンスIDの情報までたどり着けます。
今度は[0]なんて聞いてないよ!となりますね。(初心者の頃の私なら・・・略。)
こちらは、list型を呼び出すものとなっており、list内にある1番目のデータを指定しています。
list型というものは、複数のデータをひとまとめにすることができるデータ型です。
list内のデータの位置を[0][5]と指定してあげることで、1番目や6番目のデータを取り出すことができます。
今回の例ですと、EC2インスタンスは複数台作成されていることがほとんどかと思われます。
その複数台あるEC2インスタンスの情報を、返り値の中でlist型として、ひとまとめにされた状態で受け取っているわけであります。
つまり、['Reservations'][0]['Instances'][0]['InstanceId']の意味は、
'Reservations'Keyの1番目のValueにある、'Instances'Keyの1番目のValueにある'InstanceId'Keyを指定しています。
結果、'InstanceId'KeyのValue = インスタンスIDだけが出力されます。

4.コードを改善してみよう

print (ec2_client.describe_instances()['Reservations'][0]['Instances'][0]['InstanceId'])
この1行、我々人類には優しくないですよね。
ごちゃごちゃしているし、list型の1番目のデータしか出力されません。2番目のデータを出力するために手で[1]と書き換えるのは面倒です。
データが1000個あったら0から999まで書かなければいけません( ^ω^)・・・。
このように、初心者ながらもやみくもにコードを書いていくことで、さまざまな問題点が浮上してきます。
早速、解決してみると以下のようになります。


こちらも出力結果は記載しませんが、for文と呼ばれる文法を使うことにより、まとまったデータを1つずつ取り出すことができます。
このコードでは指定したリージョンの全インスタンスIDが出力されます。
print (ec2_client.describe_instances()['Reservations'][0]['Instances'][0]['InstanceId'])
ここで、上記のコードからどのように変わったかを文章で説明しますと、
 
ec2_client.describe_instances()コマンドの返り値が、変数ec2_dataに格納され、
ec2_client.describe_instances()['Reservations']と記載していたものが、ec2_data['Reservations']となり、for文で1つずつデータを取り出しています。
for文では、ec2_data['Reservations']のlist型データが1つずつ、変数reservationに格納され、その中のfor文で、reservation['Instances']として、
list型データになっているEC2インスタンスの情報を、変数instanceに格納しています。
こうして階層を掘っていった先で、instance['InstanceId']と、指定してあげることでインスタンスIDが出力されます。
 
このようにインスタンスIDを出力できるようになると、EC2を起動/停止する関数にインスタンスIDを渡して連携することができたりします。
(EC2を起動/停止するコマンドは、同じ要領で探せばすぐ見つかります。)
そもそも特定のインスタンスIDだけほしい!という状況でしたら、boto3ドキュメントを参考にec2_client.describe_instances()の()内をいじってみたりなど、できることの幅が広がってくるのではないかと思われます。

5.さいごに

本記事で私が伝えたかったことは、不格好なかたちであれ、とにかくプログラミングをすることが一番の勉強になること、
公式ドキュメントの使い方に慣れていこう!、という2点です。
私は関数を使わずに、上から下までズラっとコードを書いていた時期がありました。
ある日、1度書いた処理をもう1度書く必要が出てきたときに、関数の必要性を理解したものです。
本記事のように、たった数行のコードを書くだけでいくつもの改善点が出てきます。
今回は、私がプログラミングの入り口を見出せなかった時期に、こんな記事があればうれしいなという想いをかたちにしました。
 
本記事が、皆様のお役に立てれば幸いでございます。

AWS運用自動化サービス「Cloud Automator」