CHALICEの自動ポリシー生成 (Automatic policy generation) 対象範囲の検証
この記事では、CHALICEのAutomatic policy generation対象範囲が不明だったため、思いつく限り試し検証した結果を記載しています。
この記事では、CHALICEのAutomatic policy generation対象範囲が不明だったため、思いつく限り試し検証した結果を記載しています。
この記事の内容です。
TL;DR
app.py内にS3やDynamoDBといったLambda外を参照するコードを書きましょう。
対象読者
- CHALICEを使用していて自動ポリシー生成が行われない問題を解決したい方
環境
- Python v3.9.12
- CHALICE v1.27.1
CHALICEの自動ポリシー生成 (Automatic policy generation) の対象範囲検証および結果
以下の見出しは、boto3を使用しAutomatic policy generationのために処理を実装したファイルです。
app.py以外はすべて、app.pyに処理を実装したファイルおよび関数をimportしています。
プロジェクトはhelloworldという名前で作成しています。
app.py
以下のコードを実装。
from chalice.app import Chalice
app = Chalice(app_name='helloworld')
import boto3
@app.route('/')
def index():
s3 = boto3.client('s3')
s3.download_file()
結果: PolicyのStatement内に以下が追加される。(Sidは省略)
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"*"
],
},
project root/chalicelib内のファイル
プロジェクトルートにchalicelibディレクトリを作成し、その中に以下のファイルを作成する。
import boto3
def f():
s3 = boto3.client('s3')
s3.download_file()
次に、上記ファイルをapp.pyにimportし関数を参照させる。
from chalice.app import Chalice
app = Chalice(app_name='helloworld')
from chalicelib.hoge import f
@app.route('/')
def index():
f()
結果: PolicyのStatement内にS3の内容が追加されない。
project root/directory内のファイル
プロジェクトルートにfugaディレクトリを作成し、その中に以下のファイルを作成する。
import boto3
def f2():
s3 = boto3.client('s3')
s3.download_file()
次に、上記ファイルをapp.pyにimportし関数を参照させる。
from chalice.app import Chalice
app = Chalice(app_name='helloworld')
from fuga import f2
@app.route('/')
def index():
f2()
結果: PolicyのStatement内にS3の内容が追加されない。
project root内のファイル (app.pyと同階層)
プロジェクトルートに以下のファイルを作成する。
import boto3
def f3():
s3 = boto3.client('s3')
s3.download_file()
次に、上記ファイルをapp.pyにimportし関数を参照させる。
from chalice.app import Chalice
app = Chalice(app_name='helloworld')
from foo import f3
@app.route('/')
def index():
f3()
結果: PolicyのStatement内にS3の内容が追加されない。
結論
動作を確認する限りapp.pyのみAutomatic policy generationの対象範囲となっている。
そのため、app.py外にS3やDynamoDBなどを参照するコードを実装したい場合は、以下のような対応をとる必要がある。
from chalice.app import Chalice
app = Chalice(app_name='helloworld')
import boto3
@app.lambda_function()
def for_automatic_policy_generation():
s3 = boto3.client('s3')
s3.download_file()
@app.route('/')
def index():
# 何かしらの処理
ポリシー自動生成用にLambda関数を1つ実装することになりモヤモヤしますが、本記事執筆時点ではこうするしかないのかなと思います。
後述する参考にしたページでは
@app.route('/')
def index():
内にfor_automatic_policy_generationとほぼ同じ関数を呼び出すようにしていますが、全関数にそれを記述するのは美しくないですし、またダミーのWeb APIを生やすなら、どこからも参照されないLambda関数を1個作成する方が良いと考え上記の形にしています。