LoginSignup
11
11

Bedrockアプリに画面と認証を付けてインターネットに公開する一番簡単な手順 - Amazon Bedrock APIで始めるLLM超入門⑧

Last updated at Posted at 2024-02-18

作成したBedrockアプリのデモを行う際に、インターネットに公開したくなる事もあると思うので、一番簡単そうな手順を整理してみます。
インターネットに公開するので申し訳程度の認証機能も付けます。

初稿ではnon-SSL(HTTP)だったのですがSSL(HTTPS)の手順に変更しました

アーキテクチャ図

画面はStreamlitで作成しCloud9上で稼働させます。
インターネットからのアクセスはエッジロケーションのCloudFrontにてSSL(HTTPS)で受け、AWSネットワークバックボーンをnon-SSL(HTTP)で通って、Elastic IPをアタッチしたCloud9上のStreamlitにアクセスします。
AWSネットワーク内はnon-SSLなのでプロダクション環境では望ましくない場合があるかもしれませんが、デモ程度であれば問題ないかなと思います。

image.png

Bedrockへのモデルアクセスは許可済、リージョンはClaude2.1が使える前提です。

認証画面

こんな認証画面を付けます。
image.png

Cloud9環境の作成

名前を適当に付けて全てデフォルトでCloud9環境を作成します。(Admin権限で…)
(デフォルト)タイムアウトが30分なので、30分経つと終了しお財布にもセキュリティにも安心です。30分では短すぎる場合は伸ばして作成してください。

EC2インスタンスが作成されたら、ElasticIPの割り当て・作成したCloud9のEC2に対する関連付けを行います。

必要ライブラリのインストール

LangChainとStreamlitを使います(LangChainは使わなくても良いんですが、サンプルプログラムをスッキリさせる為だけに使っています)。認証用にstreamlit_authenticatorを使います。

pip install -U boto3 langchain langchain-community streamlit streamlit_authenticator

今回久しぶりにlangchainを触っていて気付いたのですが、私が過去に作ったlangchainを使うサンプルプログラム、今のバージョンだときっと全部動かないですね。どこかで直さないといけません。

プログラムの作成

認証機能は「付いていれば良い」の精神で、IDとパスワードは固定です。行儀が悪いですがプログラムにハードコーディングしています。
サンプルはIDがadmin、パスワードがpassとしていますが、これも行儀が悪いので適当に直してください。

凝れば色々出来そうなので詳しくは以下

hogehoge.py
from langchain_community.llms import Bedrock
import streamlit as st
import streamlit_authenticator as sa

# admin/pass 固定で認証情報を作成
authenticator = sa.Authenticate(
    credentials={"usernames":{"admin":{"name":"admin","password":"pass"}}},
    cookie_name="streamlit_cookie",
    key="signature_key",
    cookie_expiry_days=1
)

# ログイン画面描画
authenticator.login()

if st.session_state["authentication_status"]: #ログイン成功
    # ログイン後画面の描画

    authenticator.logout() #ログアウトボタン
    st.title("LangChainからのBedrock呼出し") #タイトル
    input_text = st.text_input("このテキストをBedrockに送信します")
    send_button = st.button("送信")
    
    # 送信ボタン押下
    if send_button:
        llm = Bedrock(model_id="anthropic.claude-v2:1") #Claude2.1
        answer = llm.invoke(input_text)
        st.write(answer)

elif st.session_state["authentication_status"] is False: #ログイン失敗
    st.error('Username/password is incorrect')
elif st.session_state["authentication_status"] is None: #未入力
    st.warning('Please enter your username and password')

上記の「ログイン後画面の描画」の部分がログイン後の本体、「送信ボタン押下」の部分がBedrockアクセスを行っている箇所になるので、ここだけ各自の処理に差し替えてもらえば良いかなと思います。チャットなりRAGなりAgentsなりKnowledge baseなり。

Streamlitから起動する

後でセキュリティグループに穴を開けるので、ポート番号はデフォルト(8501)で起動します。

python3 -m streamlit run hogehoge.py

Cloud9のプレビュー機能から見えれば充分な場合はポート番号8080を指定して起動してプレビュー機能で参照できます。

python3 -m streamlit run hogehoge.py --server.port 8080

セキュリティグループの穴開け

image.png

Cloud9のEC2インスタンスのセキュリティグループのインバウンドルールに対して、ポート:8501をプレフィックスリストのcom.amazonaws.global.cloudfront.origin-facingに対して許可をし、CloudFrontからのポート番号8501(Streamlit)宛のアクセスのみ許可します。

CloudFrontの作成

Cloud9のEC2インスタンスのパブリック IPv4 DNSをコピーしておきます。

CloudFrontのディストリビューションを作成します。

image.png

Origin domainはEC2インスタンスのパブリック IPv4 DNS

プロトコルはHTTPのみでPortは8501

image.png

ビューワープロトコルポリシーはHTTPS only

キャッシュポリシーはCachingDisabled

オリジンリクエストポリシーはAllViewer

image.png

WAFは適当に(適切に?)

image.png

料金クラスはお好みで

で、作成します。

image.png

作成後の画面にあるディストリビューションドメイン名をコピーします。

使ってみる

ドメインが有効になるまで数分かかります。

ブラウザから先ほどのディストリビューションドメイン名にアクセスするとログイン画面が表示されます。HTTPSでアクセス出来ています。

image.png

IDにadmin、パスワードにpassを入力しloginボタンを押下します。

image.png

ちょっと格好悪い動作の後に、本体部分が表示されます。

image.png

Bedrockへの問い合わせ内容を入力して送信ボタンを押下します。

インターネット上はSSLで通信されますので野生のハッカーは気にしなくて良いですが、AWSネットワーク内はnon-SSLで通信されますので、そこは認識しておいてください
(厳しいお会社様だとナニカに引っかかるかもしれません)

image.png

正しく動いている事が確認できました。
出力トークン数をデフォルトのままにしているので途中で切れていますね。

ログインするとCookieに保存されるので、Streamlitが起動していれば1日の間であれば再ログイン不要のはずです。

Logoutボタンを押下すると、ログアウトしてログイン画面に戻ります。

デモの実施が終わったら

認証が緩いので無効にしておいた方が無難です。
CloudFrontディストリビューションを無効にしつつ、セキュリティグループのインバウンドルールを削除しましょう。
(再開するのは手間じゃないと思います)

11
11
0

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
  3. You can use dark theme
What you can do with signing up
11
11