20210412のAWSに関する記事は18件です。

[Symbol] XYM未保有でもノード構築で収穫祭

概要 0XYMでもSymbolノード構築・運用でハーベスティング報酬(手数料)を貰うための構築手順を残します。 本記事は、ubuntu 20.04、symbol-bootstrap v1.0.3で確認しています。 委譲してもいいよという方は「13.230.96.240 (Ninja Hi-performance Symbol-Node)」まで 投げXYMは「NDLS6GYOIPHATATNAVVOUNJXBD6X4BXU6IRBHIY」まで 事前準備 まずは最新の公式情報に目を通しましょう。 サイト 備考 https://symbolnodes.org/ 全ての情報源 http://explorer.symbolblockchain.io/ アカウントやトランザクションの確認に便利 https://docs.symbolplatform.com/ja/ 公式ドキュメント https://github.com/nemtech/symbol-bootstrap symbol-bootstrapのgithub サーバの準備 今回はAWSでサーバを構築します。推奨スペックは、 「CPU: 8core、メモリ: 32GB、容量: 750GB、Diskスピード: 1500 IOPS SSD」 とのことなので、EC2インスタンスは 「t3a.2xlarge (CPU: 8core, メモリ: 32GiB, EBS[gp2]: 768GiB)」 にしました。 AMI:ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210223 SecurityGroup:TCP3000,7900portを0.0.0.0/0で公開(お好みでssh用なども追加してください) これで推奨スペック基準のubuntuサーバを用意できました。 環境構築 symbol-bootstrapを動作させるには、「Node, Docker, Docker Compose」がインストールされている必要があります。 下記手順でインストールしました。 既存パッケージ最新化 # sudo su - # apt update -y # apt upgrade -y 引き続きrootユーザのままで、 Nodeのインストール # curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - # apt install -y nodejs # node -v v14.16.1 npmを最新版にアップデート # npm install -g npm@latest # npm -v 7.9.0 symbol-bootstrapのインストール (4/12時点の最新バージョンはv1.0.3) # npm install -g symbol-bootstrap@1.0.3 # symbol-bootstrap -v symbol-bootstrap/1.0.3 linux-x64 node-v14.16.1 dockerのインストール # apt install -y apt-transport-https ca-certificates gnupg-agent software-properties-common # curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - # apt-key fingerprint 0EBFCD88 # add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" # apt install -y docker-ce docker-ce-cli containerd.io # docker -v Docker version 20.10.5, build 55c4c88 docker composeのインストール # curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose # chmod +x /usr/local/bin/docker-compose # docker-compose -v docker-compose version 1.27.4, build 40524192 dockerをrootユーザーではなく一般ユーザーで操作できるようにします。 ubuntuユーザーをdockerグループに入れ、dockerサービスを再起動します。 ここまでがrootユーザでの作業です。 # usermod -g docker ubuntu # /bin/systemctl restart docker.service # exit $ exit symbol-bootstrapの導入・起動 ここからは一般ユーザ(ubuntuユーザ)で行います。 まず、データが保存されていくディレクトリの作成と、設定ファイルの作成を行います。 $ cd ~/ $ mkdir -p ~/symbol-bootstrap/target $ cd ~/symbol-bootstrap $ vi my-preset.yml ----- nodes: - friendlyName: Ninja Hi-performance Symbol-Node maxUnlockedAccounts: 64 beneficiaryAddress: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ----- 推奨スペックとはいえ、現状そこそこリッチな環境なので、「maxUnlockedAccounts を 10(default) -> 64」へ引き上げます。 手数料が送られる、beneficiaryAddressは自分のウォレットアドレスを間違えないように入力します。 このウォレットアドレスの残高は0XYMでも問題ありません。 (ここが本記事の趣旨である0XYMでハーベスティングのキモです) 上記の設定で初期化します。 (下記コマンド実行時に、秘密鍵を扱うファイル操作用パスワードも設定します。) $ symbol-bootstrap config -p mainnet -a dual -c my-preset.yml 念のため、設定通りになっているかを確認します。 $ less target/nodes/node/server-config/resources/config-node.properties ----- [localnode] host = friendlyName = Ninja Hi-performance symbol node version = 1.0.0.0 roles = Peer,Api ----- 大丈夫なことが確認できたので、起動します。 $ symbol-bootstrap start --detached 起動確認 $ symbol-bootstrap healthCheck _ _ _ _ _ ___ _ _ _ __ ___ | |__ ___ | | | |__ ___ ___ | |_ ___ | |_ _ __ __ _ _ __ / __|| | | || '_ ` _ \ | '_ \ / _ \ | | _____ | '_ \ / _ \ / _ \ | __|/ __|| __|| '__|/ _` || '_ \ \__ \| |_| || | | | | || |_) || (_) || ||_____|| |_) || (_) || (_) || |_ \__ \| |_ | | | (_| || |_) | |___/ \__, ||_| |_| |_||_.__/ \___/ |_| |_.__/ \___/ \___/ \__||___/ \__||_| \__,_|| .__/ |___/ |_| 2021-04-12T13:44:42.140Z info Container db is running 2021-04-12T13:44:42.141Z info Container node is running 2021-04-12T13:44:42.146Z info Container broker is running 2021-04-12T13:44:42.146Z info Container rest-gateway is running 2021-04-12T13:44:42.149Z info Container node port 7900 -> 7900 is open 2021-04-12T13:44:42.149Z info Container rest-gateway port 3000 -> 3000 is open 2021-04-12T13:44:42.157Z info Testing http://localhost:3000/node/health 2021-04-12T13:44:42.173Z info Rest http://localhost:3000/node/health is up and running... 2021-04-12T13:44:42.174Z info Network is running! 初回はブロックチェーンの同期に時間が掛かりますが、しばらく経つとNode Listから自分のノードが確認できるようになります。 (下記NodeはVoting設定も追加しています) あとは委譲とハーベスティングされるのをゆっくり待つのみです。 みなさまも良い収穫ライフを!!! 参考情報 さくらのVPSでNEM Symbol のテストネットノード構築 NEM Symbol テストノード構築で GoTo 大家 [Symbol]委任したいノードが見つからない時にやること
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

XYM未保有でもNode構築で収穫祭

概要 0XYMでもSymbol Node構築・運用でハーベスティング手数料を貰うためのNode構築手順を残します。 本記事は、ubuntu 20.04、symbol-bootstrap v1.0.3で確認しています。 委譲してもいいよという方は「13.230.96.240 (Ninja Hi-performance Symbol-Node)」まで 投げXYMは「NDLS6GYOIPHATATNAVVOUNJXBD6X4BXU6IRBHIY」まで 事前準備 まずは最新の公式情報に目を通しましょう。 サイト 備考 https://symbolnodes.org/ 全ての情報源 http://explorer.symbolblockchain.io/ アカウントやトランザクションの確認に便利 https://docs.symbolplatform.com/ja/ 公式ドキュメント https://github.com/nemtech/symbol-bootstrap symbol-bootstrapのgithub サーバの準備 今回はAWSでサーバを構築します。推奨スペックは、 「CPU: 8core、メモリ: 32GB、容量: 750GB、Diskスピード: 1500 IOPS SSD」 とのことなので、EC2インスタンスは 「t3a.2xlarge (CPU: 8core, メモリ: 32GiB, EBS[gp2]: 768GiB)」 にしました。 AMI:ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210223 SecurityGroup:TCP3000,7900portを0.0.0.0/0で公開(お好みでssh用なども追加してください) これで推奨スペック基準のubuntuサーバを用意できました。 環境構築 symbol-bootstrapを動作させるには、「Node, Docker, Docker Compose」がインストールされている必要があります。 下記手順でインストールしました。 既存パッケージを最新化 # sudo su - # apt update -y # apt upgrade -y 引き続きrootユーザのままで、 Nodeのインストール # curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - # apt install -y nodejs # node -v v14.16.1 npmを最新版にアップデート # npm install -g npm@latest # npm -v 7.9.0 symbol-bootstrapのインストール (4/12時点の最新バージョンはv1.0.3) # npm install -g symbol-bootstrap@1.0.3 # symbol-bootstrap -v symbol-bootstrap/1.0.3 linux-x64 node-v14.16.1 dockerのインストール # apt install -y apt-transport-https ca-certificates gnupg-agent software-properties-common # curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - # apt-key fingerprint 0EBFCD88 # add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" # apt install -y docker-ce docker-ce-cli containerd.io # docker -v Docker version 20.10.5, build 55c4c88 docker composeのインストール # curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose # chmod +x /usr/local/bin/docker-compose # docker-compose -v docker-compose version 1.27.4, build 40524192 dockerをrootユーザーではなく一般ユーザーで操作できるようにします。 ubuntuユーザーをdockerグループに入れ、dockerサービスを再起動します。 ここまでがrootユーザでの作業です。 # usermod -g docker ubuntu # /bin/systemctl restart docker.service # exit $ exit symbol-bootstrapの導入・起動 ここからは一般ユーザで行います。 まず、データが保存されていくディレクトリの作成と、設定ファイルの作成を行います。 $ cd ~/ $ mkdir -p ~/symbol-bootstrap/target $ cd ~/symbol-bootstrap $ vi my-preset.yml ----- nodes: - friendlyName: Ninja Hi-performance Symbol-Node maxUnlockedAccounts: 64 beneficiaryAddress: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ----- 推奨スペックとはいえ、現状そこそこリッチな環境なので、「maxUnlockedAccounts を 10(default) -> 64」へ引き上げます。 手数料が送られる、beneficiaryAddressは自分のウォレットのアドレスを間違えないように入力します。 このウォレットアドレスの残高は0XYMでも問題ありません。 (ここが本記事の趣旨である0XYMでハーベスティングのキモです) 上記の設定で初期化します。 (下記コマンド実行時に、秘密鍵を扱うファイル操作用パスワードも設定します。) $ symbol-bootstrap config -p mainnet -a dual -c my-preset.yml 念のため、設定通りになっているかを確認します。 $ less target/nodes/node/server-config/resources/config-node.properties ----- [localnode] host = friendlyName = Ninja Hi-performance symbol node version = 1.0.0.0 roles = Peer,Api ----- 大丈夫なことが確認できたので、起動します。 $ symbol-bootstrap start --detached 起動確認 $ symbol-bootstrap healthCheck _ _ _ _ _ ___ _ _ _ __ ___ | |__ ___ | | | |__ ___ ___ | |_ ___ | |_ _ __ __ _ _ __ / __|| | | || '_ ` _ \ | '_ \ / _ \ | | _____ | '_ \ / _ \ / _ \ | __|/ __|| __|| '__|/ _` || '_ \ \__ \| |_| || | | | | || |_) || (_) || ||_____|| |_) || (_) || (_) || |_ \__ \| |_ | | | (_| || |_) | |___/ \__, ||_| |_| |_||_.__/ \___/ |_| |_.__/ \___/ \___/ \__||___/ \__||_| \__,_|| .__/ |___/ |_| 2021-04-12T13:44:42.140Z info Container db is running 2021-04-12T13:44:42.141Z info Container node is running 2021-04-12T13:44:42.146Z info Container broker is running 2021-04-12T13:44:42.146Z info Container rest-gateway is running 2021-04-12T13:44:42.149Z info Container node port 7900 -> 7900 is open 2021-04-12T13:44:42.149Z info Container rest-gateway port 3000 -> 3000 is open 2021-04-12T13:44:42.157Z info Testing http://localhost:3000/node/health 2021-04-12T13:44:42.173Z info Rest http://localhost:3000/node/health is up and running... 2021-04-12T13:44:42.174Z info Network is running! 初回はブロックチェーンの同期に時間が掛かりますが、しばらく経つとNode Listから自分のNodeが確認できるようになります。 (下記NodeはVoting設定も追加しています) あとは委譲とハーベスティングされるのをゆっくり待つのみです。 みなさまも良い収穫ライフを!!! 参考情報 さくらのVPSでNEM Symbol のテストネットノード構築 NEM Symbol テストノード構築で GoTo 大家 [Symbol]委任したいノードが見つからない時にやること
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Symbol] XYM未保有でもNode構築で収穫祭

