やーまんぶろぐ

気が向いた時にだけ書くブログ

CloudFormationでEC2用のIAMロールを作成するときはインスタンスプロファイルに注意する

EC2からAWSのリソースにアクセスする必要がある場合は、アクセスキーではなくIAMロールを使ってアクセスしましょう。

以下にコンソールからIAMロールを作成する方法が記載されています。
qiita.com

IAMロール作成の流れ

コンソールから作成すると、以下の流れに見えます。

  • IAMロール作成
  • IAMポリシーを選択
  • EC2作成時にIAMロールを指定

細かいけどこれは間違いで、実際には以下の流れが正しいです。

  • IAMロール作成
  • IAMポリシーを選択
  • インスタンスプロファイルを作成してIAMロールと紐づける
  • EC2作成時にインスタンスプロファイルを指定

インスタンスプロファイルはEC2にIAMロールを紐づけるために必要なものになります。

コンソールから作成するとIAMロールと同名のインスタンスプロファイルが作成されるので、EC2作成時にはIAMロールを指定しているように見えるのでしょう。

CloudFormationで作成する場合にはインスタンスプロファイルを作成することに注意しましょう。これを忘れるとIAMロールを作成していたとしても、EC2起動時にIAMロールと紐づけることができません。

CloudFormationサンプル

  • IAMロール作成
BastionIAMRole:
  Type: "AWS::IAM::Role"
  Properties:
    AssumeRolePolicyDocument:
      Statement: 
        -
          Effect: "Allow"
          Principal:
            Service:
              - "ec2.amazonaws.com"
          Action:
            - "sts:AssumeRole"
      Path: "/"
  • IAMポリシーを選択
    • Actionに必要な権限を記載しましょう。
BastionIAMPolicy:
  Type: "AWS::IAM::Policy"
  Properties:
    PolicyName: BastionIAMPolicy
    Roles:
      - Ref: BastionIAMRole
    PolicyDocument:
      Statement:
        -
          Effect: "Allow"
          Resource: ""
          Action:
          - "ec2:*"
  • インスタンスプロファイルを作成してIAMロールと紐づける
    • Roleには上で記載したIAMロールを指定します
BastionIAMInstanceProfile:
  Type: "AWS::IAM::InstanceProfile"
  Properties:
    Path: "/"
    Roles:
      - Ref: BastionIAMRole
  • EC2作成時にインスタンスプロファイルを指定
    • IamInstanceProfile以外のプロパティは省略しています
    • ここで紐付けているのがIAMロールじゃなくてインスタンスプロファイルだということに注意しましょう。
BastionEC2:
  Type: "AWS::EC2::Instance"
  Properties:
    IamInstanceProfile:
      Ref: BastionIAMInstanceProfile

CloudFormerを使ってAWS CloudFormationのテンプレートを自動作成する

CloudFormerとは自分で構築したAWSリソースから、AWS CloudFormationのテンプレートを自動作成してくれるツールになります。

自動で作成とは言ってもそのまま使いまわせるわけではないので注意が必要です。

また、EC2上にCloudFormerを構築してブラウザアクセスして使用するというところが、他のAWSのサービスとは違うところだと感じました。

EC2上にCloudFormerを構築する

まずはEC2上に構築します。公式で用意されているCloudFormationのサンプルテンプレートがあるのでそれを実行しましょう。
以下のリンクを見ながら作業しました。
kaotil.com

後でログインする時に使うユーザ名/パスワードを入力しておきます。

CloudFormerにブラウザアクセスする

CloudFormation実行が成功するとOutputsにURLが表示されるのでアクセスします。
構築時に指定したユーザ名/パスワードを入力してログインします。

念のためこの時点でSecurityGroupをコンンソールから触ってアクセスを制限しておきました。

リソースを選択してテンプレートを作成する

続いてテンプレート化したいリソースにアクセスしていきます。

以下の大項目から選択します。

  • DNS
  • VPC
  • VPC Network
  • VPC Security
  • Network
  • Managed Service
  • Managed Config
  • Compute
  • Storage
  • Storage Config
  • App Service
  • Security
  • Operational

以下のリンクにAWS CloudFormer がサポートしているリソース一覧がまとまっているので、こちらを参考にテンプレートにしたいリソースを選択していきましょう。
qiita.com

選択するとすぐにテンプレートが作成されます。
EC2の料金がかかってしますので、不要になったCloudFormerのCloudFormationスタックは削除しておきましょう。

JSONYAMLに変換する

JSONでの出力にしか対応していません。YAMLにしたい場合は別のツールで変換が必要です。

私は以下のリンクで変換を行いました。
phiary.me

注意する点

一回でうまくいくものではないので何回かトライ&エラーで頑張るしかないです。困ったらリファレンスを見ましょう。
docs.aws.amazon.com

