Cognitoの学習のため、DevSecOps – Integrating security into your pipeline の AWS WorkShop をやってみました。
タグに Cognito と記載がありますが、Cognito は登場しません。ご注意を。
この WorkShop 自体が古く、利用する Lambda のランタイムが Python2.7 です。
現在では利用できないので Python3.9 を利用しましたが、 Python2 から Python3 に変わったことで Lambda のソースコードがそのままでは利用できなくなっていました。
この記事では私が修正した箇所や、WorkShop を見ただけでは理解しにくい手順や補足を記載します。
Module 1: Environment build
WorkShop を開始する前に GitHub リポジトリをクローンする
まず WorkShop で利用するリポジトリがあるので、クローンします。
クローンしなくても GitHub リポジトリから直接コピペやダウンロードすれば WorkShop を完遂できますが、クローンした方が便利です。
git clone https://github.com/aws-samples/secure-pipelines-in-aws-workshop.git
新規作成するS3バケットについて
この S3 は、Lambda のコードの格納場所として機能します。
使用するのは最初だけで、以降は別の S3 に Zip ファイルをアップロードします。
そして、それをトリガーとして CodePipeline が起動します。
アップロードするZipファイルの修正
リポジトリ内の code/SecGuardRails.zip をそのまま S3 にアップロードすると、Lambda が動作しません。
理由としては、Lambda のハンドラーが cfn_validate_lambda.lambda_handler であるのに対し、Zipファイルの内容が以下の構造だからです。
.
├── SecGuardRails
│ ├── cfn_validate_lambda.py
│ └── stack_validate_lambda.py
└── __MACOSX
└── SecGuardRails
ハンドラーが含まれる Python ファイルが SecGuardRails ディレクトリの中にあるため、Lambda が正しく動作しません。
ハンドラーを変更するか、Lambda が動作するように Zip ファイルを再作成する方法がありますが、今回は Zip ファイルを再作成します。
対象の Python ファイルは code/SecGuardRails 内に配置されているため、同ディレクトリに移動した上、以下のコマンドで Zip ファイルを作成します。
cd code/SecGuardRails
zip SecGuardRails.zip cfn_validate_lambda.py stack_validate_lambda.py
上記により作成した SecGuardRails.zip ファイルを S3 にアップロードします。
Python 2.7 から Python 3.9 に変更
リポジトリの Pipeline.yml で、Lambda の Runtime を Python 2.7 としている箇所を Python 3.9 に変更します。
合計で 2 箇所あります。
Module 2: Encrypt the EBS
この手順でも、WorkShop どおりの手順にはなりません。
先ほど Lambda のランタイムを Python 3.9 に変更しましたが、Python 2 から Python 3 に変わった関係で、中身のソースコードを修正する必要があります。
以下の通り、2 つの関数を変更します。
変更しない場合のエラー内容は省略しますが、型関係のエラーとなります。
def get_template(s3, artifact, file_in_zip):
# 省略
with tempfile.NamedTemporaryFile() as tmp_file:
print("Retrieving s3://" + bucket + "/" + key)
s3.download_file(bucket, key, tmp_file.name)
with zipfile.ZipFile(tmp_file.name, 'r') as zip:
zip.printdir()
# 修正前. ストリング型が返却されません
#return zip.read(file_in_zip)
# 修正後
return zip.read(file_in_zip).decode('utf-8')
def s3_next_step(s3, bucket, risk, failedRules, template, job_id):
# 省略
for item in template:
# 修正前
# tmp_file.write(item)
# 修正後
item_bytes = item.encode("utf-8")
tmp_file.write(item_bytes)
なお、このモジュール以外でも、上記のとおり変更する箇所がいくつかあります(変更内容は同一です)。
さいごに
CloudFormation のセキュリティチェックに CodePipeline を作成することはないかもしれませんが、CodePipeline のステージで Lambda を呼び出せることを認識できてよかったです。
今なら、CloudFormation でのセキュリティチェックは CloudFormation Guard で行いそう(CodePipelineで行うかは置いておいて)。