概要 0XYMでもSymbol Node構築・運用でハーベスティング報酬(手数料)を貰うためのNode構築手順を残します。 本記事は、ubuntu 20.04、symbol-bootstrap v1.0.3で確認しています。 委譲してもいいよという方は「13.230.96.240 (Ninja Hi-performance Symbol-Node)」まで 投げXYMは「NDLS6GYOIPHATATNAVVOUNJXBD6X4BXU6IRBHIY」まで 事前準備 まずは最新の公式情報に目を通しましょう。 サイト 備考 https://symbolnodes.org/ 全ての情報源 http://explorer.symbolblockchain.io/ アカウントやトランザクションの確認に便利 https://docs.symbolplatform.com/ja/ 公式ドキュメント https://github.com/nemtech/symbol-bootstrap symbol-bootstrapのgithub サーバの準備 今回はAWSでサーバを構築します。推奨スペックは、 「CPU: 8core、メモリ: 32GB、容量: 750GB、Diskスピード: 1500 IOPS SSD」 とのことなので、EC2インスタンスは 「t3a.2xlarge (CPU: 8core, メモリ: 32GiB, EBS[gp2]: 768GiB)」 にしました。 AMI:ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210223 SecurityGroup:TCP3000,7900portを0.0.0.0/0で公開(お好みでssh用なども追加してください) これで推奨スペック基準のubuntuサーバを用意できました。 環境構築 symbol-bootstrapを動作させるには、「Node, Docker, Docker Compose」がインストールされている必要があります。 下記手順でインストールしました。 既存パッケージを最新化 # sudo su - # apt update -y # apt upgrade -y 引き続きrootユーザのままで、 Nodeのインストール # curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - # apt install -y nodejs # node -v v14.16.1 npmを最新版にアップデート # npm install -g npm@latest # npm -v 7.9.0 symbol-bootstrapのインストール (4/12時点の最新バージョンはv1.0.3) # npm install -g symbol-bootstrap@1.0.3 # symbol-bootstrap -v symbol-bootstrap/1.0.3 linux-x64 node-v14.16.1 dockerのインストール # apt install -y apt-transport-https ca-certificates gnupg-agent software-properties-common # curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - # apt-key fingerprint 0EBFCD88 # add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" # apt install -y docker-ce docker-ce-cli containerd.io # docker -v Docker version 20.10.5, build 55c4c88 docker composeのインストール # curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose # chmod +x /usr/local/bin/docker-compose # docker-compose -v docker-compose version 1.27.4, build 40524192 dockerをrootユーザーではなく一般ユーザーで操作できるようにします。 ubuntuユーザーをdockerグループに入れ、dockerサービスを再起動します。 ここまでがrootユーザでの作業です。 # usermod -g docker ubuntu # /bin/systemctl restart docker.service # exit $ exit symbol-bootstrapの導入・起動 ここからは一般ユーザ(ubuntuユーザ)で行います。 まず、データが保存されていくディレクトリの作成と、設定ファイルの作成を行います。 $ cd ~/ $ mkdir -p ~/symbol-bootstrap/target $ cd ~/symbol-bootstrap $ vi my-preset.yml ----- nodes: - friendlyName: Ninja Hi-performance Symbol-Node maxUnlockedAccounts: 64 beneficiaryAddress: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ----- 推奨スペックとはいえ、現状そこそこリッチな環境なので、「maxUnlockedAccounts を 10(default) -> 64」へ引き上げます。 手数料が送られる、beneficiaryAddressは自分のウォレットのアドレスを間違えないように入力します。 このウォレットアドレスの残高は0XYMでも問題ありません。 (ここが本記事の趣旨である0XYMでハーベスティングのキモです) 上記の設定で初期化します。 (下記コマンド実行時に、秘密鍵を扱うファイル操作用パスワードも設定します。) $ symbol-bootstrap config -p mainnet -a dual -c my-preset.yml 念のため、設定通りになっているかを確認します。 $ less target/nodes/node/server-config/resources/config-node.properties ----- [localnode] host = friendlyName = Ninja Hi-performance symbol node version = 1.0.0.0 roles = Peer,Api ----- 大丈夫なことが確認できたので、起動します。 $ symbol-bootstrap start --detached 起動確認 $ symbol-bootstrap healthCheck _ _ _ _ _ ___ _ _ _ __ ___ | |__ ___ | | | |__ ___ ___ | |_ ___ | |_ _ __ __ _ _ __ / __|| | | || '_ ` _ \ | '_ \ / _ \ | | _____ | '_ \ / _ \ / _ \ | __|/ __|| __|| '__|/ _` || '_ \ \__ \| |_| || | | | | || |_) || (_) || ||_____|| |_) || (_) || (_) || |_ \__ \| |_ | | | (_| || |_) | |___/ \__, ||_| |_| |_||_.__/ \___/ |_| |_.__/ \___/ \___/ \__||___/ \__||_| \__,_|| .__/ |___/ |_| 2021-04-12T13:44:42.140Z info Container db is running 2021-04-12T13:44:42.141Z info Container node is running 2021-04-12T13:44:42.146Z info Container broker is running 2021-04-12T13:44:42.146Z info Container rest-gateway is running 2021-04-12T13:44:42.149Z info Container node port 7900 -> 7900 is open 2021-04-12T13:44:42.149Z info Container rest-gateway port 3000 -> 3000 is open 2021-04-12T13:44:42.157Z info Testing http://localhost:3000/node/health 2021-04-12T13:44:42.173Z info Rest http://localhost:3000/node/health is up and running... 2021-04-12T13:44:42.174Z info Network is running! 初回はブロックチェーンの同期に時間が掛かりますが、しばらく経つとNode Listから自分のNodeが確認できるようになります。 (下記NodeはVoting設定も追加しています) あとは委譲とハーベスティングされるのをゆっくり待つのみです。 みなさまも良い収穫ライフを!!! 参考情報 さくらのVPSでNEM Symbol のテストネットノード構築 NEM Symbol テストノード構築で GoTo 大家 [Symbol]委任したいノードが見つからない時にやること
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSと1GbpsでインターネットVPN接続してデータ移行性能を計測してみた (NetApp FAS --> CVO)