以下に個人的に感じた注意点をまとめておきます。

  • subnetxxxxxxxxのように各種IDがそのまま出力される
    • PublicSubnetAのように汎用的な名前に変換する
  • PublicSubnetB, PrivateSubnetA, PrivateSubnetB, PublicSubnetAのように順番が綺麗じゃない
    • 順番を整理する
  • outputsが出力されない
    • 結果を確認したい値があるものや他のスタックで参照したいものは出力する
  • 対応していないリソースがある
    • リファレンスを見ながら追加する。CloudWatchLogsみたいにリソースそのものがないものや、AutoScalling::LaunchConfigurationのUSERDATAみたいにリソースはあるけど一部プロパティがないものもあったので注意。
  • アタッチはされているけど、作成されないリソースがある
    • IAM::InstanceProfileとかAWS::EC2::VPCEndpointはアタッチはされているけど、リソースがないのでエラーになってしまいます。事前に作成するかCloudFormationで一緒に作成するかしましょう。

IAMで踏み台サーバのローカルユーザを一元管理を実行してみる

この記事の続きです。
yamano3201.hatenablog.jp

踏み台サーバのCloudFormationテンプレートでは実現できなかった、以下の要件に対応したいと思います。

  • ユーザアカウントごとにログインさせる
  • 可能な限りユーザアカウントの管理を減らしたい
  • sudo を使わせない

基本的には以下のサイトと同じです。
qiita.com

やってることは踏み台上にIAMユーザと同名のローカルユーザを自動作成して、アカウント管理を減らそうというものになります。
IAMユーザにはSSH公開鍵を登録できるので、それをローカルユーザの.ssh/authorized_keysとしてセットすることでSSHログインも管理できます。

事前準備

  • IAMユーザにsshパブリックキーを登録
  • iam list-users, iam list-ssh-public-keys, iam get-ssh-public-keyの権限を持ったIAMロールを用意(とりあえず前回作成されたIAMロールにIAMReadOnlyAccessポリシーを追加しました)

USER DATAに登録

オートスケールで自動で作成されるたびにスクリプトを流します。
スクリプトはリンク先bashスクリプトとほぼ同じなので割愛します。

USER DATA上でjqをインストールする必要があるのでご注意ください。

sudo yum install -y jq

前回作成したUSER DATAの下に、jqインストールとリンク先スクリプトを追加するとうまく動くと思います。

鍵の更新についても実装していますが、オートスケールによって毎回新規で作成されるので余分なところは削ってもよいかもしれないです。

configurationを作成してアタッチする

オートスケールのconfigurationは編集できないので、新しく作成しましょう。(コピーすると簡単です)
そこでUSER DATAを編集します。

初期ユーザであるec2-userではなく、各ローカルユーザでログインさせたい場合は鍵の登録は不要です。

最後にAutoScallingGroup側で新しいconfigurationをアタッチすれば完成です。

最後に

前回記事と合わせると、以下の要件を合わせた踏み台の作成が完成しました。

  • ログインの証跡を残す
  • 証跡はS3に保存
  • yum updateが定期的に走る
  • オートスケールする(可能であればログインするときだけ起動するようにしたい)
  • ユーザアカウントごとにログインさせる
  • 可能な限りユーザアカウントの管理を減らしたい
  • sudo を使わせない

yamano3201.hatenablog.jp

踏み台サーバのCloudFormationテンプレートを実行してみる

踏み台サーバの要件を洗い出してみたところ、ほとんどが提供されているCloudFormationのテンプレートでカバーできていることがわかったので、まずは実行してみることにしました。

基本的には以下のサイトと同じです。
dev.classmethod.jp

要件

  • テンプレートで実現できていること
    • ログインの証跡を残す
    • 証跡はS3に保存
    • yum updateが定期的に走る
    • オートスケールする(可能であればログインするときだけ起動するようにしたい)
  • テンプレートで実現できていなかったこと
    • ユーザアカウントごとにログインさせる
    • 可能な限りユーザアカウントの管理を減らしたい
    • sudo を使わせない

今回はテンプレートでほとんどの要件を満たしていることを確認しました。
実現できていないことに関しても対策を行ったので別の記事にしたいと思います。

※2017/11/16 追記しました。
yamano3201.hatenablog.jp

実行

リンク先から「Launch Quick Start(for new VPC)」を実行します。遷移先はオレゴンリージョンになってるので構築したいリージョンに変更しましょう。
docs.aws.amazon.com

詳細は以下を入力して実行しました。
f:id:yamano3201:20171115111419p:plain

for existing VPCのほうを実行するとなぜかAutoScallingGroupの作成でタイムアウトになって以下のエラーが出てしまいました。解析はしてないです。

