Amazon Q Developerでプログラムを作ってみよう
投稿日: 2025/07/22
はじめに
こんにちは、高橋です。
前回は、Amazon Q Developerの概要と利用開始方法についてご紹介しました。今回は、Amazon Q Developerを使用して実際の現場で主に行われると思われる下記の3つの作業を実施してみたいと思います。
- プログラムの作成
- プログラムの解読(内容の理解)
- 作成済みプログラムを Lambda に変換
1.プログラムの作成
最初はAmazon Q Developerに指示を出して、プログラムの作成を行ってみたいと思います。
今回はAmazon RedShiftに保存されているCost and Usage Reportのデータから、アカウント毎に実際の従量に当たるものだけを合計し、CSVファイルに結果を出力するプログラムをPythonで作成してみたいと思います。これを実行するには以下の条件を実行するプログラムを作成する必要があります。
- Amazon RedShiftに適切なIDで適切なテーブルにアクセス
- アカウントIDを「lineitem/usageaccount」列から参照
- 集計の対象は「lineitem/lineitemtype」が「usage」になっている行
- 実際の従量は「lineitem/unblendedcost」を参照
また、テーブル名は月単位で分割されており、年月を変数とした定型の名前なので、プログラム内で自動で作成するように指示します。
これを満たすためにプロンプトには下記の内容を入力します。
下記の条件でプログラムを作成してください。
- 言語はPythonで記載
- データはRedShiftに保存
- RedShiftのエンドポイントは「XXXXXXXXXXXXX.cxhxmepe1lni.ap-northeast-1.redshift.amazonaws.com:5439/AAA」
- RedShiftのログインIDは「bbbbb」で、パスワードは「A1234567」
- テーブル名は「awsbillingYYYYMM」(YYYYは年、MMは月)
- 年月は現在の時刻から取得
- アカウントID毎(lineitem/usageaccount列に格納)に従量金額(lineitem/unblendedcost列に格納)の合計額を算出
- 対象は「lineitem/lineitemtype」列の値が「usage」になっている行のみ
実際のプログラム作成の過程では下記の出力がありました。
I’ll create a Python program that connects to RedShift, queries the billing data, and outputs the results to a CSV file according to your requirements.
Let me write the code for you:
Creating the Python script to query RedShift and output billing data to CSV
Allow file modification outside of your workspace
Allowed
I need permission to modify files outside of your workspace.
redshift_billing_query.py
redshift_billing_query.py
+52
-0
Undo
Creating requirements.txt file for dependencies
Allow file modification outside of your workspace
Allowed
I need permission to modify files outside of your workspace.
requirements.txt
requirements.txt
+2
-2
Undo
Undo all changes
プログラムを作成しました。以下は実装の説明です:
ファイル構成
redshift_billing_query.py - メインのPythonスクリプト
requirements.txt - 必要なライブラリの依存関係
プログラムの機能
現在の年月を取得して、テーブル名 awsbillingYYYYMM を動的に生成
RedShiftに接続(指定されたエンドポイント、ユーザー名、パスワードを使用)
アカウントID毎に従量金額の合計を計算するSQLクエリを実行
lineitem/lineitemtype が 'Usage' の行のみを対象
結果を output.csv ファイルに出力
実行方法
必要なライブラリをインストール:
pip install -r requirements.txt
Copy
スクリプトを実行:
python redshift_billing_query.py
Copy
注意点
RedShiftの接続情報(特にパスワード)は本番環境では環境変数や設定ファイルから読み込むことをお勧めします
大量のデータを扱う場合は、メモリ使用量に注意が必要です
このプログラムは指定された要件に従って、RedShiftからAWSの請求データを取得し、アカウントID毎に合計金額を計算してCSVファイルに出力します。
ファイルとしてはプログラムの本体の「redshift_billing_query.py」と必要なライブラリが記載された「requirements.txt」が作成されました。プロンプトに「RedShiftの接続情報(特にパスワード)は本番環境では環境変数や設定ファイルから読み込むことをお勧めします」と記載されているので、そうするように再度指示を出して、プログラムの改変してみます。
RedShiftの接続情報(特にパスワード)は本番環境では環境変数や設定ファイルから読み込むように変更してください。
環境変数から接続情報を読み込むように変更します。特にパスワードなどの機密情報は環境変数から取得するようにします。
環境変数から接続情報を読み込むように変更し、SQLクエリのカラム名も修正
redshift_billing_query.py
+10
-9
Undo
環境変数の例を示すサンプルファイルを作成
Allow file modification outside of your workspace
Allowed
I need permission to modify files outside of your workspace.
.env.example
.env.example
+5
-0
Undo
使用方法を説明するREADMEファイルを作成
Allow file modification outside of your workspace
Allowed
I need permission to modify files outside of your workspace.
README.md
README.md
+22
-0
Undo
環境変数を読み込むためのpython-dotenvライブラリを追加
requirements.txt
+2
-1
Undo
dotenvライブラリを使って.envファイルから環境変数を読み込む機能を追加
redshift_billing_query.py
+4
-0
Undo
パスワードが環境変数から取得できない場合はエラーを発生させるように変更
redshift_billing_query.py
+5
-1
Undo
Undo all changes
環境変数から接続情報を読み込むように変更しました。主な変更点は以下の通りです:
環境変数の利用:
os.environ.get() を使用して環境変数から接続情報を取得するように変更
特にパスワードはデフォルト値を設定せず、環境変数から取得できない場合はエラーを発生させるようにしました
dotenv の導入:
python-dotenv ライブラリを追加し、.env ファイルから環境変数を読み込めるようにしました
これにより、環境変数をファイルで管理できるようになります
サポートファイルの作成:
.env.example - 必要な環境変数の例を示すサンプルファイル
README.md - 使用方法を説明するドキュメント
使用方法
.env.example ファイルを .env としてコピーし、実際のパスワードを設定します
必要なライブラリをインストールします: pip install -r requirements.txt
スクリプトを実行します: python redshift_billing_query.py
これで、セキュリティが向上し、本番環境での運用に適した形になりました。パスワードなどの機密情報はソースコードに直接記載せず、環境変数から取得するようになっています。
この変更により、環境変数のサンプルファイル「.env.example」が追加されました。最終的に作成されたファイルは以下の3つとなります。
redshift_billing_query.py
import psycopg2
import pandas as pd
import os
from datetime import datetime
from dotenv import load_dotenv
# .envファイルから環境変数を読み込む
load_dotenv()
# 現在の年月を取得
current_date = datetime.now()
year_month = current_date.strftime("%Y%m")
# RedShiftの接続情報を環境変数から取得
redshift_endpoint = os.environ.get("REDSHIFT_ENDPOINT", " XXXXXXXXXXXXX.cxhxmepe1lni.ap-northeast-1.redshift.amazonaws.com ")
redshift_port = os.environ.get("REDSHIFT_PORT", "5439")
redshift_database = os.environ.get("REDSHIFT_DATABASE", "AAA")
redshift_user = os.environ.get("REDSHIFT_USER", " bbbbb")
redshift_password = os.environ.get("REDSHIFT_PASSWORD")
# パスワードが設定されていない場合はエラー
if not redshift_password:
raise ValueError("環境変数REDSHIFT_PASSWORDが設定されていません")
# テーブル名を設定
table_name = f"awsbilling{year_month}"
# RedShiftに接続
conn = psycopg2.connect(
host=redshift_endpoint,
port=redshift_port,
dbname=redshift_database,
user=redshift_user,
password=redshift_password
)
try:
# SQLクエリを作成
query = f"""
SELECT "lineitem/usageaccountid" as account_id,
SUM("lineitem/unblendedcost") as total_cost
FROM {table_name}
WHERE "lineitem/lineitemtype" = 'Usage'
GROUP BY "lineitem/usageaccountid"
ORDER BY total_cost DESC
"""
# クエリを実行してデータフレームに格納
df = pd.read_sql_query(query, conn)
# CSVファイルに出力
df.to_csv("output.csv", index=False)
print(f"データの取得と出力が完了しました。{len(df)}件のアカウントデータが出力されました。")
except Exception as e:
print(f"エラーが発生しました: {e}")
finally:
# 接続を閉じる
conn.close()
requirements.txt
psycopg2-binary==2.9.9
pandas==2.0.3
python-dotenv==1.0.0
.env.example
REDSHIFT_ENDPOINT=XXXXXXXXXXXXX.cxhxmepe1lni.ap-northeast-1.redshift.amazonaws.com
REDSHIFT_PORT=5439
REDSHIFT_DATABASE=AAA
REDSHIFT_USER=bbbbb
REDSHIFT_PASSWORD=your_password_here
環境設定ファイルを「.env」に変更して、プログラムを実行すると(ライブラリは全てインストールされていたためスキップしました)、想定通りに動作することが確認できました。
[ec2-user@ip-10-0-2-111 test]$ python3 redshift_billing_query.py
/home/ec2-user/test/redshift_billing_query.py:49: UserWarning: pandas only supports SQLAlchemy connectable (engine/connection) or database string URI or sqlite3 DBAPI2 connection. Other DBAPI2 objects are not tested. Please consider using SQLAlchemy.
df = pd.read_sql_query(query, conn)
データの取得と出力が完了しました。5件のアカウントデータが出力されました。
[ec2-user@ip-10-0-2-111 test]$
[ec2-user@ip-10-0-2-111 test]$
[ec2-user@ip-10-0-2-111 test]$ cat output.csv
account_id,total_cost
111111111111,144.0
222222222222,144.0
333333333333,104.0
444444444444,85.0
555555555555,70.0
ここまでで、30分もかからずに完了しているので、一から私が考えて作成した場合の10~20%程度の時間でできてしまったと思います。
2.プログラムの解読
皆様の部署で古いプログラムは残っているものの、引継ぎがうまく行われておらず、説明もないため、困ったということはないでしょうか。今回は先程作成したプログラムから説明のコメントを全て、削除した上で、用途と実行方法を正しく説明してくれるか試してみました。実際の実行はプログラム(sample_read.pyと命名)をVScode上で開いて、このプログラムの実行方法と実行内容を教えてくださいと指定してみました。以下がその出力結果となります。
sample_read.pyの実行方法と実行内容を教えてください。
Context
sample_read.pyの実行方法と実行内容
実行方法
このPythonスクリプトは、コマンドラインから以下のように実行できます:
python sample_read.py
Copy
ただし、実行前に環境変数の設定が必要です。特にREDSHIFT_PASSWORDは必須で、.envファイルに設定するか、環境変数として直接設定する必要があります。
実行内容
このスクリプトは以下の処理を行います:
必要なライブラリ(psycopg2, pandas, os, datetime, dotenv)をインポート
.envファイルから環境変数を読み込み
現在の年月を取得し、YYYYMM形式で保存(例:202405)
RedshiftのDB接続情報を環境変数から取得
エンドポイント、ポート、データベース名、ユーザー名、パスワード
パスワードが設定されていない場合はエラーを発生
現在の年月を使用して対象テーブル名を生成(例:awsbilling202405)
Redshiftに接続
SQLクエリを実行して以下のデータを取得:
アカウントID(lineitem/usageaccountid)
アカウントごとの合計コスト(lineitem/unblendedcostの合計)
「Usage」タイプの項目のみを対象
コストの降順でソート
取得したデータをPandasのDataFrameに格納
データをoutput.csvファイルに出力
処理完了メッセージと取得したアカウント数を表示
最後にRedshift接続を閉じる
このスクリプトは、AWSの請求情報をRedshiftから取得し、アカウントごとの合計コストをCSVファイルに出力するものです。
最初にプログラムの実行方法と実行するためには環境変数を.envファイルに設定するか、環境変数として直接設定するとあり、プログラム本体以外に必要な設定・ファイルを上げてくれています。これは必要要件という項目を作成してそこに書いてくれた方が親切でしたが、それも投入するプロンプトを工夫すればできそうではあります。
次に実行内容として各ステップを解説してくれており、プログラムの実行内容を理解するのには便利であり、プログラムが長くなればなるほど、時間も労力も節約できそうではあります。
また最後に「AWSの請求情報をRedshiftから取得し、アカウントごとの合計コストをCSVファイルに出力するものです。」と正しく纏めてくれており、プログラムの迅速な理解に有用でした。さらに実際の流用を想定した場合、「.env」ファイルの作成を行う必要があるので、「.envファイルのサンプルを作成してください。」とプロンプトに入力したところ、下記の通り「.env」ファイルが作成され、これを使用すれば、プログラムを動かせることになります。
.env
REDSHIFT_ENDPOINT=XXXXXXXXXXXXX.cxhxmepe1lni.ap-northeast-1.redshift.amazonaws.com
REDSHIFT_PORT=5439
REDSHIFT_DATABASE=AAA
REDSHIFT_USER=bbbbb
REDSHIFT_PASSWORD=your_password_here
3.作成済みプログラムを Lambda に変換
最後に、サーバ上で動作しているプログラムをサーバレス環境へ移行するケースを想定し、先ほど作成したプログラムを AWS Lambda 上で実行できるように変換してみます。さらに、それだけでは実運用までつながらないので、変換したプログラムを実際に Lambdaへデプロイするところまでを試してみたいと思います。
Amazon Q Developerに対しては、シンプルに「redshift_billing_query.pyをLambda上で実行できるようにプログラムを修正してください」とプロンプトに入力しました。
redshift_billing_query.pyをLambda上で実行できるようにプログラムを修正してください
Context
Lambda関数として実行できるようにRedshiftのクエリスクリプトを修正します。Lambda関数では、スクリプトをハンドラー関数として実装し、環境変数の取得方法を調整する必要があります。
まず、現在のコードを確認しましょう。
Lambda関数として実行できるようにRedshiftのクエリスクリプトを修正します。Lambda関数では、スクリプトをハンドラー関数として実装し、環境変数の取得方法を調整する必要があります。
現在のアクティブファイルの内容を確認しました。このスクリプトをLambda関数として動作させるために、以下の変更が必要です:
Lambda用のハンドラー関数を作成する
dotenvの代わりにLambdaの環境変数を使用する
CSVファイルの出力先をLambdaの一時ディレクトリに変更する
必要に応じてS3へのアップロード機能を追加する
以下のように修正します:
Lambda関数として実行できるようにスクリプトを修正し、ハンドラー関数を追加、環境変数の取得方法を調整、ファイル出力先を/tmpに変更、S3アップロード機能を追加
Allow file modification outside of your workspace
Allowed
I need permission to modify files outside of your workspace.
redshift_billing_query.py
redshift_billing_query.py
+85
-56
Undo
Lambda関数として実行できるように、以下の変更を行いました:
Lambda用のハンドラー関数を追加
lambda_handler(event, context) 関数を作成し、すべてのコードをこの関数内に移動しました
適切なレスポンス形式(statusCodeとJSON形式のbody)を返すようにしました
環境変数の取得方法を変更
dotenvライブラリの使用を削除し、Lambda環境変数を直接使用するようにしました
S3バケット情報を環境変数から取得するオプションを追加しました
ファイル出力先の変更
CSVファイルの出力先をLambdaの一時ディレクトリ(/tmp)に変更しました
Lambdaでは /tmp 以外のディレクトリには書き込み権限がないため
S3アップロード機能の追加
環境変数 S3_BUCKET_NAME が設定されている場合、CSVファイルをS3にアップロードします
S3のキー名は環境変数 S3_KEY_PREFIX で指定するか、デフォルトで billing/account_costs_YYYYMM.csv を使用します
エラーハンドリングの強化
例外処理を改善し、エラーメッセージをJSON形式で返すようにしました
接続が開いている場合は確実に閉じるようにしました
Lambda関数のデプロイ方法
このスクリプトをLambda関数としてデプロイする際は、以下の環境変数を設定してください:
REDSHIFT_ENDPOINT - Redshiftのエンドポイント
REDSHIFT_PORT - Redshiftのポート番号(デフォルト: 5439)
REDSHIFT_DATABASE - データベース名(デフォルト: AAA)
REDSHIFT_USER - ユーザー名(デフォルト: bbbbb)
REDSHIFT_PASSWORD - パスワード(必須)
S3_BUCKET_NAME - 結果を保存するS3バケット名(オプション)
S3_KEY_PREFIX - S3のキー名(オプション)
Lambda関数に以下のライブラリをレイヤーとして追加するか、デプロイパッケージに含める必要があります:
psycopg2
作成されたプログラムは以下の通りです。
import psycopg2
import pandas as pd
import os
import boto3
import json
from datetime import datetime
def lambda_handler(event, context):
try:
# 現在の年月を取得
current_date = datetime.now()
year_month = current_date.strftime("%Y%m")
# RedShiftの接続情報を環境変数から取得
redshift_endpoint = os.environ.get("REDSHIFT_ENDPOINT", "XXXXXXXXXXXXX.cxhxmepe1lni.ap-northeast-1.redshift.amazonaws.com ")
redshift_port = os.environ.get("REDSHIFT_PORT", "5439")
redshift_database = os.environ.get("REDSHIFT_DATABASE", "AAA")
redshift_user = os.environ.get("REDSHIFT_USER", "bbbbb")
redshift_password = os.environ.get("REDSHIFT_PASSWORD")
# S3バケット情報を環境変数から取得(オプション)
s3_bucket = os.environ.get("S3_BUCKET_NAME")
s3_key = os.environ.get("S3_KEY_PREFIX", f"billing/account_costs_{year_month}.csv")
# パスワードが設定されていない場合はエラー
if not redshift_password:
raise ValueError("環境変数REDSHIFT_PASSWORDが設定されていません")
# テーブル名を設定
table_name = f"awsbilling{year_month}"
# RedShiftに接続
conn = psycopg2.connect(
host=redshift_endpoint,
port=redshift_port,
dbname=redshift_database,
user=redshift_user,
password=redshift_password
)
# SQLクエリを作成
query = f"""
SELECT "lineitem/usageaccountid" as account_id,
SUM("lineitem/unblendedcost") as total_cost
FROM {table_name}
WHERE "lineitem/lineitemtype" = 'Usage'
GROUP BY "lineitem/usageaccountid"
ORDER BY total_cost DESC
"""
# クエリを実行してデータフレームに格納
df = pd.read_sql_query(query, conn)
# Lambdaの一時ディレクトリにCSVファイルを出力
temp_file_path = "/tmp/output.csv"
df.to_csv(temp_file_path, index=False)
# S3にアップロード(オプション)
if s3_bucket:
s3_client = boto3.client('s3')
s3_client.upload_file(temp_file_path, s3_bucket, s3_key)
result_message = f"データの取得と出力が完了しました。{len(df)}件のアカウントデータがS3バケット {s3_bucket}/{s3_key} に保存されました。"
else:
result_message = f"データの取得と出力が完了しました。{len(df)}件のアカウントデータが/tmpに保存されました。"
# 接続を閉じる
conn.close()
return {
'statusCode': 200,
'body': json.dumps({
'message': result_message,
'record_count': len(df)
})
}
except Exception as e:
error_message = f"エラーが発生しました: {str(e)}"
print(error_message)
return {
'statusCode': 500,
'body': json.dumps({
'message': error_message
})
}
finally:
# 接続が開いている場合は閉じる
if 'conn' in locals() and conn:
conn.close()
主な変更点はAmazon Q Developerの回答にある様に以下の点です。
- Lambda用のハンドラー関数を作成する
- dotenvの代わりにLambdaの環境変数を使用する
- CSVファイルの出力先をLambdaの一時ディレクトリに変更する
- 必要に応じてS3へのアップロード機能を追加する
1つ目は、Lambdaの作法に則ったコード修正です。Lambda関数として正しく動作するよう、エントリポイントやハンドラーの形式を整えています。
2つ目は、環境変数の取得方法の変更です。元々は設定ファイルから読み込んでいましたが、Lambdaの環境変数機能を活用する形に変更しています。
3つ目と4つ目は、結果の出力先の変更です。3つ目では一時的なローカル出力を行い、4つ目では出力先を Amazon S3 に変更となります。実運用を想定すると、4つ目の S3への出力 がより妥当であり、運用面でも有効だと考えられます。
これで、Lambda上で実行可能なプログラムが完成しました。次のステップとして、実際にこのプログラムを Lambda環境に実装(デプロイ)する必要があります。
この作業についても、労力と時間を削減するためにAmazon Q Developerを活用することにしました。そこで、プロンプトに「このプログラムをLambda環境にデプロイするための手順を教えてください」と入力しました。
このプログラムをLambda環境にデプロイするための手順を教えてください
Context
Lambda環境へのデプロイ手順
1. デプロイパッケージの作成
mkdir -p package
pip install -t package pandas psycopg2-binary
cp redshift_billing_query.py package/
cd package
zip -r ../deployment_package.zip .
cd ..
Copy
2. AWS CLIでデプロイ
aws lambda create-function ¥
--function-name redshift-billing-query ¥
--zip-file fileb://deployment_package.zip ¥
--handler redshift_billing_query.lambda_handler ¥
--runtime python3.9 ¥
--timeout 60 ¥
--memory-size 512 ¥
--role arn:aws:iam::<アカウントID>:role/lambda-redshift-s3-role
Copy
bash
3. 環境変数の設定
aws lambda update-function-configuration ¥
--function-name redshift-billing-query ¥
--environment "Variables={REDSHIFT_ENDPOINT=s XXXXXXXXXXXXX.cxhxmepe1lni.ap-northeast-1.redshift.amazonaws.com,REDSHIFT_PORT=5439,REDSHIFT_DATABASE=AAA,
REDSHIFT_USER=bbbbb,REDSHIFT_PASSWORD=<パスワード>,S3_BUCKET_NAME=<バケット名>}"
Copy
4. VPC設定(Redshiftが非公開VPC内の場合)
aws lambda update-function-configuration ¥
--function-name redshift-billing-query ¥
--vpc-config SubnetIds=subnet-xxxx,subnet-yyyy,SecurityGroupIds=sg-zzzz
Copy
5. テスト実行
AWS Consoleから関数を開き、テストイベントを作成して実行します。
空のJSONオブジェクト {} で十分です。
注意点
Lambda実行ロールには以下の権限が必要です:
CloudWatch Logs書き込み権限
Redshift接続権限
S3バケットへの書き込み権限
パッケージサイズが大きい場合は、S3経由でデプロイしてください
本番環境ではRedshiftパスワードをAWS Secrets Managerで管理することを推奨します
メモリサイズは処理するデータ量に応じて調整してください
タイムアウトは60秒以上に設定することをお勧めします
結果として、5つの手順と注意事項が出力されました。
Lambda上にプログラムをアップロードするためには実際のプログラムとそれを実行するために必要なライブラリをパッケージ化したファイルを作成する必要があるのですが、手順1ではその手順がコマンドレベルで記載されています。手順2、3ではLambdaへのデプロイと環境変数の設定をAWS CLIから実行するコマンドが記されています。手順4ではプライベートネットワーク内のRedShiftへアクセスするための設定が指定され、手順5でテストの実行方法が指定されています。また、注意点にはLambdaに割り当てるIAMロールに必要な権限やファイルが大きすぎる場合のデプロイ方法に関する助言などが記載されています。
実際に記載の通りにコマンドを実行したところ、正常にLambda環境上にプログラムがデプロイされ、テストを実行すると正常にファイルが指定S3バケットに保存されました。