背景と結論 自社でオンプレとAWS, GCP, Azureを接続してハイブリッド・マルチクラウド環境を構築し、利用しています。この接続にインターネットVPNを使っていますが、そこそこ安くて高速な回線だったのでクラウドへのデータ移行速度を計測しました。 転送元:   NetApp京橋オフィスに設置したNetApp FAS8040 (SSD 400GB x24本, ONTAP 9.1) 転送先:   AWS TokyoリージョンのEC2インスタンス上で動作しているCVO (Cloud Volumes ONTAP 9.9.0)   EC2インスタンスはm5.xlarge(4core 16GB)、EBSはgp2とsc1の2種類で試しました。 ネット回線:   Nuro アクセス スタンダードプラン(法人向けインターネット接続サービス)   下り2Gbps/上り1Gbpsで月額2万円程度。   (https://biz.nuro.jp/service/internet/standard/) ルーター:   Yahama RTX1210 コピーツール:   NetApp XCP v1.6.2 結論から書くと、上り(AWSへのアップロード)で約70~90MB/s(560-720Mbps)の性能が出ました。(2021年4月時点) 24時間で6TB以上のデータを転送できます。 netperfツールのように土管の太さを測るのではなく、実際にデータを転送して対向のストレージまで書き込んでいます。このスピードが出れば帯域保証型の高価な回線を使わなくてもほとんどのワークロードはカバーできるかと思います。 測定は24時間継続して行ったり時間帯別や曜日別の転送レートも数値化できれば良かったのですが、日常的に遅く感じることが無いことと、性能測定を目的とした長時間の回線利用はネット回線の約款に記載された禁止事項に当たる場合があるので短時間(10秒程度)で試しました。 今回は回線がデータ移行のボトルネックになりましたが、AWSと10Gbpsの閉域網で接続したテストも実施済みです。10GbpsではCVOが動作するEC2インスタンスがボトルネックになるので、インスタンスタイプやEBSボリューム構成を何種類か変更してテストしたので以下の記事もご参照ください。 ■10GbpsでAWSとDirect Connect接続し、NetApp FASからクラウド(CVO)へのデータ移行性能を測ってみた https://qiita.com/kan_itani/items/1898ddd3b05e8d0fae50 目次 オンプレミスのラボ環境 利用しているインターネット回線とルーター AWSとのVPN接続手順 テストパターンと結果 考察・雑談 関連情報 前置きが少し長いので、とりあえず結果だけ知りたい方は「4. テストパターンと結果」に飛んでご覧ください。 1. オンプレミスのラボ環境 検証内容に応じて、以下の3つのパターンを選択できます。 (1) 踏み台サーバ経由のラボ利用 Windowsの踏み台サーバにRDP通信のみ許可し、その踏み台サーバがグローバルIPとプライベートIPの両方に足を延ばす構成です。プライベートIPのセグメントにいる仮想サーバやストレージがインターネットへ通信する際は、ソースNATされて通信できますが、インターネットから直接アクセスできるのは踏み台サーバのみです。 (2) IPマスカレードによるポートフォワード グローバルIPアドレスのポート番号によって、通信先のプライベートIPを使い分ける方法です。 通信要件が変わると設定変更を入れるのに少し手間がかかるので、あまりこの構成は利用していません。 (3) インターネットVPNによる接続 お客様環境のラボや、AWS/Azure/GCPの環境とサイトtoサイトのVPNで接続する方法です。 (1)のWindows踏み台サーバ構成とこのVPNを同時に構成する事も可能です。 2. 利用しているインターネット回線とルーター インターネット回線 以下のNuro光回線を利用しています。 デフォルトで固定のグローバルIPが一つ付属しますが、固定IPアドレスオプションを申し込んでIPを8個増やしています。(ネットワークアドレスとブロードキャストで-2なので実質6個。) ネットワーク構成は以下の通りです。ルータ1と書かれているところに後述するYamaha RTX1210を配置し、DMZ上にVLANを複数切って異なる検証を同時に行えるようにしています。グローバルIPとVLANは1対1で割り当てており、グローバルIPへのアクセスはルータ側で制限しています。 ルーター機種 ルーターはYahama RTX1210を使っています。機能に不満や不足を感じることもなく、メーカーの技術サポートのレベルも高いのでお勧めします。また、インターネットVPNでスループット不足を感じることもありません。AWSとのVPN接続ではルーターのconfigをAWSのGUIからダウンロード出来たり、Azureの場合はYamahaホームページに設定手順や例が充実しているので困ることがありません。 上記の絵のように複数のVLANで環境を分離し、それぞれのVLANから異なるクラウド/オンプレ環境にVPN接続しています。また、以下のようなネットワーク構成にして各クラウドにVPNを張り、マルチクラウドで環境を使い分けることも可能です。  192.168.66.0/24 - オンプレミス  172.16.0.0/16 - AWS  172.17.0.0/16 - Azure  172.18.0.0/16 - GCP Yamahaルーターのスペック等は以下をご確認ください。 https://network.yamaha.com/products/routers/rtx1210/spec 3. AWSとのVPN接続手順 こちらは別記事で記載予定です。(2021年4月中を予定) Azureとの接続手順は以下に記載しています。 https://qiita.com/kan_itani/items/0cda4479b61d543c8dde 4. テストパターンと結果 テストパターン CVOのインスタンス: m5.xlarge固定 EBS:gp2 (SSD) / sc1 (Cold HDD)  ※ CVOに割り当てるデータ用EBSは、1アグリゲートにつき1つにしています。  ※ gp2は500GB、SC1は1TBの容量で作りました。 移行元のデータの種類によって性能差があるかどうかも比較したかったので、ファイルサイズも2パターンでテストしています。 平均ファイルサイズ:  小 (50KBytes/file)  大 (100MB以上/file) テスト結果 割り当てたEBSはバーストクレジットが十分残っている状態でテストしています。 ここでの「転送レート」は、CVOのsysstatのNet Inの値の中央値を記載しています。 No. インスタンス 回線速度 EBS構成(gp2 or sc1) ファイルサイズ 転送レート(bytes/s) CPU使用率(CVO) Disk Util 備考 (1) m5.xlarge 1Gbps gp2 500GB x1 小 80-100MB/s 35-55% 10%以下 回線ネック (10G回線を使った際はさらに性能が出たため。) (2) m5.xlarge 1Gbps gp2 500GB x1 大 70-90MB/s 30-40% 10%以下 同上 (3) m5.xlarge 1Gbps sc1 1TB x1 大 10-25MB/s 10-25% 0-7% sc1の作成直後は極端に遅かった (4) m5.xlarge 1Gbps sc1 1TB x1 大 90-100MB/s 33-49% 100% DISK utilが高い。 (5) m5.xlarge 1Gbps sc1 1TB x1 小 70-110MB/s 40-62% 100% EBS DISKネック (10G回線に変えてもおそらくこれが上限) 今回は短時間のテストでしたが、長時間実施してバーストクレジットが無くなるとそのEBSのサイズの本来のベース性能まで落ちます。 500GiBのgp2の場合:  バースト 3000iops (3000 x IOブロックサイズ=転送レート)  ベース  1500iops 1TiBのsc1の場合:  バースト 80 MiB/s  ベース  12 MiB/s 参考:https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-volume-types.html 以下にCVOのsysstat結果を記載しますが、CVOのDISK Writeの値を見るとgp2の場合はCPのタイミングで大量のWriteを短時間で処理できていますが、sc1の場合は多少のブレはありますが、均すと80,000KB/s程度の性能になっていることが確認できます。 (1) m5.xlarge(1Gbps, gp2 500GB x1, ファイルサイズ小) CVOのsysstat XCPデータ移行ツールの結果 (2) m5.xlarge(1Gbps, gp2 500GB x1, ファイルサイズ大) CVOのsysstat XCPデータ移行ツールの結果 (3) m5.xlarge(1Gbps, sc1 1TB x1, ファイルサイズ大) CVOのsysstat XCPデータ移行ツールの結果 (4) m5.xlarge(1Gbps, sc1 1TB x1, ファイルサイズ大) CVOのsysstat XCPデータ移行ツールの結果 (5) m5.xlarge(1Gbps, sc1 1TB x1, ファイルサイズ小) CVOのsysstat XCPデータ移行ツールの結果 5. 考察・雑談 1Gbpsの回線を使ってオンプレミスからのCloud Volumes ONTAPにデータ転送する場合はm5.xlargeのインスタンスで十分であることがわかりました。 今回の検証におけるボトルネックは回線とEBSストレージ(sc1)でした。CVOのCPUにはまだ余裕がありました。 EBSストレージにgp2で1TBのサイズを切り出せば、バーストクレジットを気にすることなく常に最大性能を出せますが、多少高くなります。 sc1 (Cold HDD)のベーススループットは非常に低いのですが、バーストクレジットを使い切らない範囲でのデータ転送であれば検討の余地があるかと思います。あるいはsc1を10TiB以上を切り出せば、ベーススループットで1Gbps(≒120MiB/s)を出せるようになります。 (但しブロックサイズが大きいwriteである必要があります。) 【Amazon EBSボリュームの種類】 (https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-volume-types.html) GB単価では最近はS3よりもsc1のほうが安くなっているので、ある程度大きなデータを扱うことがわかっていれば、sc1でも十分な性能を出すことができると思われます。(ランダムI/Oは弱いですが、バックアップ用途のI/Oには向いています) 今回はテストしませんでしたが、st1 (スループット最適化HDD)を3TiB以上切り出すことでバーストクレジットを気にすることなく1Gbpsの性能を出すことができるようになります。 【Amazon EBSボリュームの種類】 (https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-volume-types.html) 今回は回線が1Gbpsで細いためデータ用のEBSストレージを1つだけ切り出してテストしましたが、10GbpsのDirect Connect経由の検証では複数のEBSをRAID-0で構成したテストも実施しています。単一EBSボリュームとは異なった性能特性が見えてきたので、こちらの記事もご覧ください。(「6.関連記事」を参照) 月2万円の回線とYamahaルータがあれば、簡単にハイブリッド環境を作ることができます。 AWSから課金されるVPN接続料金は0.48ドル/時間で、8時間でも4ドル弱、24時間x7日間利用しても81ドル程度です。Azureと異なり、回線速度別の課金体系は見当たりません。 (https://aws.amazon.com/jp/vpn/pricing/) 今回はデータ移行を主目的として検証しましたが、本来のハイブリッドクラウド環境としての使い方もできますので、この検証環境に興味のある方はNetApp社かそのパートナー様までご連絡ください。環境をお貸し出しいたします。 「こんなテストも実施してみてほしい!」というご要望があれば、記事のコメントまでご連絡ください。 6. 関連記事 (1) 10GbpsでAWSとDirect Connect接続し、NetApp FASからクラウド(CVO)へのデータ移行性能を測ってみた https://qiita.com/kan_itani/items/1898ddd3b05e8d0fae50 (2) EBSのバースト性能について https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-volume-types.html (3) XCPを使ったオンプレ to オンプレデータ移行性能(rsyncとの比較) https://www.storage-channel.jp/blog/nfs-small-file.html (4) Nuroアクセススタンダード回線 https://biz.nuro.jp/service/internet/standard/ (5) AWSとのVPN接続料金 https://aws.amazon.com/jp/vpn/pricing/ (6) Yamahaルータ https://network.yamaha.com/products/routers/rtx1210/spec (7) AWSとのVPN接続手順 (今後追記予定) (8) AzureとのVPN接続手順 https://qiita.com/kan_itani/items/0cda4479b61d543c8dde (9) XCPデータ移行ツールについて (追記中)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSと1GbpsでインターネットVPN接続してデータ移行性能を計測してみた (NetApp FAS -> CVO)

背景と結論 自社でオンプレとAWS, GCP, Azureを接続してハイブリッド・マルチクラウド環境を構築し、利用しています。この接続にインターネットVPNを使っていますが、そこそこ安くて高速な回線だったのでクラウドへのデータ移行速度を計測しました。 転送元:   NetApp京橋オフィスに設置したNetApp FAS8040 (SSD 400GB x24本, ONTAP 9.1) 転送先:   AWS TokyoリージョンのEC2インスタンス上で動作しているCVO (Cloud Volumes ONTAP 9.9.0)   EC2インスタンスはm5.xlarge(4core 16GB)、EBSはgp2とsc1の2種類で試しました。 ネット回線:   Nuro アクセス スタンダードプラン(法人向けインターネット接続サービス)   下り2Gbps/上り1Gbpsで月額2万円程度。   (https://biz.nuro.jp/service/internet/standard/) ルーター:   Yahama RTX1210 コピーツール:   NetApp XCP v1.6.2 結論から書くと、上り(AWSへのアップロード)で約70~90MB/s(560-720Mbps)の性能が出ました。(2021年4月時点) 24時間で6TB以上のデータを転送できます。 netperfツールのように土管の太さを測るのではなく、実際にデータを転送して対向のストレージまで書き込んでいます。このスピードが出れば帯域保証型の高価な回線を使わなくてもほとんどのワークロードはカバーできるかと思います。 測定は24時間継続して行ったり時間帯別や曜日別の転送レートも数値化できれば良かったのですが、日常的に遅く感じることが無いことと、性能測定を目的とした長時間の回線利用はネット回線の約款に記載された禁止事項に当たる場合があるので短時間(10秒程度)で試しました。 今回は回線がデータ移行のボトルネックになりましたが、AWSと10Gbpsの閉域網で接続したテストも実施済みです。10GbpsではCVOが動作するEC2インスタンスがボトルネックになるので、インスタンスタイプやEBSボリューム構成を何種類か変更してテストしたので以下の記事もご参照ください。 ■10GbpsでAWSとDirect Connect接続し、NetApp FASからクラウド(CVO)へのデータ移行性能を測ってみた https://qiita.com/kan_itani/items/1898ddd3b05e8d0fae50 目次 オンプレミスのラボ環境 利用しているインターネット回線とルーター AWSとのVPN接続手順 テストパターンと結果 考察・雑談 関連情報 前置きが少し長いので、とりあえず結果だけ知りたい方は「4. テストパターンと結果」に飛んでご覧ください。 1. オンプレミスのラボ環境 検証内容に応じて、以下の3つのパターンを選択できます。 (1) 踏み台サーバ経由のラボ利用 Windowsの踏み台サーバにRDP通信のみ許可し、その踏み台サーバがグローバルIPとプライベートIPの両方に足を延ばす構成です。プライベートIPのセグメントにいる仮想サーバやストレージがインターネットへ通信する際は、ソースNATされて通信できますが、インターネットから直接アクセスできるのは踏み台サーバのみです。 (2) IPマスカレードによるポートフォワード グローバルIPアドレスのポート番号によって、通信先のプライベートIPを使い分ける方法です。 通信要件が変わると設定変更を入れるのに少し手間がかかるので、あまりこの構成は利用していません。 (3) インターネットVPNによる接続 お客様環境のラボや、AWS/Azure/GCPの環境とサイトtoサイトのVPNで接続する方法です。 (1)のWindows踏み台サーバ構成とこのVPNを同時に構成する事も可能です。 2. 利用しているインターネット回線とルーター インターネット回線 以下のNuro光回線を利用しています。 デフォルトで固定のグローバルIPが一つ付属しますが、固定IPアドレスオプションを申し込んでIPを8個増やしています。(ネットワークアドレスとブロードキャストで-2なので実質6個。) ネットワーク構成は以下の通りです。ルータ1と書かれているところに後述するYamaha RTX1210を配置し、DMZ上にVLANを複数切って異なる検証を同時に行えるようにしています。グローバルIPとVLANは1対1で割り当てており、グローバルIPへのアクセスはルータ側で制限しています。 ルーター機種 ルーターはYahama RTX1210を使っています。機能に不満や不足を感じることもなく、メーカーの技術サポートのレベルも高いのでお勧めします。また、インターネットVPNでスループット不足を感じることもありません。AWSとのVPN接続ではルーターのconfigをAWSのGUIからダウンロード出来たり、Azureの場合はYamahaホームページに設定手順や例が充実しているので困ることがありません。 上記の絵のように複数のVLANで環境を分離し、それぞれのVLANから異なるクラウド/オンプレ環境にVPN接続しています。また、以下のようなネットワーク構成にして各クラウドにVPNを張り、マルチクラウドで環境を使い分けることも可能です。  192.168.66.0/24 - オンプレミス  172.16.0.0/16 - AWS  172.17.0.0/16 - Azure  172.18.0.0/16 - GCP Yamahaルーターのスペック等は以下をご確認ください。 https://network.yamaha.com/products/routers/rtx1210/spec 3. AWSとのVPN接続手順 こちらは別記事で記載予定です。(2021年4月中を予定) Azureとの接続手順は以下に記載しています。 https://qiita.com/kan_itani/items/0cda4479b61d543c8dde 4. テストパターンと結果 テストパターン CVOのインスタンス: m5.xlarge固定 EBS:gp2 (SSD) / sc1 (Cold HDD)  ※ CVOに割り当てるデータ用EBSは、1アグリゲートにつき1つにしています。  ※ gp2は500GB、SC1は1TBの容量で作りました。 移行元のデータの種類によって性能差があるかどうかも比較したかったので、ファイルサイズも2パターンでテストしています。 平均ファイルサイズ:  小 (50KBytes/file)  大 (100MB以上/file) テスト結果 割り当てたEBSはバーストクレジットが十分残っている状態でテストしています。 ここでの「転送レート」は、CVOのsysstatのNet Inの値の中央値を記載しています。 No. インスタンス 回線速度 EBS構成(gp2 or sc1) ファイルサイズ 転送レート(bytes/s) CPU使用率(CVO) Disk Util 備考 (1) m5.xlarge 1Gbps gp2 500GB x1 小 80-100MB/s 35-55% 10%以下 回線ネック (10G回線を使った際はさらに性能が出たため。) (2) m5.xlarge 1Gbps gp2 500GB x1 大 70-90MB/s 30-40% 10%以下 同上 (3) m5.xlarge 1Gbps sc1 1TB x1 大 10-25MB/s 10-25% 0-7% sc1の作成直後は極端に遅かった (4) m5.xlarge 1Gbps sc1 1TB x1 大 90-100MB/s 33-49% 100% DISK utilが高い。 (5) m5.xlarge 1Gbps sc1 1TB x1 小 70-110MB/s 40-62% 100% EBS DISKネック (10G回線に変えてもおそらくこれが上限) 今回は短時間のテストでしたが、長時間実施してバーストクレジットが無くなるとそのEBSのサイズの本来のベース性能まで落ちます。 500GiBのgp2の場合:  バースト 3000iops (3000 x IOブロックサイズ=転送レート)  ベース  1500iops 1TiBのsc1の場合:  バースト 80 MiB/s  ベース  12 MiB/s 参考:https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-volume-types.html 以下にCVOのsysstat結果を記載しますが、CVOのDISK Writeの値を見るとgp2の場合はCPのタイミングで大量のWriteを短時間で処理できていますが、sc1の場合は多少のブレはありますが、均すと80,000KB/s程度の性能になっていることが確認できます。 (1) m5.xlarge(1Gbps, gp2 500GB x1, ファイルサイズ小) CVOのsysstat XCPデータ移行ツールの結果 (2) m5.xlarge(1Gbps, gp2 500GB x1, ファイルサイズ大) CVOのsysstat XCPデータ移行ツールの結果 (3) m5.xlarge(1Gbps, sc1 1TB x1, ファイルサイズ大) CVOのsysstat XCPデータ移行ツールの結果 (4) m5.xlarge(1Gbps, sc1 1TB x1, ファイルサイズ大) CVOのsysstat XCPデータ移行ツールの結果 (5) m5.xlarge(1Gbps, sc1 1TB x1, ファイルサイズ小) CVOのsysstat XCPデータ移行ツールの結果 5. 考察・雑談 1Gbpsの回線を使ってオンプレミスからのCloud Volumes ONTAPにデータ転送する場合はm5.xlargeのインスタンスで十分であることがわかりました。 今回の検証におけるボトルネックは回線とEBSストレージ(sc1)でした。CVOのCPUにはまだ余裕がありました。 EBSストレージにgp2で1TBのサイズを切り出せば、バーストクレジットを気にすることなく常に最大性能を出せますが、多少高くなります。 sc1 (Cold HDD)のベーススループットは非常に低いのですが、バーストクレジットを使い切らない範囲でのデータ転送であれば検討の余地があるかと思います。あるいはsc1を10TiB以上を切り出せば、ベーススループットで1Gbps(≒120MiB/s)を出せるようになります。 (但しブロックサイズが大きいwriteである必要があります。) 【Amazon EBSボリュームの種類】 (https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-volume-types.html) GB単価では最近はS3よりもsc1のほうが安くなっているので、ある程度大きなデータを扱うことがわかっていれば、sc1という選択肢もアリかと思います。(ランダムI/Oは弱いですが、バックアップ用途のI/Oには向いています) 今回はテストしませんでしたが、st1 (スループット最適化HDD)を3TiB以上切り出すことでバーストクレジットを気にすることなく1Gbpsの性能を出すことができるようになります。 【Amazon EBSボリュームの種類】 (https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-volume-types.html) 今回は回線が1Gbpsで細いためデータ用のEBSストレージを1つだけ切り出してテストしましたが、10GbpsのDirect Connect経由の検証では複数のEBSをRAID-0で構成したテストも実施しています。単一EBSボリュームとは異なった性能特性が見えてきたので、こちらの記事もご覧ください。(「6.関連記事」を参照) 月2万円の回線とYamahaルータがあれば、簡単にハイブリッド環境を作ることができます。 AWSから課金されるVPN接続料金は0.48ドル/時間で、8時間でも4ドル弱、24時間x7日間利用しても81ドル程度です。Azureと異なり、回線速度別の課金体系は見当たりません。 (https://aws.amazon.com/jp/vpn/pricing/) 今回はデータ移行を主目的として検証しましたが、本来のハイブリッドクラウド環境としての使い方もできますので、この検証環境に興味のある方はNetApp社かそのパートナー様までご連絡ください。環境をお貸し出しいたします。 「こんなテストも実施してみてほしい!」というご要望があれば、記事のコメントまでご連絡ください。 6. 関連記事 (1) 10GbpsでAWSとDirect Connect接続し、NetApp FASからクラウド(CVO)へのデータ移行性能を測ってみた https://qiita.com/kan_itani/items/1898ddd3b05e8d0fae50 (2) EBSのバースト性能について https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-volume-types.html (3) XCPを使ったオンプレ to オンプレデータ移行性能(rsyncとの比較) https://www.storage-channel.jp/blog/nfs-small-file.html (4) Nuroアクセススタンダード回線 https://biz.nuro.jp/service/internet/standard/ (5) AWSとのVPN接続料金 https://aws.amazon.com/jp/vpn/pricing/ (6) Yamahaルータ https://network.yamaha.com/products/routers/rtx1210/spec (7) AWSとのVPN接続手順 (今後追記予定) (8) AzureとのVPN接続手順 https://qiita.com/kan_itani/items/0cda4479b61d543c8dde (9) XCPデータ移行ツールについて (追記中)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[AWS CDK] L2 Constructから直接アクセスできないプロパティにアクセスする

はじめに AWS CDKのL2 Constructは、CloudFormationのリソースを抽象化した概念です。 複雑なインフラを簡単に定義できるため非常に便利な存在ですが、時に抽象化が原因でリソースを扱いづらくなる場合があります。 例えば、L2 Constructの props では設定できないCloudFormationの設定値が存在するような場合です。 本記事では、上記のような場合に、CDKの機能を用いてそれらの設定値を変更する方法を紹介します。 問題となるケース 例として、 aws-apigatewayv2.WebSocketApi というL2 Constructを使い、Lambda Authorizerが設定されたWebSocket APIを定義する事を考えます。 WebSocketApi Constructは、現状 props など直接的なインターフェースからAuthorizerを設定することができません。 Issue #13869 CloudFormationで設定できることは確認できています。 これを解決する最高の方法は、上記のIssueを解決するPull Requestを送る方法ですが、それほど時間もないので簡単な方法で一旦間に合わせたいです。 このような時、どうすれば良いでしょうか? 上記はかなり特有の状況ですが、CDKを使っていると似たような状況に出くわした方も多いのではと思います。 一般化すると、CDKのL2 Constructから直接設定できないがL1 Constructでは設定できる値をどう設定するか? という問題になります。 以下では、そのようなケースに普遍的に適用可能な方法を紹介します。 対処方法 CDKでは、findChild などのメソッドを使うことで、L2 Constructの内部で定義されているL1 Constructにアクセスできます。 下記に例を示します。 import * as cdk from "@aws-cdk/core"; import * as agw from "@aws-cdk/aws-apigatewayv2"; export class ExampleStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // WebSocketApiの定義(通常通り) const api = new agw.WebSocketApi(this, `WebSocket`); // Construct treeからCfnRoute (L1 Construct)を取得 const connectRoute = api.node.findChild("$connect-Route").node.defaultChild as agw.CfnRoute; // 取得したCfnRouteの設定値を編集 connectRoute.authorizationType = "CUSTOM"; connectRoute.authorizerId = createAuthorizer().ref; } // Authorizerを返す関数 (省略) createAuthorizer(): agw.CfnAuthorizer { ... } } これにより、本来 WebSocketApi からは設定できなかった $connect ルートの authorizationType や authorizerId を設定しています。 解説 上記のコードで何をやっているのかを解説します。 Constructツリー CDKでは、Constructはツリーを形成します。 Constructを定義する際は、下記のように 第1引数で scope を指定します。 この scope で指定したConstructを親となり、定義したConstructが子としてツリーに追加されていきます。 Constructクラスのコンストラクタ class Construct { constructor(scope: Construct, id: string); } CDKのアプリケーションで定義されるConstructは、全てこのツリーの中に入っています。 rootノードは App (よく new cdk.App() と書くやつです)で、そこから Stack があり、その中の Construct と続きます。 L2 ConstructはL1 Constructを束ねるツリーとみなせます。 このため、あるL2 Constructの子ノードを見れば、その中で定義されているL1 Constructが必ず存在するわけです。 ツリーのノードとしてのインターフェースは、Constructの node プロパティ で取得できます。 下記のコードでは、findChild 関数によりこのツリーを辿って所望のL1 Constructを取得しています。 上記コード例の抜粋 const connectRoute = api.node.findChild("$connect-Route").node.defaultChild as agw.CfnRoute; defaultChild プロパティは、あるConstructに最大で1つ存在する特別なノードです。 (実は id が Resource または Default のノードが defaultChild になります。id については次の節でまとめます。) L2 Constructに直に対応するL1 Constructが割り当てられる場合が多いようです。(WebSocketRoute → CfnRoute、 Bucket → CfnBucket など) defaultChild プロパティから取得できるという意味では特別ですが、その他の扱いは通常のノードと変わりません。 ツリー内ノードのID 上記で findChild 関数や defaultChild プロパティの意味を説明しました。 それでは、 findChild 関数の引数に渡している $connect-Route とは何でしょうか? これは、Constructを定義する際に渡している、第2引数 id です。 Constructクラスのコンストラクタ class Construct { constructor(scope: Construct, id: string); } このIDはツリーのあるノードの直接の子の間でユニークなため、あるConstructに対して id を指定して findChild すると、一意のConstructを取得することができます。 所望のConstructに設定されている id を知るためには、コードを読むのが正攻法です。 (例えば、上記WebSocketの例だと この辺りを読むとわかります。) より簡単な方法として、実際に生成されたテンプレートのMetadataを見るという方法もあります。 生成されたテンプレート websocketapiconnectRoute50EA91CF: Type: AWS::ApiGatewayV2::Route Properties: ... Metadata: aws:cdk:path: ExampleStack/WebSocket/$connect-Route/Resource この場合、下記のように対応します ExampleStack: Stackの id WebSocket: WebSocketApi Constructの id $connect-Route: WebSocketApi Constructの中の WebSocketRoute Constructの id Resource: WebSocketRoute Constructの中の CfnRoute Constructの id ツリーと実際のリソースの対応 先程でてきたコードを上の対応に沿って書き直すと、下記のようになります。 上記コード例の抜粋 const api = new agw.WebSocketApi(this, `WebSocket`); const connectRouteL2 = api.node.findChild("$connect-Route") as agw.WebSocketRoute; const connectRoute = connectRouteL2.node.defaultChild as agw.CfnRoute; defaultChild は id が Resource か Default のノードになることに注意してください。 取り出してきたchildの型は IConstruct になるため、 as で必要な型にキャストすると良いでしょう。 まとめ 上記の方法で、任意のL2 Constructから、所望のConstructを取り出すことができます。 これにより、L2 Constructの抽象性とL1 Constructの柔軟性、どちらのメリットも享受することが可能です。 抽象化を恐れることなくCDKを使っていきましょう!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HerokuからAWSに移行後のActionCableの設定方法

概要 本日、本番環境をHerokuからAWSに移行後、ブラウザ上で動作を確認したら、コメント機能の非同期通信で実装した所がうまく動作をしなかったので解決策をシェアしたいと思います。 起きていたこと Herokuでのデプロイ時とAWSでのデプロイ時でのproduction.rbの記述方法が異なる。 Herokuでの場合 production.rb ActionCable.server.config.disable_request_forgery_protection = true config.action_cable.url = "wss://【Herokuアプリ名】.herokuapp.com/cable" config.action_cable.allowed_request_origins = ['https://【Herokuアプリ名】.herokuapp.com', 'http://【Herokuアプリ名】.herokuapp.com' AWSでの場合 production.rb ActionCable.server.config.disable_request_forgery_protection = true config.action_cable.url = "ws://【Elastic IP】/cable" config.action_cable.allowed_request_origins = ['http://【Elastic IP】'] 上記に加えてAWSの場合必要な対応 /etc/nginx/conf.d/rails.conf upstream app_server { server unix:/var/www/アプリケーション名/shared/tmp/sockets/unicorn.sock; } server { listen 80; server_name Elastic IP; root /var/www/アプリケーション名/current/public; location ^~ /assets/ { gzip_static on; expires max; add_header Cache-Control public; root /var/www/アプリケーション名/current/public; } try_files $uri/index.html $uri @unicorn; location @unicorn { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://app_server; } # -------------------ここから------------------- # /cableのパスに対してwebsocketの仕組みを用いるための設定 location /cable { proxy_pass http://app_server/cable; proxy_http_version 1.1; proxy_set_header Upgrade websocket; proxy_set_header Connection Upgrade; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # -------------------ここまでを追記------------------- error_page 500 502 503 504 /500.html; まとめ 今回の件ではAWSの場合だとWebサーバーとしてNginxを用意していたので、ActionCableを用いる場合、サーバーサイドへのリクエストを受け取る役目のあるWebサーバーにて、websocketの仕組みを用いるための設定をする必要があることを認識することが出来ました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CloudShellでTerraformを実行してみる

はじめに Cloudshellで使うメリットは、、、 個人の環境の差を気にしなくてよい! CLI等のインストールがいらない! です。 なので、とりあえずterraform触ってみたいとか、 社内勉強会とかにはいいかなと思います! 少しでも参考になる箇所があれば幸いです。 Terraformってなに? Terraformは、何百ものクラウドサービスを管理するための一貫したCLIワークフローを提供するコードソフトウェアツールとしてのオープンソースインフラストラクチャです。 ほう… ちなみによくわからん… 簡単に言えば、インフラ環境をコードで管理する(IaC)を実現するサービス! とか言ってもわからんもんはわからん… なんでもそうだけど、触ってみるのが早いので触ってニュアンス覚えたろ! 無料だし! (筆者はAWSしか触ったことないので、AWSで…) ちなみに触るだけならCloudShellがおすすめです! https://www.terraform.io/ 今回作る構築 今回は、ネットワークの基礎的なところを作成していきたいと思います。 CloudShellからTerraformを使ってみる AWS CloudShellは、ブラウザベースのシェルで、AWSリソースの安全な管理、探索、操作を簡単に行うことができます。CloudShellは、お客様のコンソール認証情報で事前に認証されています。一般的な開発ツールや運用ツールがあらかじめインストールされているので、ローカルでのインストールや設定は必要ありません。CloudShellを使えば、AWSコマンドラインインターフェイス(AWS CLI)を使ってスクリプトを素早く実行したり、AWS SDKを使ってAWSサービスAPIを実験したり、その他様々なツールを使って生産性を高めることができます。CloudShellは、ブラウザからすぐに使用でき、追加費用もかかりません。 https://aws.amazon.com/jp/cloudshell/?nc1=h_ls 要するに、便利なツールいっぱい詰んでるTerminalですね。 裏はコンテナが動いてるみたいです。 試す分にはこいつがめちゃくちゃ便利です。 では、さっそくTerraformをインストールしましょう! CloudShellはAmazon Linuxなので、このリンクのLinuxタブ→Amazon Linuxタブから手順通りに進めればインストールが可能です。 まずはAWSのマネジメントコンソールから、CloudShellを開きます。 この時、リージョンが東京であることを確認してください。 暫くたつとCloudShellが使用可能な状態になりますので、以下コードを実行します。 sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo sudo yum -y install terraform さて、インストールはこれで完了です。 ここからパスを通します。 sudo mkdir /home/app sudo mv /bin/terraform /home/app/ export PATH="$PATH:/home/app/" これでパスが通りました。 terraform versionなどを打って正常に反応が来るか確認しましょう! $ terraform version Terraform v0.14.9 こんなん帰ってきたらおk! 社内ハンズオンの場合はここで、リポジトリ用意しておいてクローンしましょう! 今回は一つずつ作成してみます! 事前準備 terraform.stateファイルを格納する場所が必要です。 1つS3バケットを作成しておきます! aws s3 mb s3://terraform-handson-${ランダムな番号} Terraformで使用するファイル 構成 今回はなーんにも考えずに全部一階層にぶち込みます! terraform_handson      ├ provider.tf ├ backend.tf ├ local.tf ├ variable.tf ├ output.tf ├ vpc.tf ├ subnet.tf ├ igw.tf ├ ngw.tf ├ rtb.tf ├ eip.tf とりあえずterraform_handsonフォルダを作成して移動します。 mkdir terraform_handson && cd $_ provider.tf Terraform構成では、Terraformがそれらをインストールして使用できるように、必要なプロバイダーを宣言する必要があります。さらに、一部のプロバイダーは、使用する前に構成(エンドポイントURLやクラウドリージョンなど)を必要とします。 ファイル作成 vi provider.tf 今回はAWSを使用するので、AWS Providerを宣言します。 ついでに、デフォルトは東京リージョンなので、オレゴンリージョンもエイリアスを付けて宣言ておきます! ファイルの中身は以下の通りです。 provider "aws" { version = "= 3.14.1" } provider "aws" { version = "= 3.14.1" alias = "oregon" region = "us-west-2" } backend.tf provider.tfと同じようにファイル作成してください。(以下省略) 各Terraform構成は、操作が実行される場所と方法、状態 スナップショットが保存される場所などを正確に定義するバックエンドを指定できます。ほとんどの重要なTerraform構成は、複数のユーザーが同じインフラストラクチャで作業できるようにリモートバックエンドを構成します。 terraform.stateファイルを置く場所を指定します! S3バケットに格納するのが一般的です。 terraform { backend "s3" { bucket = "terraform-handson-${ランダムな番号}" key = "handson/terraform" region = "ap-northeast-1" encrypt = true } } local.tf ローカル値は、構成内で同じ値または式を複数回繰り返さないようにするのに役立ちますが、使いすぎると、使用される実際の値を非表示にすることで、将来のメンテナが構成を読みにくくする可能性があります。 ローカル値は、単一の値または結果が多くの場所で使用され、その値が将来変更される可能性がある状況で、適度にのみ使用してください。中央の場所で値を簡単に変更できることは、ローカル値の主な利点です。 今回はローカル値にサブネットを指定します。 ルートテーブルの関連付けをする際に、繰り返し処理で管理できるので! locals { pri_subnet_id_tokyo = { pri-subnet-first-handson-tokyo = aws_subnet.pri-subnet-first-handson-tokyo.id, pri-subnet-second-handson-tokyo = aws_subnet.pri-subnet-second-handson-tokyo.id } } locals { pri_subnet_id_oregon = { pri-subnet-first-handson-oregon = aws_subnet.pri-subnet-first-handson-oregon.id, pri-subnet-second-handson-oregon = aws_subnet.pri-subnet-second-handson-oregon.id } } variable.tf 入力変数はTerraformモジュールのパラメーターとして機能し、モジュール自体のソースコードを変更せずにモジュールの側面をカスタマイズできるようにし、異なる構成間でモジュールを共有できるようにします。 構成のルートモジュールで変数を宣言する場合、CLIオプションと環境変数を使用してそれらの値を設定できます。子モジュールでそれらを宣言する場合、呼び出し元のモジュールはmoduleブロック内の値を渡す必要があります。 モジュールを使用する際に大活躍のvariableさんですね。 今回は試しにリソース名に変数でも入れてみます。 variable "number" {} output.tf 出力値は、terraform apply時に出力したい場合や、他のアカウントでその値を参照したい場合に必要です。 (モジュールのリソースを上階層のアカウントで参照した場合も必要) 今回は特にそういった用途はないですが、何となくEIPでも見ようかなと… output "eip-address-tokyo" { value = aws_eip.eip-handson-tokyo.public_ip } output "eip-address-oregon" { value = aws_eip.eip-handson-oregon.public_ip } Resource ここからは各リソースファイルをサラッとご紹介 vpc.tf resource "aws_vpc" "vpc-handson-tokyo" { cidr_block = "10.102.0.0/17" tags = { Name = "vpc-handson-tokyo-${var.number}" } } resource "aws_vpc" "vpc-handson-oregon" { provider = aws.oregon cidr_block = "10.103.0.0/17" tags = { Name = "vpc-handson-oregon-${var.number}" } } 今回のようにString型の文字列の中に変数を入れる場合は${var.~~}という書き方が必要です。 例えば、変数が丸っと名前の場合は Name = var.number だけで出来ます! Name = ${var.number} としても通りますが、そのやり方古いよ?と怒られちゃいます。 subnet.tf resource "aws_subnet" "pub-subnet-handson-tokyo" { vpc_id = aws_vpc.vpc-handson-tokyo.id availability_zone = "ap-northeast-1a" cidr_block = "10.102.0.0/24" tags = { Name = "pub-subnet-handson-tokyo-${var.number}" } } resource "aws_subnet" "pri-subnet-first-handson-tokyo" { vpc_id = aws_vpc.vpc-handson-tokyo.id availability_zone = "ap-northeast-1a" cidr_block = "10.102.1.0/24" tags = { Name = "pri-subnet-first-handson-tokyo-${var.number}" } } resource "aws_subnet" "pri-subnet-second-handson-tokyo" { vpc_id = aws_vpc.vpc-handson-tokyo.id availability_zone = "ap-northeast-1c" cidr_block = "10.102.2.0/24" tags = { Name = "pri-subnet-second-handson-tokyo-${var.number}" } } resource "aws_subnet" "pub-subnet-handson-oregon" { provider = aws.oregon vpc_id = aws_vpc.vpc-handson-oregon.id availability_zone = "us-west-2a" cidr_block = "10.103.0.0/24" tags = { Name = "pub-subnet-handson-oregon-${var.number}" } } resource "aws_subnet" "pri-subnet-first-handson-oregon" { provider = aws.oregon vpc_id = aws_vpc.vpc-handson-oregon.id availability_zone = "us-west-2a" cidr_block = "10.103.1.0/24" tags = { Name = "pri-subnet-first-handson-oregon-${var.number}" } } resource "aws_subnet" "pri-subnet-second-handson-oregon" { provider = aws.oregon vpc_id = aws_vpc.vpc-handson-oregon.id availability_zone = "us-west-2b" cidr_block = "10.103.2.0/24" tags = { Name = "pri-subnet-second-handson-oregon-${var.number}" } } eip.tf resource "aws_eip" "eip-handson-tokyo" { vpc = true } resource "aws_eip" "eip-handson-oregon" { provider = aws.oregon vpc = true } igw.tf resource "aws_internet_gateway" "igw-handson-tokyo" { vpc_id = aws_vpc.vpc-handson-tokyo.id tags = { Name = "igw-handson-tokyo-${var.number}" } } resource "aws_internet_gateway" "igw-handson-oregon" { provider = aws.oregon vpc_id = aws_vpc.vpc-handson-oregon.id tags = { Name = "igw-handson-oregon-${var.number}" } } ngw.tf resource "aws_nat_gateway" "ngw-handson-tokyo" { allocation_id = aws_eip.eip-handson-tokyo.id subnet_id = aws_subnet.pub-subnet-handson-tokyo.id tags = { Name = "ngw-handson-tokyo-${var.number}" } } resource "aws_nat_gateway" "ngw-handson-oregon" { provider = aws.oregon allocation_id = aws_eip.eip-handson-oregon.id subnet_id = aws_subnet.pub-subnet-handson-oregon.id tags = { Name = "ngw-handson-oregon-${var.number}" } } rtb.tf resource "aws_route_table" "pub-rtb-handson-tokyo" { vpc_id = aws_vpc.vpc-handson-tokyo.id tags = { Name = "pub-rtb-handson-tokyo-${var.number}" } } resource "aws_route_table" "pri-rtb-handson-tokyo" { vpc_id = aws_vpc.vpc-handson-tokyo.id tags = { Name = "pri-rtb-handson-tokyo-${var.number}" } } resource "aws_route_table" "pub-rtb-handson-oregon" { provider = aws.oregon vpc_id = aws_vpc.vpc-handson-oregon.id tags = { Name = "pub-rtb-handson-oregon-${var.number}" } } resource "aws_route_table" "pri-rtb-handson-oregon" { provider = aws.oregon vpc_id = aws_vpc.vpc-handson-oregon.id tags = { Name = "pri-rtb-handson-oregon-${var.number}" } } resource "aws_route" "pub-route-handson-tokyo" { route_table_id = aws_route_table.pub-rtb-handson-tokyo.id destination_cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.igw-handson-tokyo.id depends_on = [aws_route_table.pub-rtb-handson-tokyo] } resource "aws_route" "pri-route-handson-tokyo" { route_table_id = aws_route_table.pri-rtb-handson-tokyo.id destination_cidr_block = "0.0.0.0/0" gateway_id = aws_nat_gateway.ngw-handson-tokyo.id depends_on = [aws_route_table.pri-rtb-handson-tokyo] } resource "aws_route" "pub-route-handson-oregon" { provider = aws.oregon route_table_id = aws_route_table.pub-rtb-handson-oregon.id destination_cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.igw-handson-oregon.id depends_on = [aws_route_table.pub-rtb-handson-oregon] } resource "aws_route" "pri-route-handson-oregon" { provider = aws.oregon route_table_id = aws_route_table.pri-rtb-handson-oregon.id destination_cidr_block = "0.0.0.0/0" gateway_id = aws_nat_gateway.ngw-handson-oregon.id depends_on = [aws_route_table.pri-rtb-handson-oregon] } resource "aws_route_table_association" "pub-rtb-assoc-handson-tokyo" { route_table_id = aws_route_table.pub-rtb-handson-tokyo.id subnet_id = aws_subnet.pub-subnet-handson-tokyo.id } resource "aws_route_table_association" "pri-rtb-assoc-handson-tokyo" { for_each = local.pri_subnet_id_tokyo route_table_id = aws_route_table.pri-rtb-handson-tokyo.id subnet_id = each.value } resource "aws_route_table_association" "pub-rtb-assoc-handson-oregon" { provider = aws.oregon route_table_id = aws_route_table.pub-rtb-handson-oregon.id subnet_id = aws_subnet.pub-subnet-handson-oregon.id } resource "aws_route_table_association" "pri-rtb-assoc-handson-oregon" { provider = aws.oregon for_each = local.pri_subnet_id_oregon route_table_id = aws_route_table.pri-rtb-handson-oregon.id subnet_id = each.value } ここでfor_each急に出てきてなんなん? と思われたかもしれません。 サブネットって実際はもっと大量にあると思います。 そいつらをいちいちルートテーブルに関連付けるだけで新しいリソースセクション作成してるとコードが肥大化してしまうので、for_eachを使って繰り返し処理をしています。 for_each = local.pri_subnet_id_oregonでmap型を代入しておきます。 例えば for_each = { a = apple b = banana } のとき、 each.key = [a, b] each.value = [apple, banana] のようなイメージで繰り返されていきます。 構築してみる さてここまで長かったですね。 ちなみにCloudshellは接続が一度切れるとHomeより上の階層がリセットされてしまうので、パスを通しなおす必要があります。 実践向きではないですね… 飛ばしている方がほとんどだと信じています。 それでは、まずはinitから! terraform init 準備が整ったところで、terraform plan!! variableに指定していた値を入力しろ!と言われました 適当に入力してEnter押します! いろいろ表示されますが、 Plan: 28 to add, 0 to change, 0 to destroy. になっていればとりあえずオッケー! terraform applyしましょう! ほんとにApplyしちゃうよ? ってファイナルアンサー?が来るので yesと入力し、Enter!! リソースの作成が開始されます! nat_gatewayがちょっと時間食いますね… Applyが成功して、outputに指定していたEIPのアドレスが出力されました! 実際の中身をマネコンで確認してみてください! ではterraform destroyします! また聞かれるので、答えてあげてください。 そしてまたも、みのさん、、、ファイナルアンサー??? yes!!!! 削除が始まりました! 削除できました!! 最後にS3の削除をお忘れなきよう… aws s3 rb s3://terraform-handson-${ランダムな番号} --force まとめ 今回は、CloudShellでTerraformを実行しました。 主なユースケースは社内勉強会とかになるかなと思います。 個人の環境の違いを考慮しなくてよくなるので、非常に楽ですね! Cloud9と違って無料ですし… それではまた!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WinodwsServerのディスクの拡張

はじめに AWSやAzureでは、それぞれの管理画面でディスクを拡張しても、サーバにすぐに認識されるわけではなく サーバでディスクを認識させなければならない。 今回は、サーバのOSバージョンごとに拡張の方法を説明する。 Windows2016 コントロールパネルからコンピュータの管理 画面を開く ディスクの管理を選んで、右クリックをして、最新の情報に更新を押す。 ディスクが表示される。拡張した50GBは、まだ利用できない。 ボリュームの拡張を選ぶ ディスクが拡張される。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Terraform】 countからfor_eachへ書き換えたらスプラット演算子の動きが変わった

いままでcountで記述していたものをfor_eachに直してみたところスプラット演算子の動きが変わったのでメモ 状況 いままではVPCのサブネットリソースをcountで複数作ってそれをoutputで他のモジュールに渡して利用しておりました resource "aws_subnet" "private_data" { count = length(var.azs) vpc_id = aws_vpc.vpc.id cidr_block = cidrsubnet(aws_vpc.vpc.cidr_block, 8, 11 + count.index) availability_zone = element(var.azs, count.index) map_public_ip_on_launch = false } output "data_private_subnets" { value = aws_subnet.private_data } 他のモジュールで使うときはこんな感じで使ってた resource "aws_db_subnet_group" "db" { name = "${var.name}-${terraform.workspace}-db-subnet" description = "Database Subnet Group for ${var.name}-${terraform.workspace}" subnet_ids = var.data_private_subnets[*].id # この部分 } そんでもって、for_eachを使って書き直したのがこちら resource "aws_subnet" "private_db" { for_each = var.azs cidr_block = cidrsubnet(aws_vpc.vpc.cidr_block, 8, index(values(var.azs), each.value) + 11) availability_zone = each.value vpc_id = aws_vpc.vpc.id map_public_ip_on_launch = false } すると以下のようなエラーが出るようになった Error: Unsupported attribute on modules/aws/database/subnet_group.tf line 4, in resource "aws_db_subnet_group" "db": 4: subnet_ids = var.data_private_subnets[*].id This object does not have an attribute named "id". Issue とりあえずIssueを漁ってみたら以下が見つかった https://github.com/hashicorp/terraform/issues/22476 https://github.com/hashicorp/terraform/issues/23245 Issueを読んでみると以下のように修正すれば大丈夫っぽいことがわかった The short answer is that if you were to modify your code to values(aws_route53_record.record)[*].fqdn it will work as you're expecting it to. 修正 Issueに書いてあるとおり、aws_db_subnet_groupのリソース作成部分を以下のように修正したら問題なく動くようになった resource "aws_db_subnet_group" "db" { name = "${var.name}-${terraform.workspace}-db-subnet" description = "Database Subnet Group for ${var.name}-${terraform.workspace}" subnet_ids = values(var.private_subnets_db)[*].id # この部分 } おわりに for_each便利だけど思わぬ落とし穴?にハマってしまいました
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSサーバーにおけるデプロイの方法(AWS EC2、Unicorn、Nginx)

今回の記事ではデプロイの概要と反省をしていきます。 AWSを用いたデプロイまでの流れ EC2の初期設定(IPアドレスの取得)      ↓ データベースの設定(mariaDB)      ↓ EC2のRailsを起動(Unicorn)      ↓ Webサーバーの設定(Nginx)      ↓ 自動デプロイの設定(Capistrano) 大変だったこと 初期設定で生成したインスタンスを再起動すると、起動していたDB、サーバーが停止してしまっています。そのため、IPアドレスをブラウザに貼っても、画面遷移する事ができずエラーになってしまいます。そのため、EC2からCapistranoまでは一蓮托生であるということを忘れないようにする。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Databricksクイックスタートガイド

初めてDatabricksを利用される方向けに、入門者向けの内容をマニュアルからピックアップして翻訳したものになります。全文はDatabricks documentation | Databricks on AWSから参照できます。 注意1 こちらは翻訳時点の内容となります。可能な限りアップデートしますが、最新の状態でない箇所がある可能性をご了承ください。 注意2 AWSでの利用を想定したものとなっています。 お願い 誤記、翻訳要望等ございましたら、コメントでご指摘いただけると幸いです。 Databricksのコンセプト Databricksとは何かを説明します。 データブリックスのレイクハウスプラットフォーム Databricksワークスペースのコンセプト - Qiita Databricks環境セットアップ(管理者向け) Databricks環境セットアップ手順をご説明します。 注意 AWSでフリートライアルを実施する際には、Databricksからのサポートを受けることをお勧めします。Databricks担当までお問い合わせください。 Databricksフリートライアルへのサインアップ - Qiita 管理者向けDatabricksスタートガイド - Qiita Databricksにおけるユーザー管理 - Qiita ユーザー向けスタートガイド データサイエンティスト、データエンジニア、データアナリストが利用するDatabricksワークスペースと利用方法をご説明します。 ユーザー向けDatabricksスタートガイド - Qiita Databricksクラスター Databricksでデータ分析やデータ加工を行う際に必ず必要になるクラスターについてご説明します。 Databricksにおけるクラスター作成 - Qiita Databricksにおけるクラスター管理 - Qiita Databricksノートブック Databricksの多くの作業を実施することになるノートブックの使い方をご説明します。 Databricksノートブックを管理する - Qiita Databricksノートブックを使う - Qiita Databricksにおけるデータの可視化 - Qiita データエンジニアリングに関わる作業 Databricks上で、どのようにデータを読み込み、加工するのかを、データエンジニアリングにおける重要なコンポーネントとなるDelta Lakeを含めてご説明します。 Databricksにおけるデータベースおよびテーブル - Qiita Databricksにおけるファイルシステム - Qiita Databricksにおけるデータのインポート、読み込み、変更 - Qiita Delta Lakeクイックスタートガイド - Qiita 機械学習に関わる作業 MLflowを用いて、どのように機械学習モデルを管理するのかをご説明します。 PythonによるDatabricks MLflowクイックスタートガイド - Qiita サポート Databricksのサポート - Qiita BIツールの活用 Coming soon Sparkによる分散処理 Coming soon 監査ログの設定 Coming soon Databricks 無料トライアル Databricks 無料トライアル
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon RDS のクラスターを Slack から起動/停止する

はじめに Slackを使ってAmazon RDSを上げ下げできるようにしました。使わない時間帯はちゃんと落としてから帰りましょう。 やること 以下のことを行います。時間配分は作業目安です。 AWS に Chatbot を設定(5分) SlackにAWS Chatbotアプリを追加(5分) Lambdaを書く(30分) IAMを追加(5分) Slackワークフロービルダーを設定(10分) 構成図 SlackにAWS Chatbotアプリを追加してSlackワークフロービルダー経由でLambdaを叩きます。 Lambdaの動きは以下のようにしています。 AWS に Chatbot を設定(5分) AWSのコンソールにログインし、Chatbotと検索してください。クライアントにSlackを選択し、画面の指示に従って設定を完了させてください。 SlackにAWS Chatbotアプリを追加(5分) SlackにAWS Chatbotアプリを追加してください。 Lambdaを書く(30分) Lambdaを書きましょう。コードはPythonです。そのままコピペして使うと良いでしょう。 import boto3 RDS = boto3.client('rds') # Type in {"clusters": ["<cluster-1>", "<clu-2>"], "action": "stop"} def lambda_handler(event, context): # 入力チェック try: clusters = event.get('clusters') action = event.get('action') except Exception as e: invalid_msg = "Exception! Failed with: {0}".format(e) print(invalid_msg) return invalid_msg if (not (action == "stop" or action == "start")) or (not isinstance(clusters, list)): invalid_msg = "clusters must be a list of strings, action must be \"Start\" or \"Stop\"" print(invalid_msg) return invalid_msg # データベースをフィルタリングし、入力値のクラスターのみを取得 dbs = set([]) rds_instances = RDS.describe_db_instances() for rds_instance in rds_instances['DBInstances']: for instance in clusters: if instance in rds_instance['DBClusterIdentifier']: dbs.add(rds_instance['DBClusterIdentifier']) # アクションを実行 for db in dbs: try: if action == "start": print("Start {0} cluster.".format(db)) response = RDS.start_db_cluster(DBClusterIdentifier=db) else: print("Stop {0} cluster.".format(db)) response = RDS.stop_db_cluster(DBClusterIdentifier=db) except Exception as e: err_msg = "Exception: {0}".format(e) print(err_msg) return err_msg return { 'status': "Success!", 'body': "{0}".format(dbs), } IAMを追加(5分) Lambdaの実行ロールにRDSを再起動できるように追加でポリシーをアタッチします。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "rds:DescribeDBInstances", "rds:StartDBCluster", "rds:StopDBCluster" ], "Resource": "*" } ] } Slackワークフロービルダーを設定(10分) 以下のコマンドをSlackワークフロービルダーに設定してみましょう。ワークフロービルダーが使えない環境の場合はAWS Chatbotアプリを追加したChannel内で直接Slackに打ち込んでみよう。 DBクラスター起動 SlackからLambda経由でRDSを起動します。clustersに起動したいクラスター名、actionにstartを指定します。 @aws lambda invoke --payload {"clusters": ["<Cluster-1>","<Cluster-2>"], "action":"start"} --function-name <作成したLambda関数名> --region ap-northeast-1 DBクラスター停止 SlackからLambda経由でRDSを停止します。clustersに停止したいクラスター名、actionにstopを指定します。 @aws lambda invoke --payload {"clusters": ["<Cluster-1>","<Cluster-2>"], "action":"stop"} --function-name <作成したLambda関数名> --region ap-northeast-1 おまけ:DBクラスターのステータス確認 ステータス確認はLambdaを経由せずとも直接取得できます。 @aws rds describe-db-instances --query DBInstances[].[DBInstanceIdentifier,DBInstanceStatus] --region ap-northeast-1 さいごに 今回はSlackをトリガーにRDSの上げ下げを紹介しましたが、CloudWatch EventsとLambdaを連携させれば決まった時間に自動で上げ下げもできるようになります。こちらもセットで設定しておけば、うっかり起動しっぱなしなんてことはなくなるでしょう。またクラスターではなくインスタンスを上げ下げしたいんじゃ、という需要もあるかと思います。その場合は、適宜クラスターのところをインスタンスに書き換えてみてください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SaaS系スタートアップのリアルなAWSアーキテクチャ設計

※Zennに統合しました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS認定試験】SAP-C01落ちた話

はじめに 先日、SAP-C01(AWS認定ソリューションアーキテクトアソシエイト)に落ちたので、失敗を次回に活かすために自責の念を込めて体験記を残します。 これまでのAWS認定受験遍歴 2020/08 AWS認定クラウドプラクティショナー(CLF)取得 2020/11 AWS認定ソリューションアーキテクトアソシエイト(SAA)取得 2021/01 AWS認定デベロッパーアソシエイト(DVA)取得 2021/02 AWS認定SysOpsアドミニストレータアソシエイト(SOA)取得 2021/03 AWS認定ソリューションアーキテクトプロフェッショナル(SAP)取得できず SAPとは AWS認定試験の中で最難関と呼び声高い試験です。 2年間のAWS実務経験レベルの知識を要求されます。 AWS 認定ソリューションアーキテクト – プロフェッショナル試験は、AWS におけるシステムの管理および運用に関する 2 年以上の実務経験を持つソリューションアーキテクト担当者を対象としています。 AWS 認定ソリューションアーキテクト – プロフェッショナル- https://aws.amazon.com/jp/certification/certified-solutions-architect-professional/ 試験対策 Udemyで問題を解く。 わからないサービスのBlackBeltを読み、理解を深める。 繰り返す。 というアソシエイトと同様に、物量で押し通すスタイルでやってました。 これがアダになるとは。。。 活用した問題集: AWS 認定ソリューションアーキテクト プロフェッショナル模擬試験問題集(全5回分375問) 試験対策の反省点 模擬問題を数日に渡って解いていた まず、SAPの特性なのですが、問題文・選択肢がひたすらに長いです。 業後に勉強を始めるわけですが、1問1問に対するパワーが多く集中力がなかなか続きません。 また、Udemyはすべての問題(75問)が解き終わらないと答えの閲覧が行えません。 そのため、「数日に分けて問題集を解く」→「すべて解き終わったら回答を確認」ということを行っていたので知識定着率が低かったです。 (Udemyの問題の質は非常に良いのです。Udemyが悪いのではなく、集中できなかった自分が悪い。。。) AWS Organizations,AWS Direct Connect など普段扱わないようなサービスの理解不足 AWS OrganizationsはAWSアカウント周りを管理するためのツールです。これらのツールは概念的には理解できていたのですが、実運用を想定した際のベストプラクティスがわからなかったです。 AWS Direct Connectはオンプレ環境とAWS環境は専用線で繋ぐことができるサービスです。こちらも概念的には理解していたのですが、「じゃあ複数DCからVPCに繋ぐにはどういう設定したらいいの?」といった具体的なことまでは押さえていませんでした。 試験対策を振り返るとこのあたりの理解が甘かったので、ハンズオンや解説があるならば確認し、しっかりと理解しておくべきだと思いました。 試験 ピアソンVUEを活用し、在宅受験を行いました。 そういえば、運転免許証をスマホで撮影する際に前はインカムしか使えなかったのが、裏のカメラも使えるようになっていました。 定期的に問題点を修正してくれるのはうれしいですね!! おかげで撮るのがめちゃくちゃ楽になってました。 試験中の反省点 フラグの活用ができていなかった SAPの試験時間は3時間,75問と長丁場になります。そのため、1問1問に時間をかけすぎないことを意識して取り組みました。 しかし、すべて解き終わった後にすべてを見直そうとしてしまい、時間をかけるべき問題に時間がかけられませんでした。 そのため、見直すべき問題には適切にフラグを付けるべきだと感じました。 選択肢の違いの見極めに時間がかかった SAPは長文の問題に似通った選択肢があります。そのため、それぞれの選択肢の違いを見極める必要があります。パッと見て同じなので、何度も読んで理解する必要があるのですが、これは模擬問題などで経験を積み、最短時間で答えを導き出せるように訓練をしたほうが良いと感じました。 まとめ 勉強方法は「まとまった時間で模擬問題を解きまくる」もしくは「一問一答を隙間時間に解きまくる」が効率良いのかなと思います。 そして、いまいち理解できていないサービスは適宜メモを取り、ハンズオンを行う、BlackBeltを読むなどで知識吸収を図りましょう。 試験中は選択肢の違いを意識し、時間がかかりそうな問題や自信がない問題にはフラグつけ、見直し時に多く時間をかけられるようにしましょう。 次回こそは合格したい!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CloudWatch Eventsでメール通知をしてみる

cloudwatch eventsとは? イベントソースを定義することでリソースの変更をリアルタイムに取得し、 AWSのアクションをトリガーすることができます。 とりあえずAPIで取ってきたものに対してなにかアクションを行うようなことをします。 構成図 今回の構成図は以下で、シンプルです。 EC2インスタンスが停止されるとSNSでメールが来る仕組みを作りたいと思います。 作成 目次 EC2インスタンスの作成 SNSトピックの作成 cloudwatch eventsの作成 アラートの発火 EC2インスタンスの作成 今回は省略します 作成方法は こちら をごらんください SNSトピックの作成 移動 ホーム > SNS > トピック から、トピックの作成を行います。 トピックの作成 トピックの作成を行います。 タイプはベストエフォート型のスタンダードで、 名前・表示名ともに cloudwatch-ec2-notification とします。 それ以外は特に変更せずに作成を行います。 トピックの作成が完了 トピックの作成が完了しました。 サブスクリプションの作成 サブスクリプションの作成を行います。 作成方法は↑の画面の下の方に サブスクリプションの作成 のボタンがあるのでそこから進みます。 サブスクリプションの詳細を設定 サブスクリプションの詳細を決めます。 こちらは、通知先を記載する箇所になります。 プロトコルはどんな方法で通知するのかの方法でEメールに、 エンドポイントは通知先のメールアドレスを記載します。 それ以外は特に記載せず作成を行います。 サブスクリプションの作成完了 サブスクリプションが作成されました サブスクリプションの承認 現在、サブスクリプションが保留中になっているのでメールで承認します。 メールに以下のように承認メールが来ているので Confirm subscription を押すと承認することが出来ます。 承認完了画面に切り替わりました。 SNSのサブスクリプションをリロードすると以下のように承認済みになりました。 cloudwatch eventsの作成 移動 ホーム > cloudwatch > イベント > ルール から ルールの作成を行います。 ステップ 1: ルールを作成する - イベントソース まずはイベントソースを作成します。 イベントパターンとしては、イベントが一致したときの設定です。 サービス名はEC2 イベントタイプはEC2 Instance State-change Notification 特定のインスタンスが状態はstoppedになったときに、トリガーを発火します。 ステップ 1: ルールを作成する - ターゲット ターゲットは先ほど作成したSNSトピックを設定とします。 こちらで設定を完了として、詳細設定に移ります。 ステップ 2: ルールの詳細を設定する ルールの名前と説明を記載します。 どちらも ec2-alart と、ルールの作成を行います。 ルールの設定完了 ルールが設定されました。 アラートの発火 インスタンスの停止 トリガーとしてインスタンスを停止させます。 停止させました メールの確認 メールが飛んできましたーわーい インスタンスが停止しました的なことが見受けられます 勉強後イメージ やってみたほうがイメージついたかも。 cloudwatch eventsではSNSの設定はできなさそうなのねー
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerComposeをdevelopmentで実行する

これまで、production環境で開発をしてきた。 Dockerを導入し、AWSでのデプロイを試みている。 しかしそれは、他の記事を参考に作っていた為、 意味もわからず、本番環境でやってきただけで、 必要な構成も理解していないので上手く進まなかった。 そこで、development環境に戻し、 まずはDockerの導入にフォーカスして理解度を高めていく。 各ファイルの修正 docker-compose.yml services: local-redis: image: redis container_name: rails-redis container_name: rails-redis local-rails: build: . @@ -15,9 +14,31 @@ services: - local-redis env_file: - env_file.env container_name: rails-rails container_name: rails-rails command: bundle exec rails s -b 0.0.0.0 # bundle exec rails s -e production environment: RAILS_DATABASE_PASSWORD: blago18 RAILS_DATABASE_HOST: db RAILS_DATABASE_USER: blago18 RAILS_ENV: development volumes: - .:/var/www/footomo db: image: mysql volumes: - mysql-data:/var/lib/mysql # ports: # - 3306:3306 environment: MYSQL_ROOT_PASSWORD: MySQL8.0 MYSQL_DATABASE: app_development MYSQL_USER: blago18 MYSQL_PASSWORD: blago18 command: - --default-authentication-plugin=mysql_native_password volumes: mysql-data: コンテナに入ってmigrationを実行 Kotaro18:footomo kotaro18$ docker-compose up --build Creating network "footomo_default" with the default driver Building local-rails [+] Building 0.3s (16/16) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 37B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/ruby:2.6.6 0.0s => [ 1/11] FROM docker.io/library/ruby:2.6.6 0.0s => [internal] load build context 0.1s => => transferring context: 24.44kB 0.1s => CACHED [ 2/11] RUN curl -sL https://deb.nodesource.com/setup_11.x | bash - 0.0s => CACHED [ 3/11] COPY ./ /var/www/footomo 0.0s => CACHED [ 4/11] WORKDIR /var/www/footomo 0.0s => CACHED [ 5/11] COPY Gemfile /var/www/footomo 0.0s => CACHED [ 6/11] COPY Gemfile.lock /var/www/footomo 0.0s => CACHED [ 7/11] RUN apt-get update 0.0s => CACHED [ 8/11] RUN apt-get upgrade -y 0.0s => CACHED [ 9/11] RUN gem update bundler 0.0s => CACHED [10/11] RUN apt-get install build-essential patch ruby-dev zlib1g-dev liblzma-dev -y 0.0s => CACHED [11/11] RUN bundle install 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:80be9ac03901063a087005abd6dda11a3649ae427b8362763ce3dac898f1c523 0.0s => => naming to docker.io/library/footomo_local-rails 0.0s Successfully built 80be9ac03901063a087005abd6dda11a3649ae427b8362763ce3dac898f1c523 Creating rails-redis ... done Creating footomo_db_1 ... done Creating rails-rails ... done Attaching to rails-redis, footomo_db_1, rails-rails db_1 | 2021-04-07 23:35:44+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.23-1debian10 started. db_1 | 2021-04-07 23:35:44+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql' db_1 | 2021-04-07 23:35:44+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.23-1debian10 started. db_1 | 2021-04-07T23:35:45.026977Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.23) starting as process 1 db_1 | 2021-04-07T23:35:45.041398Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started. rails-redis | 1:C 07 Apr 2021 23:35:44.073 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo rails-redis | 1:C 07 Apr 2021 23:35:44.074 # Redis version=6.0.8, bits=64, commit=00000000, modified=0, pid=1, just started rails-redis | 1:C 07 Apr 2021 23:35:44.074 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf rails-redis | 1:M 07 Apr 2021 23:35:44.105 * Running mode=standalone, port=6379. rails-redis | 1:M 07 Apr 2021 23:35:44.106 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. rails-redis | 1:M 07 Apr 2021 23:35:44.106 # Server initialized rails-redis | 1:M 07 Apr 2021 23:35:44.112 * Ready to accept connections db_1 | 2021-04-07T23:35:45.698289Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended. db_1 | 2021-04-07T23:35:46.033480Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock db_1 | 2021-04-07T23:35:46.142287Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed. db_1 | 2021-04-07T23:35:46.142734Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel. db_1 | 2021-04-07T23:35:46.148257Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory. db_1 | 2021-04-07T23:35:46.195505Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.23' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL. ここで、初歩的なミスをしてしまいました。 一旦、Ctl+Cでキャンセルしてから、 同じターミナルでコンテナに入ろうとしたところ、 railsは既に立ち上がってますとのエラーが。 server.pidを削除したり、 他のターミナルで立ち上がってないかチェックしてました。 単純に、1つのターミナルでコンテナを立ち上げ、 もう1つのターミナルでコンテナに入ればいいだけでした。 Kotaro18:footomo kotaro18$ docker-compose exec local-rails bash root@fc0180c62138:/var/www/footomo# そして、migrationを実行 Kotaro18:footomo kotaro18$ docker-compose exec local-rails bash root@fc0180c62138:/var/www/footomo# rails db:migrate == 20180217122153 CreateBoards: migrating ===================================== -- adapter_name() -> 0.0000s -- adapter_name() -> 0.0000s -- adapter_name() -> 0.0000s -- create_table(:boards, {:options=>"ENGINE=InnoDB", :id=>:integer}) -> 0.0507s == 20180217122153 CreateBoards: migrated (0.0511s) ============================ == 20180315233935 CreateComments: migrating =================================== -- adapter_name() -> 0.0000s -- adapter_name() -> 0.0000s -- adapter_name() -> 0.0000s -- create_table(:comments, {:options=>"ENGINE=InnoDB", :id=>:integer}) -> 0.1153s == 20180315233935 CreateComments: migrated (0.1230s) ========================== == 20180324120737 CreateTags: migrating ======================================= -- adapter_name() -> 0.0000s -- adapter_name() -> 0.0000s -- adapter_name() -> 0.0002s -- create_table(:tags, {:options=>"ENGINE=InnoDB", :id=>:integer}) -> 0.0416s == 20180324120737 CreateTags: migrated (0.0485s) ============================== == 20180324120941 CreateBoardTagRelations: migrating ========================== -- adapter_name() -> 0.0000s -- adapter_name() -> 0.0001s -- adapter_name() -> 0.0000s -- create_table(:board_tag_relations, {:options=>"ENGINE=InnoDB", :id=>:integer}) -> 0.0912s == 20180324120941 CreateBoardTagRelations: migrated (0.0963s) ================= == 20180506115954 CreateUsers: migrating ====================================== -- adapter_name() -> 0.0000s -- adapter_name() -> 0.0000s -- adapter_name() -> 0.0000s -- create_table(:users, {:options=>"ENGINE=InnoDB", :id=>:integer}) -> 0.0376s -- add_index(:users, :name, {:unique=>true}) -> 0.0656s == 20180506115954 CreateUsers: migrated (0.1056s) ============================= == 20181128051946 AddBirthdayToUser: migrating ================================ -- add_column(:users, :birthday, :date, {}) -> 0.0430s == 20181128051946 AddBirthdayToUser: migrated (0.0452s) ======================= Dockerのコンテナに入り、 dbをmigrationできました。 引き続き、開発環境で コンテナの適切な導入を実施していきます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Nuxt.js+Vuetify on AWS Amplify環境のWebアプリbundleサイズ削減覚書

この記事は何 自作webアプリ開発中に直面した『bundleサイズ大きすぎる問題』解決に向けた覚書 最終的な結論は下記の通り 目下開発推進中のプロジェクト(今回だとaws-amplify)を使う場合は最新版が出ていないか、その中で自分が直面している問題が解決されていないか確認することが必要。 GithubのIssueを確認して、その中で解決策が議論されていないか探すことが必要。 何が問題だったか 以下の環境でbundleサイズがgzip後で680kB程度あり、Lighthouseのモバイルスコアが50点程度になる要因の1つであった。 package.json { "dependencies": { "@aws-amplify/ui-components": "^1.1.0", "@aws-amplify/ui-vue": "^1.0.6", "@nuxtjs/pwa": "^3.3.5", "aws-amplify": "^3.3.24", "core-js": "^3.8.3", "nuxt": "^2.14.12", "nuxt-webfontloader": "^1.1.0" }, "devDependencies": { "@nuxtjs/vuetify": "^1.11.3", etc..., }, } Nuxt.js開発時のbundleサイズ削減に向けてよく見かける方法として、下記はすでに導入済み。 Vuetify.jsのTreeShakeを有効化する extractCSSオプションを有効化する またAmplifyのTreeShakeを使ってbundleサイズ削減に向けた対策も織り込み済み。この辺、ちょっと古いネット情報を見てしまうと誤るので要注意。 https://github.com/aws-amplify/amplify-js/issues/488 ざっくり書くとこう OK: import { Auth } from '@aws-amplify/auth NG: import { Auth } from 'aws-amplify' その上で、js、cssそれぞれで下記の課題あり。 js: aws-amplify/authから参照しているelliptic, bn.jsなどのサイズが無駄に大きい(gzip後で100kB超) css: 全体のサイズが280kB程度ある。中身を見てみるとTreeShakeを有効にしているのに、使用していないVuetifyコンポーネントのcssが大量に含まれている 解決手段 aws-amplify/authから参照しているモジュール GithubのIssueを漁っていると全く同じ課題が議論されており、すでに解決策もmergeされていることがわかった(see) 多くの環境にとって不要なモジュールをすべてimportしていたっぽい(雰囲気) @aws-amplify/authが参照しているamazon-cognito-identity-jsが4.6.0以降であれば上記修正を織り込み済み aws-amplify/authを3.4.27から3.4.29に上げて効果を確認した。bundleサイズ▲150kB程度。 Vuetify.jsのCSSが読み込まれてしまう問題 こちらもnuxt-vuetifyのissueを読み漁って探した どうやらTreeShakeを有効にしていてもcssは適切に取捨選択されない模様 nuxt-purgecssを使えば良いという情報にたどり着くまでが長かった…。 ただしnuxt-purgecssのデフォルト設定だと、必要なcssまで削減してしまうことも分かった。適切な設定が必要。 nuxt-purgecssという単語がわかったので検索してみると、Qiitaでも投稿されている方を発見(see)。大変参考になりました。cssサイズ激減。 おわりに 新しいものに手を出すときは、最前線の情報を探しに行くことが大事ですね…。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む