search
LoginSignup
0

posted at

updated at

oreoreCLIを作って最速で静的ホスティングを行う

3-shake Advent Calendar2022の22日目です。

初めに

自分は最近flutterやReactなどで作業をしている時にふと思うことがあります
GO「よし一旦できたから成果物webに上げてみるか〜」
GO「えっとS3作ってポリシー設定して成果物ドラック&ドロップして...めんどくさい」
そうなんですこの作業が毎回億劫なんです!!
え、CICDつくればいいじゃんって?さすがにそこまで構築するのはオーバーすぎる
そうだ俺俺CLIつくろう!!

前提条件

  • 詳しいコードの説明はしません
  • Pythonを知っている方向けです

ディレクトリ構造

oreorecli
├── code
│   ├── __init__.py
│   └── core.py
└── setup.py

それぞれのファイルの説明

code/core.py

ここはCLIで動かしたい実際の処理を記述します。
今回はここでは下記のような実装を行いました

  • S3バケットの作成
  • 静的ホスティングの設定
  • バケットポリシーの付与
  • サブコマンドで渡されてきたディレクトリの中身をS3にアップロードする

setup.py

ここはCLIの設定を記述する部分です
CLI自体の名前やバージョン、使用するPythonのバージョンなども記載しています

コード説明

core.py

import boto3
import json
import time
import argparse
from multiprocessing import Process
import subprocess

# サブコマンド定義
p = argparse.ArgumentParser()
p.add_argument('dist', help='公開したいフォルダ')
args = p.parse_args()


def main():

  s3 = boto3.client("s3")
  now_time =int(time.time())

  args_dist = args.dist
  target = '=' 
  idx = args_dist.find(target)
  fix_dist = args_dist[idx+len(target):]


  #バケットポリシー定義
  bucket_policy = {
      'Version': '2012-10-17',
      'Statement': [{
          'Sid': 'AddPerm',
          'Effect': 'Allow',
          'Principal': '*',
          'Action': ['s3:GetObject'],
          'Resource': f'arn:aws:s3:::{str(now_time)}/*'
      }]
  }

  # S3バケット作成
  res = s3.create_bucket(ACL="public-read",
                        Bucket=str(now_time),
                        CreateBucketConfiguration={
                          "LocationConstraint": "ap-northeast-1"
                          })

  # S3バケットに静的ホスティング設定
  response = s3.put_bucket_website(
      Bucket=str(now_time),
      WebsiteConfiguration={
          'IndexDocument': {
              'Suffix': 'index.html'
          },
      },
  )
  bucket_policy = json.dumps(bucket_policy)

  s3.put_bucket_policy(Bucket=str(now_time), Policy=bucket_policy)
  
  #引数で渡されたものをS3にアップロード
  cmd_sync =f'aws s3 sync {fix_dist} s3://{str(now_time)}/'
  print("アップロード中です・・・")
  result = subprocess.Popen(cmd_sync.split(" "))
  result.wait()
  print("完了しました")
  print("以下のURLからアクセスできます")
  print(f"http://{str(now_time)}.s3-website-ap-northeast-1.amazonaws.com")


ポイント

  • S3バケットの名前は被らないようにunixtimeを取得してそちらを名前に使っている
  • アップロードする時にプロセスの終了を待って完了したら静的ホスティングのURLをprintしている
  • 引数distでローカル上でアップロードしたいフォルダを指定できるようにしている

setup.py

from setuptools import setup, find_packages
setup(
    name="oreorecli",
    version="0.0.1",
    description="s3で静的ホスティングを行うCLI",
    install_requires=["boto3"],
    author="masaki.go",
    entry_points={
        "console_scripts": [
            "oreorecli=sample.core:main",
        ]
    },
    classifiers=[
        'Programming Language :: Python :: 3.9',
    ]
)

ポイント

  • install_requiresにしようするパッケージを記載している。今回はboto3
  • console_scriptsではどのコマンドを叩いた時にcore.pyのmain関数を動かすかを定義しています

実際に叩いてみる

今回はflutterをwebようにビルドして成果物はローカルにあります

oreorecli dist=web/
アップロード中です・・・
upload: web/favicon.png to s3://1671008872/favicon.png
upload: web/icons/Icon-maskable-192.png to s3://1671008872/icons/Icon-maskable-192.png
upload: web/icons/Icon-192.png to s3://1671008872/icons/Icon-192.png
upload: web/manifest.json to s3://1671008872/manifest.json
upload: web/index.html to s3://1671008872/index.html
upload: web/icons/Icon-maskable-512.png to s3://1671008872/icons/Icon-maskable-512.png
upload: web/icons/Icon-512.png to s3://1671008872/icons/Icon-512.png
完了しました
以下のURLからアクセスできます
http://1671008872.s3-website-ap-northeast-1.amazonaws.com

最後に

AWSのCLIでよくない?っていう意見は受け付けていません!!!!w

パッケージの配布の仕方などはこちらの記事がとてもよく纏まっていました。
https://www.karakaram.com/how-to-create-python-cli-package/

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0