Lambda関数設定画面

テスト実行結果①

テスト実行結果②
この様にAmazon Q Developerを使用すれば、Lambdaに関する知識が乏しくても、簡単に既存のプログラムを変換して、Lambda上にデプロイすることができます。
6.さいごに
今回は Amazon Q Developer を活用し、コードの生成・解読(解説)・変更を試してみました。
私はインフラエンジニアで、コードを読むことはある程度できますが、実際に書くとなるとかなりの時間を要します。今回の作業も、独力でやる場合丸一日かかることを覚悟しなければなりませんが、Amazon Q Developerを使用したことで、わずか1時間足らずでコードの作成を完了することができました。
さらに、Amazon Q Developerはコードの作成だけでなく、AWSへの実装に関するアドバイスも得られるため、アプリケーション開発から実装までのスピードにおいて、Amazon Q Developerの活用の有無が大きな差を生むことは明らかです。
今後の業務効率化に向けて、皆様もぜひAmazon Q Developerの利用を検討してみてはいかがでしょうか。
CTCは、AWSのビジネス利活用に向けて、お客様のステージに合わせた幅広い構築・運用支援サービスを提供しています。
経験豊富なエンジニアが、ワンストップかつ柔軟にご支援します。
ぜひ、お気軽にお問い合わせください。