s3のレプリケーションは機能有効化した後のデータしかレプリケートしない
Amazon S3 は何をレプリケートしますか - Amazon Simple Storage Service
デフォルトでは、Amazon S3 は以下をレプリケートします。 レプリケーション設定の追加後に作成されたオブジェクト。
既存のオブジェクトのレプリケーション
というメニューもあるようだが、サポート依頼なので あくまでオプション的な機能のようだ。
S3 バッチオペレーション の実行 - Amazon Simple Storage Service
aws cli使うかbatch operationを使う感じで。 いずれにせよ設定しただけでどうにかなるものではないみたい。
IAM PassRoleについて理解する(なんとなく)
AWSを使ってるとなんとなくしかわかっていないIAMのPassRole
IAM: 特定の AWS サービスに IAM ロールを渡す - AWS Identity and Access Management
安定のクラメソさんと公式の一部
まず。何となくEC2とRDSで運用。みたいな感じだとそのサーバーがアクセスしたいリソースへのアクセス権をアタッチしておくのがIAM Roleという理解。 「EC2からS3へアクセスしたい」とかが良い例。
んで。クラメソさんのEC2の例だと。 何かしらの理由で自由にEC2へアタッチされるRoleが選ばれると困るから「EC2へアタッチできるRoleはこのロールだけね」って感じの設定をしてるんだと思う。
大前提としてPassRoleしてないサービスへはRoleは付与できないと言う事なのかな。
んで。
次の例として出してるCodePipelineの例。
AWSCodePipelineFullAccess
{ "Action": [ "iam:PassRole" ], "Effect": "Allow", "Resource": [ "arn:aws:iam::*:role/service-role/cwe-role-*" ], "Condition": { "StringEquals": { "iam:PassedToService": [ "events.amazonaws.com" ] } } }, { "Action": [ "iam:PassRole" ], "Effect": "Allow", "Resource": "*", "Condition": { "StringEquals": { "iam:PassedToService": [ "codepipeline.amazonaws.com" ] } } },
自分のIAMから同じのをコピってきた。 まず下段の
"Resource": "*", "codepipeline.amazonaws.com"
これでこのポリシーをアタッチされたCodePipelineリソース自身がCodePipelineリソースへのアクセス権(作成とか削除とか)を持つことになる。 (当たり前すぎて逆に混乱するのだがそう言うこと)
そして上段側の
"arn:aws:iam::*:role/service-role/cwe-role-*" "events.amazonaws.com"
これによってアタッチされたCodePipelineリソースがイベントブリッジにアタッチできるロールはワイルドカードで指定されているようなroleのみとなる。
何となくGlueとかLambdaとかでもこの辺が出てくるのだが。 使いたいサービスが他のサービスに依存しているときに(CloudWatchとかS3とか)、 GlueサービスとかLambdaサービスのリソースにアタッチされているRoleにcloudwatchとかの作成や修正の権限が無いと動かせない。
って事なのかなと理解してる。
違ってたら修正したい。
次はAssumeRole
AWS WAFを導入するための最低限必要な知識
AWS WAF(new)
古いものはclassicと表記されている。 今回検証対象としないため対象外
いわゆるWeb Application FireWallで。 SQLインジェクションとかXSSみたいな怪しいhttpリクエストをblockしてくれたりログ出してくれたりメトリクスを出してくれたりする。
設定対象
CloudFrontかALB(CLBは不可)にアタッチする。 akamaiやinacpsulaのようなCDN型みたいにCNAMEで指定するようなやり方では無い。 なのでオンプレとか他クラウドにアタッチはできない(ACMみたいなもん)
WEB ACL
名前の通りウェブアクセスコントロールリスト。 ブロックするアルゴリズムを設定する。 このACL自体にデフォルトアクションとしてallowとblockがある。
外部向けサービスなら基本的にallow 社内向けサービスとかで閉じたいならblock(cloudfront + s3みたいな構成でも使える。もちろんバケットポリシーでもいいが)
RuleGroup
ルールグループはルールの塊。 SQLインジェクションのルールとか。作る。 まずはマネージドルールを適用するところから始める。
自分でルールをカスタマイズもできるのでその場合はルールグループを作成することになる。
IP Sets
IPのホワイトリスト、ブラックリストを作成するにはここで作成する。 RuleGroupとは別管理になるが。 WEB Acl側から見ると適用するルールの一つということになるのでこれもWEB ACLにセットすることになる。
AWSマネージドルール
AWSがあらかじめ用意してくれてるルールで、 terminatingRuleMatchDetails というSQLインジェクションとXSSにおいて bodyのログを出してくれるのはマネージドルールだけ。
今回はAMRsからCore rule setとSQL databaseを利用します。セットアップ方法は下記を参照してください。
クラスメソットさん参照
この後はWAF Charmとfirehose & s3を使ったログについて
s3のVPCエンドポイント情報
基本機能
https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-endpoints.html
- サブネット単位で設定可能 -- 実際はRouteTable単位
インターフェースエンドポイントとゲートウェイエンドポイントがある。 s3はゲートウェイエンドポイント。
https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpce-gateway.html
プレフィックスリストの ID の形式は pl-xxxxxxx で、プレフィックスリストの名前の形式は「com.amazonaws.region.service」
作るとこいう感じのリソースができるので、 これをサブネットのRouteTBLに追加すると設定される。
エンドポイントにはエンドポイントポリシーが割振れて、これでアクセスコントロールが出来る。 今はまだ全許可しかしてない。 (アウトバウンドを抑制するようなセキュリティ要件が厳しい場合に使用するのか?)
1 つの VPC 内に複数のエンドポイントを (複数のサービス用などに) 作成できます。また、1 つのサービス用に複数のエンドポイントを作成し、複数のルートテーブルを使用して、この同じサービスに複数のサブネットから異なるアクセスポリシーを適用することもできます。
なるほど。S3とDynamoDBと両方ともをVPCエンドポイントにする場合二つのエンドポイントを一つのRouteテーブルに紐付ける形になると。
きになる制限
https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-endpoints-s3.html
エンドポイントポリシーでは、Docker イメージレイヤーを保存するために Amazon ECR で使用される Amazon S3 バケットへのアクセスを許可する必要があります。詳細については、Amazon Elastic Container Registry ユーザーガイドの「インターフェイス VPC エンドポイント (AWS PrivateLink)」を参照してください。
ECR使ってる場合ECRのバケットへの許可を明示的にやる必要がありそう。
特定の S3 バケットへのアクセスを制限するポリシーを作成できます。これは、VPC で S3 バケットを使用する他の AWS サービスがある場合に便利です。my_secure_bucket のみへのアクセスを制限するポリシーの例を次に示します。
なるほど。VPCエンドポイント側の設定でVPC内部のリソースからのアクセスを制御できると。
バケットポリシー側でもできると。 リクエストを出す側と受け付ける側。どちら側でやるかは好みだと思うけど。
それなりに複雑になってきてる構成の場合エンドポイントルールでやるのはそれなりに効率良さそう。
python3.6で文字リテラルに変数を組み込むf文字列
メモ書き程度に
s3のパスなんかを指定するときにディレクトリ名(擬似だが)指定するときに連結したりformatするよりもコレが便利だと思った
baccket_name = "hoge-bucket" file_path = "/foo/bar/hogehoge.json" s3_path = f"s3://{baccket_name}{file_path}"
fを先頭に入れてダブルクオートで括って、 {}で括って変数を入れる。
AWS GlueJob(Pythoh shell)でMySQL(RDS | Aurora MySQL compatible)に接続する
なぜだかは不明だが(pythonの事がわかってないからなのか)GlueのPython実行(PythonShel)にはMySQLへの接続ライブラリが無い。
https://docs.aws.amazon.com/ja_jp/glue/latest/dg/add-job-python.html
しょうがないので外部ライブラリとして作って自分のバケットにおいて読み込ませる事にした。
ドキュメント漁ってもいまいち一気通貫に行かなかったので、 実際やったことを記録しておく。
ライブラリをローカルに取得してeggファイルを作る
git clone https://github.com/PyMySQL/PyMySQL.git cd PyMySQL/ python setup.py bdist_egg
これでdistディレクトリ配下にeggファイルが作成されるので。 この
PyMySQL-0.9.3-py3.6.egg
ファイルをGlueが読み込めるS3のバケットに配置してやる。
注意点
eggファイルを作る時のpythonバージョンとGlue上のPythonバージョンを揃える事。 このファイルを作った時は
Python 3.6.9
揃ってないとjob実行時にエラーになります。
S3の設定
Jobからread可能なS3の適当な場所にアップロードする
Glue側の設定
GlueのJob設定の
Python library path
という所にS3のフルパスを記入してやる。
s3://バケット/PyMySQL-0.9.3-py3.6.egg
みたいな感じ。 これで後は
import pymysql.cursors
みたいな感じでjobから読み出せる。
次はDataframe使っていい感じにETLする。
glueで開発エンドポイントを使用してdynamic dtaframe触って見たときの覚書
# とりあえず必要そうなものと使いそうなものをimport import sys from awsglue.transforms import * from awsglue.utils import getResolvedOptions from pyspark.context import SparkContext from awsglue.context import GlueContext from awsglue.job import Job import datetime import pprint # サンプルソースから引っ張り、scはspark contextの実態の予定だったが実際はインスタンス化できず # databaseurlはjdbc接続形式 glueContext = GlueContext(sc) dynamicframe = glueContext.create_dynamic_frame.from_options( connection_type='mysql', connection_options={ 'url': database_url, 'user': user_name, 'password': password, 'dbtable': table_name }) # dynamic frameで実行(とりあえずこれで見られる) dynamicframe.select_fields(['hoge', 'foo']).show() # ざっくり全件みたいなら dynamicframe.show() # 件数知りたいなら dynamicframe.count() # 列を追加したい場合は一度sparkd dataframeに変換する hoge = dynamicframe.toDF() # 関数を使って挿入 hoge = hoge.withColumn('hoge_id', lit(999)) # dynamic frameに戻す dynamicframe = dynamicframe.fromDF(hoge,glueContext ,dynamicframe) # あとはs3に書いたりする