Received 0 SUCCESS signal(s) out of 1. Unable to satisfy 100% MinSuccessfulInstancesPercent requirement

確認

  • ログインの証跡を残す
    • ec2-userでログインして/var/log/bastion/bastion.log を確認するとコマンド履歴が残っていることがわかります
  • 証跡はS3に保存
    • CloudWatchLogsにLinux-bastion-BastionStack-XXXX-BastionMainLogGroup-YYYY というロググループが作成されています。その下にインスタンスID名のLogStreamsが作成されています。オートスケールされるたびに同一のロググループに新しいLogStreamsが作成される形になります。
  • yum updateが定期的に走る
    • cronで実現していました。
$ crontab -l
0 0 * * * yum -y update --security
  • オートスケールする(可能であればログインするときだけ起動するようにしたい)
    • インスタンスを停止させると、インスタンスが削除されて新しいインスタンスが作成されました
    • ログインするときだけ起動すれば充分なので、夕方に削除されるスケジュールアクションを追加しました。

f:id:yamano3201:20171115111129p:plain

まとめ

これでほとんどがOKですね。次回は、テンプレートで実現できなかった部分をまとめたいと思います。

※2017/11/16 追記しました。
yamano3201.hatenablog.jp

RDSのread onlyのON/OFFをCLIで実行

こちらのAmazon RDS編 ~リードレプリカへの書き込み~ 記事を参考にread onlyのON/OFFをCLIで実行してみました。
recipe.kc-cloud.jp

パラメータグループのread_only のflagをONにすることで書き込みができなくなります。

read_only ON

$ aws rds modify-db-parameter-group --db-parameter-group-name XXXX --parameters 'ParameterName=read_only,ParameterValue=1,ApplyMethod=immediate'

反対にflagをOFFにすることで書き込みが可能になります。

read_only OFF

$ aws rds modify-db-parameter-group --db-parameter-group-name XXXX --parameters 'ParameterName=read_only,ParameterValue=0,ApplyMethod=immediate'

仮想環境(venv)の使い方 Python3 メモ

macで以下の環境で実行しました。

$ python3 -V
Python 3.5.1

Pythonの標準モジュールvenvを使うことで、プログラムごとに実行環境を分離できます。

$ python3 -m venv hoge
$ . hoge/bin/activate
(hoge) $ python -V
Python 3.5.1
(hoge) $ deactivate
$ 

バージョン番号を使わなくても、pythonコマンドで仮想環境に紐付けられたPythoランタイムを起動できます。

Pythonクローリング&スクレイピング -データ収集・解析のための実践開発ガイド- メモ

クローリング&スクレイピングに興味があったので読んでみました。
サンプルページも多く、非常に参考になりました。

クローリング・スクレイピングとは何か

まずは説明。

  • クローリング
    • Webページのハイパーリンクをたどって次々にWebページをダウンロードする作業
  • スクレイピング
    • ダウンロードしたWebページから必要な情報を抜き出す作業

Pythonではじめるクローリング・スクレイピング

Webページを取得する、正規表現で情報を抜き出す、データベースに保存する、という3つの処理を行います。

ここではゴリゴリに実装しています。

強力なライブラリ

ライブラリのメモ。

データベースへの保存についても書かれています。

実用のためのメソッド

ここではよい設計について書かれています。
キャッシュを使って更新されたデータだけを取得する方法、クロール先が変化した場合のメール通知などが書かれています。

クローリング・スクレイピングの実践とデータの活用

ここではAPIに対応しているサービスの情報取得について書かれています。
APIで取得するとスクレイピングが不要になるので、けっきょくこれが一番実用的だと思いました。

他にもデータ可視化についても書かれています。

フレームワーク Scrapy

Webサイトのクローリング・スクレイピングをするなら、以下のことができるScrapyというフレームワークを使うのがよいみたいです。

  • Webページからのリンクの抽出
  • robots.txtの取得と拒否されているページのクロール防止
  • XMLサイトマップの取得とリンクの抽出
  • ドメインごと / IPアドレスごとのクロール時間間隔の調整
  • 複数のクロール先の平行処理
  • 重複するURLのクロール防止
  • エラー時の回数制限付きのリトライ
  • クローラーのデーモン化とジョブの管理

Elasticsearchによる全文検索についても書かれていました。

クローラーの継続的な運用・管理

AWSでの運用・管理方法が書かれています。EC2上のcronで動かすくらいなら、PythonだしLambdaでいいんじゃないかと思いました。

メールによる通知をSESもあるのでクラウド化できそうですね。

クラウド活用としては画像の保存先としてS3が紹介されていました。

Vagrantによる開発環境の構築

一般的なVagrantの話。