AWS Athenaにできるだけ少ない権限でアクセスする。

AWS Athenaを触る時に必要な権限を確認し、余分な権限をつけずに実行するのが目的。

概要

AWS Athenaとは

Amazon Athena はインタラクティブなクエリサービスで、Amazon S3 内のデータを標準 SQL を使用して簡単に分析できるようになります。Athena はサーバーレスなので、インフラストラクチャの管理は不要です。実行したクエリに対してのみ料金が発生します。

AWS Athenaは標準でAWS Glueと統合されています。

この意味するところはS3をデータソースとしてAWS Athenaで CREATE DATABASE すると、AWS GlueカタログとしてDBが出来上がるということです。

つまり、Athenaを利用する時にはGlueの権限も必要ということです。

また、先にデータソースとしてS3を利用すると書きました。これはつまり、データソースであるS3へアクセスできる必要があるということです。

最後に、Athenaでのクエリ結果はまたS3に保存されます。ですので保存先S3へのアクセス権も必要です。

必要な権限

Athena

  • action: "athena:*"
  • resource: "*"

Glue

default database
  • action: "glue:GetDatabase"
  • action: "glue:Catalog"
  • resource: "arn:aws:glue:::database/default
target database
  • action: "glue:*"
  • resource: "arn:aws:glue:::database/
  • resource: "arn:aws:glue:::table//*

S3

source
  • action: "s3:ListBucket"
  • action: "s3:GetObject"
  • action: "s3:GetObjectLocation"
  • resouce: "arn:aws:s3:::<source_bucket>"
  • resouce: "arn:aws:s3:::<source_bucket>/*"
destination
  • action: "s3:PutObject"
  • action: "s3:ListMultipartUploadParts"
  • action: "s3:ListBucketMultipartUploads"
  • action: "s3:ListBucket"
  • action: "s3:GetObject"
  • action: "s3:GetBucketLocation"
  • action: "s3:CreateBucket"
  • action: "s3:AbortMultipartUpload"
  • resouce: "arn:aws:s3:::<dest_bucket>"
  • resouce: "arn:aws:s3:::<dest_bucket>/*"

おわりに

Glueは default データベースに対して、Catalog、GetDatabaseあたりがないと動かないのが謎いです。

scrapy で カスタムアウトプットする。

scrapy crawl 'crawler' -o outpu.csv

というような方法で spiderを動かして結果をファイルに吐き出すことができます。

-o output.csvであればcsvで書き出されますし、-o output.jsonであればjsonで書き出されます。

この書き出し方について、カスタマイズしようという趣旨の話です。

scrapy rawl にて -oオプションを利用して出力する場合、 FeedExporterというものが利用されます。

これはscrapyの設定settings.pyにて利用するExporterを指定することができるようになっています。

具体的には

FEED_EXPORTERS = {
    'csv' = 'path.to.CustomExporter',
    'sample' = 'path.to.SampleExporter`
}

というように行うことで、拡張子ごとに利用するExporterを指定するという方法で行います。

では、Exporterはどう実装するのか。 公式ドキュメント Item Exporters — Scrapy 1.5.1 documentation に記載がありますが、

BaseItemExporterを継承し、__init__ でファイルオブジェクトを受取り、export_itemで受け取ったアイテムをファイルオブジェクトに書き出す。

というのが基本になります。

class SampleExporter(BaseItemExporter):
    def __init__(self, file, **kwargs):
        self.file = file
        super().__init__(**kwargs)

    def export_item(self, item):
        record = str(item).encode('utf-8') + b'\n'
        self.file.write(record)

のような形ですね。

この状態で scrapy crawl 'spider' -o output.sample とやると、単純にitemを文字列にシリアライズした結果が出力されていきます。

scrapy/exporters.py at master · scrapy/scrapy · GitHub にデフォルトで用意されているFeedExporterがありますので、参考にしましょう。

FTPと ipv6plus

家庭用光回線ですが、

PPPoE方式だと大人の事情で通信速度が上がらない状況がある。という認識がだんだん広まっていて、

IPv6plusというPPPoEではなく、IPv6トンネルとNATを利用して高速にIPv4接続ができる。

みたいなサービスが流行って来ているように思います。

そんなipv6plusですが、 利用できるポートが少ないなどの欠点もあり、一部ゲームやアプリが動かないというやつがあります。

FTPもそんなやつで、通常、ポートを開けれないとFTP Passiveモードというのを使うのですが、これが通らなく、FTPでファイルがダウンロードできないという悲しみがあったりします。

まじでつらい。

最近は色々httpに移っているのでそこそこ大丈夫になってきているんですが、一部、FTPでのみ配布されているドキュメントだとか、ツールがあるのですよね。