ECS on Fargate環境でPythonコードを使ってRDS:MySQLへ接続する

  • 2021年11月7日
  • 2021年11月7日
  • AWS, IT
AWS

こんにちはますのです。Python初心者です。
pipとpip3の違いが分かっていないレベルです。

そんなわたしですが、こんな依頼を頂きました。

  • EC2で動いているPythonのタスクサーバをECSへ移行したい
  • コード管理はGithubで行いたい
  • Github Actionsでデプロイしたい
  • パスワード関係はGithubのSecretsに保存する

omg…
何言ってるのか分からねぇけどやるしかねぇ。

とりあえずコードは現在利用されているものを使いまわします。
そしてコードを見ていて気付きます。

「RDSへの接続」が必要

PythonコードでのMySQLの接続で苦労した部分が多かったのでメモです。

configparser」を使ってiniファイルを作成し、iniファイルを読み込む方法で解決

今回は「configparser」を利用してiniファイルからパスワードを読み込む方法を使いました。
全体の流れとしては以下の通り。

  • GithubのSecretsにRDSパスワードを格納
  • GibhubActionsでECSへデプロイ
  • ECSonFarageteのコンテナ内「./config/rds_pass」にSecrets内容を展開
  • Pythonを実行して「rds_pass」から「config.ini」を作成
  • config.iniを利用してMySQLへ接続する

Python2と3の違いに気付かずハマった「ConfigParser」と「configparser」

ちなみに最初は「ConfigParser」を使ってエラーに苦しめられていました。

# Python3の場合
import configparser
config = configparser.ConfigParser()

# Python2の場合
import ConfigParser
config = Configparser.ConfigParser()

参考記事:Python2のConfigParserで読み込んだ設定ファイルの内容を辞書型で扱えるようにする

大文字と小文字の違いがあることに気付いたのは色々回避策を試したあとのこと…。
Python3とPython2のバージョン違いを意識せずに検索していたので、プログラムは世知辛いことを実感したのです。

Pythonの実装例

さて、では実際に実装時に使ったコードです。

iniファイル作成のコード部分

パスワード以外もSecrets保存したいというお話が出たため、「rds_user」「rds_dbname」も追加しています。

import configparser

print('Make config.ini ')
f1 = open('./config/rds_pass', 'r')
f2 = open('./config/rds_user', 'r')
f3 = open('./config/rds_dbname', 'r')

rds_password = f1.read()
rds_user = f2.read()
rds_dbname = f3.read()

config = configparser.ConfigParser()
config['RDSParameter'] = {'pass': rds_password,
                          'user': rds_user,
                          'dbname': rds_dbname}
with open('config.ini', 'w') as configfile:
  config.write(configfile)

print('Read RDS Settings')
config.read('config.ini')
config.sections()
config['RDSParameter']['pass']
config['RDSParameter']['user']
config['RDSParameter']['dbname']

参考:configparser — 設定ファイルのパーサー

Secretsにiniファイルを登録する場合、改行が消えてしまいます。
改行を残すためには「base64」でエンコード→デコード処理をして改善出来ることを後日知りました。
GithubのSecretsに保存する前にひと手間ありますが、運用管理上クリア出来るのであれば「base64」でiniファイルを作成する方が良いかなと所感です。

作成したiniファイルを利用してRDSのMySQLへ接続する

今回接続には「pymysql」モジュールを使いました。

import pymysql
conn = pymysql.connect(
host='RDSのエンドポイント名',
user=config['RDSParameter']['user'],
db=config['RDSParameter']['dbname'],
password=config['RDSParameter']['pass'],
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)

これでiniファイルの情報を利用して接続することが出来ました。

本当はhostも含めてiniファイル作りたかったのです。
手抜き感お許しください。

最後に

RDSにパスワード認証じゃなくてIAM認証とかしなさいよ
もう少しスマートなやり方あるでしょうよ
というお声もあるだろうなぁと思います。

Python初めて利用ということでその点は寛大なお心で見て頂ければと。
この情報は脆弱性あるから推奨されてないで!っていうものがあれば、その時は教えて頂けると嬉しいです。

参考にしたサイト

Python2のConfigParserで読み込んだ設定ファイルの内容を辞書型で扱えるようにする

configparser — 設定ファイルのパーサー

 

最新情報をチェックしよう!