dockerでFTPサーバーを作成し、PythonとSSMのパラメーターストアを利用してファイルのアップロードをしてみた

2022.12.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

データアナリティクス事業本部のueharaです。

今回はdockerイメージからFTPサーバーを作成し、PythonでSSMのパラメーターストアに保管しているアカウント情報の取得、ファイルの作成・アップロードを行うという検証をしてみたいと思います。

dockerによるFTPサーバーの構築

dockerによるFTPサーバーの構築は、こちらの記事で紹介されています。 今回は上記記事を参考に、ローカル環境にFTPサーバーの構築を行います。

dockerイメージのダウンロード

まず、docker-pure-ftpdのイメージをダウンロードします。

docker pull stilliard/pure-ftpd

コンテナの起動

先程掲載した記事を参考に、今回は以下のdocker-compose.ymlファイルを作成します。

docker-compose.yml

version: '3'

services:
  ftpd_server:
    image: stilliard/pure-ftpd
    container_name: pure-ftpd
    ports:
      - "21:21"
      - "30000-30009:30000-30009"
    
    # docker-compose.ymlがあるディレクトリに、コンテナとの共有ディレクトリを作る
    volumes: 
      - "./data:/home/testuser/"
      - "./passwd:/etc/pure-ftpd/passwd"

    environment:
      PUBLICHOST: "localhost"
      FTP_USER_NAME: testuser
      FTP_USER_PASS: test123
      FTP_USER_HOME: /home/testuser

    restart: always

今回はあくまでローカル環境での検証を目的としているため、FTP_USER_NAMEtestuserFTP_USER_PASStest123としました。

コンテナとの共有ディレクトリについても、docker-compose.ymlを置くディレクトリと同じ階層としています。

docker-compose.ymlの準備が完了したら、docker-compose.ymlがあるディレクトリでdocker-compose upを実行し、コンテナを起動します。

docker-compose up

コンテナを起動すると、ホスト側に共有ディレクトリが作成され、以下のようになっているかと思います。

.
├ data
├ docker-compose.yml
└ passwd

以上でFTPサーバーの構築は完了です。

FTP接続用アカウント情報をSSMに保管

アカウント情報の管理・取得方法は種々あるかと思いますが、今回はSSMのパラメーターストアを利用してみます。

準備

AWSコンソールにサインインを行い、「AWS Systems Manager > パラメーターストア」からパラメーターの作成を行います。

パラメーター名は/cm-uehara/ftp/testとし、検証用ですが一応アカウント情報のためタイプは安全な文字列を選択、値はtestuser:test123とユーザー名とパスワードをコロンで区切る形としました。

アカウント情報の取得テスト

以下のPythonプログラムを実行し、SSMのパラメーターストアからアカウント情報が取得できるか確認してみます。

ssm_test.py

import boto3


ssm_client = boto3.client("ssm")

# SSMからパラメーター情報の取得
ftp_account = ssm_client.get_parameters(
    # SSMに登録したパラメーター名の設定
    Names=["/cm-uehara/test/ftp"],
    WithDecryption=True,
)["Parameters"][0]["Value"]

# ユーザー名とパスワードを分離
ftp_username, ftp_password = ftp_account.split(":")

print(f"username: {ftp_username}\npw: {ftp_password}")

実行後、以下のようにアカウント情報が表示できていれば成功です。

username: testuser
pw: test123

PythonによるFTPサーバーへのファイルのアップロード

FTPサーバーへのアクセスは標準モジュールであるftplibを使います。

作成・アップロードするファイルの仕様は簡単ですが以下とします。

  • 「何らかの処理」を行った結果のステータスファイル(success/fail)を作成、アップロードする
  • 「何らかの処理」の実行時間を記録し、ファイル名は「%Y%m%d_%H%M%S_(success/fail).txt」とする
  • ファイルの中身には「success/fail」のみを書き込む

上記を踏まえ、作成したftp_test.pyは次のようになります。

import datetime
import ftplib
import io

import boto3


ssm_client = boto3.client("ssm")

ftp_account = ssm_client.get_parameters(
    Names=["/cm-uehara/test/ftp"],
    WithDecryption=True,
)["Parameters"][0]["Value"]

ftp_username, ftp_password = ftp_account.split(":")

status = None
time_now = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
try:
    """
    何かしらの処理
    """
    # raise Exception() # 確認用
    status = "success"
except:
    status = "fail"

# FTPのconfigを作成
ftp_config = {
    "host": "localhost",
    "user": ftp_username,
    "passwd": ftp_password,
}

# ファイルのアップロード
with ftplib.FTP(**ftp_config) as ftp:
    bytes_io = io.BytesIO(bytes(status, encoding="utf-8"))
    filename = f"{time_now}_{status}.txt"
    ftp.storbinary(f"STOR {filename}", bytes_io)

上記を実行し、ホスト側の共有ディレクトリであるdataに、20221204_174732_success.txtのようなファイルが作成されていれば成功です。

.
├ data
  └ 20221204_174732_success.txt
├ docker-compose.yml
└ passwd

テキストの中身は以下のようになっています。

20221204_174732_success.txt

success

ftp_test.py# raise Exception() # 確認用のコメントアウトを外すと、20221204_174732_fail.txtのようなファイルが作成されることを確認できます。

最後に

今回はdockerイメージからFTPサーバーを作成し、PythonでSSMのパラメーターストアに保管しているアカウント情報の取得、ファイルの作成・アップロードを行うといった検証をしてみました。

参考になりましたら幸いです。

参考文献