20210413のAWSに関する記事は24件です。

【とりあえずハンズオン】EC2でReactを動かすだけの話

はじめに この記事では EC2 上で React を動かすだけのハンズオン記事です。 ベストプラクティスや間違いがあれば 書き直していく予定です。 環境 ヤマダにペペロンチーノをこぼされた初代 Surface Book 実装 RAM 8GB エディション Windows 10 Pro バージョン 20H2 OS ビルド 19042.867 Chrome 89.0.4389.90(Official Build) (64 ビット) ハンズオンセットアップ ざっくり、流れを説明 AWS 上に EC2 を構築 Visual Studio Code で Remote SSH をインストール Remote SSH の設定 EC2 に React をインストール React を ローカルホストで実行 AWS 上に EC2 を構築 まずはコンソールを開いて。。。 と以前から CloudFormation の記事で EC2 の構築をやっているので 今回は IaC で構築します。 VPC を構築 まずは EC2 を置くためのサブネットを切る為に VPC を CloudFormation で構築します。 CloudFormation の管理画面を開きます。 スタックの作成をクリック vpc_network.yml AWSTemplateFormatVersion: 2010-09-09 Parameters: VpcCidrBlock: Description: VpcCidrBlock Type: String Default: 10.0.0.0/21 Resources: MainVpc: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCidrBlock EnableDnsHostnames: true EnableDnsSupport: true Tags: - Key: Name Value: MainVpcfromCF IGW: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: igw Value: igw-cf AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref MainVpc InternetGatewayId: !Ref IGW Outputs: MainVpc: Value: !Ref MainVpc Export: Name: MainVpcId MainIgw: Value: !Ref IGW Export: Name: MainIGWId ファイル選択から vpc_network.yml をアップロードします。 スタック名は「vpc_network」とします。 サブネットを切る VPC が構築できたらサブネットを切ります。 今回は React アプリケーション公開用にセキュリティグループに TCP でポート 80 を開けます。 ReactSubnet.yml AWSTemplateFormatVersion: 2010-09-09 Parameters: AZ: Description: AvailabilityZone Type: String Default: "ap-northeast-1a" PublicSubnetCidrBlock: Description: PublicSubnetCidrBlock Type: String Default: 10.0.2.0/24 Resources: PublicSubnet: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Ref AZ VpcId: !ImportValue MainVpcId CidrBlock: !Ref PublicSubnetCidrBlock Tags: - Key: Name Value: PublicSubnet PubRT: Type: AWS::EC2::RouteTable Properties: VpcId: !ImportValue MainVpcId Tags: - Key: PublicRoute Value: PublicRouteCf PubToInternet: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PubRT DestinationCidrBlock: 0.0.0.0/0 GatewayId: !ImportValue MainIGWId PubRTAssociate: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet RouteTableId: !Ref PubRT secSSHGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: PublicSecGrp GroupDescription: PublicSecGrp VpcId: !ImportValue MainVpcId SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 Tags: - Key: Name Value: PublicSecGrp Outputs: PublicSubnet: Value: !Ref PublicSubnet Export: Name: PublicSubnet PublicSecGrp: Value: !GetAtt secSSHGroup.GroupId Export: Name: PublicSecGrp ファイル選択から ReactSubnet.yml をアップロードしてスタックを作成 スタック名を「react-subnet」とします。 スタックの作成には時間がかかりますので少し待ちましょう。 キーペアを作成する AWS コンソールから EC2 を開き、左ペインからキーペアを選択 キーペアを作成をクリック キーペアを「Mykeypair」という名前で作成 EC2 を構築する CloudFormation の画面に戻り、EC2 を作成する。 public_react_ec2.yml AWSTemplateFormatVersion: 2010-09-09 Resources: myEC2Instance: Type: AWS::EC2::Instance Properties: KeyName: Mykeypair ImageId: ami-0992fc94ca0f1415a InstanceType: t2.micro Monitoring: false NetworkInterfaces: - AssociatePublicIpAddress: true DeviceIndex: "0" GroupSet: - !ImportValue PublicSecGrp PrivateIpAddress: "10.0.2.10" SubnetId: !ImportValue PublicSubnet Tags: - Key: Name Value: PublicEC2 ファイル選択から public_react_ec2.yml をアップロード スタックの完成予想図 セキュリティグループの確認 SSH 用のポートと公開用のポート番号が開かれていることを確認しましょう。 Visual Studio Code の設定 Visual Studio Code で Remote SSH をインストール EC2 に SSH でログインする為に VisualStudioCode のプラグインである「Remote SSH」をインストールします。 まだ、インストールをしていない人は以下のようにインストールと表示されていると思います。 インストールされている方は以下 Remote SSH の設定 Visual Studio Code の拡張機能 Remote SSH を設定します。 まず、Visual Studio Code の画面左下の緑ボタンを押します。 するとウィンドウの上部に選択肢が出るので「Connect to Host...」を選択 続いて「Configure SSH Hosts」を選択 Remote SSH の格納先を問われるのでユーザ名配下の.ssh を選択 以下の内容を環境に合わせて記載。 Host React-EC2 HostName {パブリックIPアドレス} IdentityFile {キーペア名(フルパス)} User ec2-user コンフィグを保存して閉じる。 再度、緑のボタンを押して Remote SSH 接続を開始すると新しいウィンドウが開かれる。 point The authenticity of host '54.178.82.82 (54.178.82.82)' can't be established. ECDSA key fingerprint is SHA256:sDZUv1irzZeafPa0UzdyNMmI0SGAViB5/ZTmRJ4vwG0. Are you sure you want to continue connecting (yes/no)? SSH 接続する前にこんなことを聞かれたら yes と打って次へ React を試す EC2 React のセットアップ 「Open Folder 」を選択 ディレクトリを選択 ec2-user のホームディレクトリ「/home/ec2-user/」を選択 Visual Studio Code のウィンドウ左ペインから ファイルを新規作成 以下のような Bash スクリプトを書いて EC2 の「/home/ec2-user/」に保存する。 react-nginx.sh # !/bin/bash sudo yum update -y && \ sudo amazon-linux-extras install -y nginx1.12 && \ sudo systemctl start nginx.service && \ sudo systemctl enable nginx.service && \ sudo yum -y install git && \ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash && \ . ~/.nvm/nvm.sh nvm install node && \ git clone https://github.com/ymd65536/react.git && \ cd react && \ sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf_backup && \ sudo cp ./nginx.conf /etc/nginx/nginx.conf && \ sudo systemctl restart nginx && \ bash ./react_install.sh react_install.sh は react リポジトリに格納 react_install.sh # !/bin/bash cd quick-react && \ npm install && \ npm run build && \ npm run start echo "React Setup Complete!!" &(アンパサンド)を使うことでコマンドの実行がこけた時の対策ができる。 例えば、今回のケースだと最初の yum がこけた場合は以降のコマンドは実行されない。 また、バックスラッシュでコマンド同士をつなぐとコマンド同士をつないでから実行するという意味になる。 作成した Bash スクリプトを実行する。 HTTP で開く http://localhost:3000/ を開く ※npm run start すると自動で開かれる。 ちなみに まとめ 今回は CloudFormation で VPC と EC2 を構築して React 環境を建てました。 次回はこの React をコンテナに入れたいと思います。 CloudFormation にスクリプトを埋め込めばもっと楽にできたなこれ。(あとの祭り) おわり
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Fargate タスクを定期実行したいときに EventBridge 以外の選択肢も検討してみる

概要 Amazon ECS の Fargate タスクを cron のようにスケジュール実行したい場合、候補として挙がるのが EventBridge (CloudWatch Events) ただし EventBridge には考慮しなければいけない 2 つの問題点がある メリット・デメリットを理解して、それ以外の選択肢も考えてみる EventBridge 利点 サーバレスでフルマネージド 実装不要 欠点 1. 少なくとも 1 回の起動が保証される よく知られている特徴で、稀に 2 回以上イベントが実行されることがある。 対策 同時実行耐性や冪等性が保証されるようにアプリケーションを実装する必要がある。 2. Fargate タスクの起動は保証しない ポイントは以下。 EventBridge はタスクの RunTask の実行を保証する ただし RunTask によってタスクが起動したかどうかは保証しない 筆者も経験があるが、稀に AWS 側の不具合で Fargate が起動に失敗することがあった。 なお、この事象は EventBridge からの呼び出しに限らず、AWS CLI や SDK など RunTask API を利用するもの全般にいえる。 対策 Step Functions を間に挟み、もし Fargate の起動に失敗した場合はリトライするようにステートマシンを組む方法がある。 EventBridge --> Step Functions --> Fargate 議論 EventBridge を利用する場合、欠点で挙げた 1. (稀に 2 回以上起動) と 2. (Fargate の起動保証はしない) を考慮しなければいけない。 一方で、EventBridge を使わずにあえて crontab を動かすためのサーバーを別で用意するという原始的な手もある。この場合、欠点で挙げた 1. は考慮しなくてもよい。ただし依然として 2. は cron 側の実装でなんとかしなければいけないし、新たに cron の可用性を考慮しなければいけない。 このあたりはトレードオフにはなるが、同時実行耐性や冪等性を保証するアプリケーションの実装が困難な場合は検討してもよいのではないだろうか。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

S3 + CloudFront + WAFv2 をCDKで構築した時にregion等でハマった話

「CloudFront経由でS3にアクセスする + WAFv2でアクセス制限をかける」リソース一式を構築するAWS CDKのサンプルです. WAFv2リソースはus-east-1リージョンのスタックとして S3バケットとCloudFrontはそれ以外のリージョンのスタックとして(検証ではap-northeast-1を使用) deployする方法と,実装でハマったポイントをまとめました. CDKは,2021.04.13時点での最新バージョンである,1.98.0を使用しました. 動機 S3でホスティングしている既存ウェブサイト(ap-northeast-1)に独自ドメインを割り当てたかったが,バケット名がドメイン名と異なっており,CloudFrontの導入が必要となった. CloudFront経由でのアクセスに,IPベースでのアクセス制限をかける必要があり,WAFでのアクセス制御も必要となった. 既存リソースはCDKで管理されており,新たに追加するリソースもCDKの管理下にしたかった. Overview CDK サンプルコード 01-waf stack WAFv2 WebACLを管理するスタックです. CloudFormation - WAFv2 - Scopeに書かれているように,WAFv2のACLをCloudFrontに関連付けたい場合,US East (N. Virginia) Region (us-east-1)へWAFv2リソースを作成する必要があります.そこで,app.tsで明示的にリージョンを指定しています. const wafStack = new WafStack(app, '01-waf', { // (省略) env: { account: stackEnv.account, region: "us-east-1", // ここ }, // (省略) }); 実装当初,この制限に気づかず,deployエラーでハマりました.(WAFv1の場合,リージョン制限は無いようです.) 後述のスタックで作成するCloudFrontとの関連付けには,作成したWebACLのARNが必要となります. ここでは,SSM Parameter StoreにWebACL ARNを格納しました(これを参照する方法は後述). 02-web-dist stack コンテンツを格納するS3バケット S3バケットを向き先としたCloudFront distribution を管理するスタックです.技術検証のため,01-waf スタックと別リージョンにしています. S3バケット,CloudFront web distributionを定義し,先に作成したWAFv2 ACLと関連付けていくのですが, ここでの問題は,US East (N. Virginia) RegionのParameter Storeに格納されているWebACL ARNを参照しなければならない点です. cross-regionの参照は通常の方法では不可能なため,こちらを参考にカスタムリソースを使った参照クラスを実装して解決しました. ハマったポイント WAFv2 リソースのリージョン制限 WAFv2のWebACLをCloudFrontに関連付ける場合,ACLをus-east-1に作成する必要がありました. CDKでの他リージョンのSSM Parameter Store参照 const param = ssm.StringParameter.valueForStringParameter(this, `param-name`); の方法で参照できるのは,そのスタックの同一リージョンのParameter Storeのみです. cross-region参照するため,カスタムリソースを使った方法の情報にたどり着くまで苦労しました... CDKでのCloudFrontへのWAF WebACLの関連付け @aws-cdl/aws-wafv2モジュールにCfnWebACLAssociationというクラスがあり,最初,これを使えばよいかと思ったのですが,こちらで関連付けできるのは,API Gateway REST API等,CloudFront distribution以外の場合でした. CloudFrontと関連付ける場合は,CloudFrontWebDistribution側で,WebACLを指定する必要があります. webACLのプロパティ名はwebACLIdとなっていますが,WAFv2を使う場合WebACLのARNを指定する点にも注意してください. this.distribution = new cloudfront.CloudFrontWebDistribution( this, "website-distribution", { webACLId: webAclArn, // 以下省略 } ); ACLの中身 本サンプルでは,IPアドレスベースの制限としています.アクセスを許可するIPアドレスは, cdk.context.jsonに記述して,CDK context valueとしてインポートしています. サンプル公開用では,ダミーのIPアドレスを記述しているので,検証したいIPアドレスに書き換えてください. { "allowed_ips": [ "10.0.0.0/16" ] } Reference 本スタック実装にあたり参考にさせていただいたサイトを,トピック別に掲載しました. WAFを使ったCloudFrontへのアクセス制限 CloudFront + S3 での IP アドレスベースのアクセス制限設定をする CDKを使ったWAFリソースのdeploy AWS CDKでWAFv2を構築しIPアドレス制限を試してみた AWS WAFv2をCDKで構築してみた TerraformでCloudFrontにACL(AWS WAF)を定義するときのエラー対処方法 AWS WAFの解説 AWS WAFを完全に理解する - WAFの基礎からv2の変更点まで - WAF WebACL for CloudFrontの作成リージョンに関する注意 【小ネタ】AWS WAF v2 の WebACL (CloudFront用)を東京リージョンから CloudFormation で作成しようとしたら怒られた AWS WAF v1 と v2 それぞれで WebACL を CloudFormation で作成したときにハマった話 AWS CDKで他のリージョンのssm parameter storeを参照する方法 CloudFormation Cross-Region Reference | stack overflow
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】無料でできること

プログラミング勉強日記 2021年4月13日 AWSの無料で使えるサービスの種類  AWSの無料で使えるサービス内容によって3種類ある。前3種類のAWS無料枠のサービスは期間や利用できるサービスが異なる。 常に無料 12か月間無料 トライアル 常に無料の枠  この枠では、該当するサービスが永遠無料でできる。AWSを使っているすべてのユーザが利用できる。 12ヶ月無料の枠  AWSにサインアップした時点から12か月間無料でできるサービス。 トライアルの枠  該当するサービスを一定の期間無料で利用することができる。サービスによって無料で利用できる条件が異なるので、注意が必要。(条件は回数の場合もあれば機関の場合もある。) 無料でできること 常に無料の枠  アプリ利用時の設定が不要で、大量のデータ管理、高速のデータ処理を行える。 12ヶ月無料の枠  利用設定の手間がかかることなく、データの取得・保存が簡単にでき、様々な管理を自動化できる。  1年間全てのサービスが無料というわけではない!AWSのアカウント登録から1年間有効な無料枠があるというサービスなので、無料で使えるのは一部に限る。なので、該当しないサービスの利用では課金されるので注意が必要。 トライアルの枠  作業効率を上げることができ、安全な環境で作業をできる。 参考文献 AWS 無料利用枠 もう悩まない!AWSの無料利用枠でできることをわかりやすく解説
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ROSAで作成されるAWSのリソースを調べた

こんにちは。 AWSで気軽にOpenShiftが使えるROSAがリリースされたはいいものの、「結構いい値段するんじゃないかな…」と思ってる方も多いかと思います。 実際にROSAを使ってみて、どういうリソースが作られてるのかを整理したので、自分の備忘を兼ねて書き残してみました。 目的 ROSAのコストイメージや構成を確認したかったので、デフォルトで構築するとどういうリソースができるのかを調査しました 全ては調べきれなかったので、コストに影響が大きそうなNWとEC2周りを重点的に調査してます 調査した環境 rosa create cluster --cluster-name XXXX を実行して作成した環境を調査しています 細かい環境の作り方はこちらを見ていただくと良いかと。(@Yusuke-Yさんありがとうございます) https://qiita.com/Yusuke-Y/items/bffc2a1197ff4f7bbb3e 調査結果 作成されたEC2リソース一覧 リソース種別 個数 EC2インスタンス(m5.xlarge) 5 EC2インスタンス(r5.xlarge) 2 EC2インスタンス(t2.micro) 構築時のみ全region分 EBS 17 EBSSnapshot 5 SecurityGroup 5 NLB 2 CLB 3 TargetGroup 3 作成されたNWリソース一覧 リソース種別 個数 VPC 1 Subnet 2(PublicとPrivate各1つ) RouteTable 2 InternetGateway 1 ElasticIP 1 S3Endpoint 1 NatGateway 1 NetworkACL 1 作成されたリソース一覧(その他) リソース種別 個数 S3Bucket 2 HostedZone 2 気になるところ 結果としては上記の通りなのですが、調べてみて気になったところをいくつか記載します。 EC2インスタンスが多い xlargeクラスのインスタンスが7つ上がるので、それだけで結構コストがかかります。 会社などで使う分には大した額では無いでしょうが、個人でちょっと試してみる、という場合には中々負担が大きいです。 LBがやたら多い ROSAをデフォルトで入れた場合、CLBが3つ、NLBが2つ作成されます。 集約できそうな気もしますが、ROSAで作成された環境に手動で手を加えるのはサポート外になるようです。 Bootstrap用(?)のEC2が全リージョンに作成される 環境作成時にBootstrap用と思われるEC2が全リージョンに作成されるという動きをするため、一時的に全リージョンにEC2インスタンスが作成されます。 t2.microなのでそれほどコストには響かないとは思いますが、ちょっと気持ち悪い動きをします。 WAFが適用できない AWSのWAFをロードバランサに適用する場合はALBへの適用となりますが、ROSAで作成されるアプリの入り口となるロードバランサはCLBになります。 そのため、WAFを適用したい場合はALBを別途作成する(ROSAでVPCを作成した場合は他のVPCへ配置)か、AWSのWAF以外を利用する必要があります。 まとめ 正直な感想としては、個人で使う分には決して安くは無いというのが感想ですね…上記以外にOpenShiftのライセンス費用もわずかですがかかります。 具体的なコストで言うと、クラスターを立ち上げた後で8時間ぐらい起動しっぱなしにしていたところ、請求はコミコミで10$強でした。 とはいえ、OpenShiftの導入が格段に容易になったことから、ちょっと使ってみたい、一日ぐらい触れれば満足、というニーズにはフィットすると思います。 気になった方は是非一度お試しください。 内容に誤記等あればご指摘ください。よろしくお願いします。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon Managed Blockchain(Hyperledger Fabric)ハンズオン体験記

はじめに 先日、こちらのハンズオンに参加したので、忘備録を兼ねて、体験記を残しておきたいと思います。 https://awsbasics.connpass.com/event/206599/ 当日は大量の手順に追われ、何をやっていたのか理解できずに進めていましたが、こうやって振り返ることで、理解していきたいです。 元記事はこちらのようです。 Hyperledger Fabricの概要 ※この項目はハンズオン中にはありませんでしたが、内容理解のために追加しました。  【参考】https://medium.com/acompany/hyperledger-fabric-%E6%A6%82%E8%A6%81-b24a6d74e74c 構成 CA ユーザ証明書の管理 Peer 台帳の保持 Orderer ブロックの作成・配布 Client ブロックチェーンとやり取りするアプリ データ chaincode 台帳の照会や更新の処理手順 Go、Node.js、Javaなどで記述 ledger 台帳 Blockchain 履歴を保持 World State 現在の状態を保持 中身はLevelDB(キーバリュー)かCouchDB(JSON) 処理の流れ Endorsement  1-1. Transaction ProposalをPeerに送信(1)  1-2. ユーザーのIDと権限を検証(2)  1-3. Responseを返信(3) Ordering  2-1. TransactionをOrdererに送信(4)  2-2. ブロックを作成(5) ValidationとCommitment  3-1. ブロックをPeerに配布(6)  3-2. イベントを送信(7) 構成 今回は以下のような構成を構築します。 クライアントノードはCloud9上に構築しますが、アカウントが1つしかないので作成するのは1つだけです。(Blockchainのメリットを感じることはできないですね) 前提条件 今回は東京リージョンで構築します。 Cloud9環境の作成 ポイントだけ記述します。 環境の作成 インスタンスタイプは「t2.medium」に変更 ネットワーク設定で、VPCとパブリックサブネットを設定(後で使用するので覚えておくこと) 起動に少し時間がかかる ホームディレクトリの表示 右上歯車から左ペイン「AWS SETTINGS」-「Credentials」を選択 「AWS managed temporary credentials」をOFFに 左ペイン「Environment」の左上歯車から「Show Home in Favorites」を選択 後でホームディレクトにファイルを保存するのに楽だから ターミナル画面で作業 「aws configure」を実行して、「Default region name」を「ap-northeast-1」(東京リージョン)を指定 IAMの設定 ポイントだけ記述します。 ロールの作成 「一般的なユースケース」-「EC2」を選択 以下の2つのロールをアタッチ AmazonManagedBlockchainFullAccess AmazonS3FullAccess Cloud9のIAMロールを変更 ポイントだけ記述します。 EC2で作業 Cloud9用インスタンスを選択 「アクション」-「セキュリティ」-「IAMロールの変更」を選択 作成したIAMロールを選択 ネットワークの作成 Managed Blockchainの初期設定 ポイントだけ記述します。 ネットワークの作成 「Hyperledger Fabric」で作成 Hyperledger Fabric認証機関(CA)の管理者ユーザ名と管理者パスワードは、後で使うので覚えておくおくこと 30分ほど時間がかかる VPCエンドポイントの作成 Cloud9を構築したVPC、サブネット、セキュリティグループ(EC2のCloud9用インスタンスで確認)を指定 ピアノードの作成 自分が所有するメンバーから、特に設定を変更せずに作成 後で使うので「ピアエンドポイント」を覚えておくこと Fabricクライアントの設定 ここからCLIでの作業が大量に発生します。 Cloud9の設定① EC2で作業 Cloud9用インスタンスを選択 セキュリティグループをクリック 「インバウンドルールの編集」で以下を追加 すべてのTCP ソース:セキュリティグループID(自分自身) ルールを保存 Cloud9で作業 コンソールで以下を順次実行 使用するモジュールのインストール sudo yum update -y sudo yum install jq telnet emacs docker libtool libtool-ltdl-devel git -y dockerの起動 sudo service docker start sudo usermod -a -G docker ec2-user Cloud9ディスク容量を増設 Cloud9で作業 ディスク容量を確認 df -h 「resize.sh」をカレントディレクトリに保存 resize.sh #!/bin/bash # Specify the desired volume size in GiB as a command-line argument. If not specified, default to 20 GiB. SIZE=${1:-20} # Get the ID of the environment host Amazon EC2 instance. INSTANCEID=$(curl http://169.254.169.254/latest/meta-data/instance-id) # Get the ID of the Amazon EBS volume associated with the instance. VOLUMEID=$(aws ec2 describe-instances \ --instance-id $INSTANCEID \ --query "Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.VolumeId" \ --output text) # Resize the EBS volume. aws ec2 modify-volume --volume-id $VOLUMEID --size $SIZE # Wait for the resize to finish. while [ \ "$(aws ec2 describe-volumes-modifications \ --volume-id $VOLUMEID \ --filters Name=modification-state,Values="optimizing","completed" \ --query "length(VolumesModifications)"\ --output text)" != "1" ]; do sleep 1 done #Check if we're on an NVMe filesystem if [ $(readlink -f /dev/xvda) = "/dev/xvda" ] then # Rewrite the partition table so that the partition takes up all the space that it can. sudo growpart /dev/xvda 1 # Expand the size of the file system. # Check if we are on AL2 STR=$(cat /etc/os-release) SUB="VERSION_ID=\"2\"" if [[ "$STR" == *"$SUB"* ]] then sudo xfs_growfs -d / else sudo resize2fs /dev/xvda1 fi else # Rewrite the partition table so that the partition takes up all the space that it can. sudo growpart /dev/nvme0n1 1 # Expand the size of the file system. # Check if we're on AL2 STR=$(cat /etc/os-release) SUB="VERSION_ID=\"2\"" if [[ "$STR" == *"$SUB"* ]] then sudo xfs_growfs -d / else sudo resize2fs /dev/nvme0n1p1 fi fi IAMで作業 IAMロールにさらに2つの権限を追加 AmazonEC2FullAccess AWSCloud9Administrator Cloud9で作業 コンソールで以下を順次実行 sh resize.sh 30 ディスク容量を確認 df -h EC2で作業 Cloud9インスタンスを再起動 Cloud9の設定② Cloud9で作業 コンソールで以下を順次実行 Docker Composeのインストール sudo curl -L https://github.com/docker/compose/releases/download/1.20.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose sudo chmod a+x /usr/local/bin/docker-compose Goのインストール wget https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz tar -xzf go1.14.4.linux amd64.tar.gz sudo mv go /usr/local gitのインストール sudo yum install git -y 「~/.bash_profile」を修正して、保存 「MyMemberCaEndpoint」を「Fabric認証機関エンドポイント」の値に変更 「MyNetworkOrdererEndpoint」を「サービスエンドポイントの注文」の値に変更 bash_profile # .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs PATH=$PATH:$HOME/.local/bin:$HOME/bin # GOROOT is the location where Go package is installed on your system export GOROOT=/usr/local/go # GOPATH is the location of your work directory export GOPATH=$HOME/go # CASERVICEENDPOINT is the endpoint to reach your member's CA # for example ca.m-K46ICRRXJRCGRNNS4ES4XUUS5A.n-MWY63ZJZU5HGNCMBQER7IN6OIU.managedblockchain.us-east-1.amazonaws.com:30002 export CASERVICEENDPOINT=MyMemberCaEndpoint # ORDERER is the endpoint to reach your network's orderer # for example orderer.n-MWY63ZJZU5HGNCMBQER7IN6OIU.managedblockchain.amazonaws.com:30001 export ORDERER=MyNetworkOrdererEndpoint # Update PATH so that you can access the go binary system wide export PATH=$GOROOT/bin:$PATH export PATH=$PATH:/home/ec2-user/go/src/github.com/hyperledger/fabric-ca/bin 引き続き、Cloud9で作業 コンソールで以下を順次実行 環境の設定、確認 source ~/.bash_profile sudo docker version sudo /usr/local/bin/docker-compose version go version 「get_member」を修正し、直接コンソールで実行 「network-id」をネットワークIDに変更 「member-id」をメンバーIDに変更 get_menber aws managedblockchain get-member \ --network-id n-MWY63ZJZU5HGNCMBQER7IN6OIU \ --member-id m-K46ICRRXJRCGRNNS4ES4XUUS5A 引き続き、Cloud9で作業 コンソールで以下を順次実行 認証関連の準備 curl https://$CASERVICEENDPOINT/cainfo -k mkdir -p /home/ec2-user/go/src/github.com/hyperledger/fabric-ca cd /home/ec2-user/go/src/github.com/hyperledger/fabric-ca wget https://github.com/hyperledger/fabric-ca/releases/download/v1.4.7/hyperledger-fabric-ca-linux-amd64-1.4.7.tar.gz tar -xzf hyperledger-fabric-ca-linux-amd64-1.4.7.tar.gz Hyperledger Fabricのサンプルの取得 cd /home/ec2-user git clone --branch v1.4.7 https://github.com/hyperledger/fabric-samples.git 「docker-compose-cli.yaml」を修正し、ホームディレクトリ(/home/ec2-user)に保存 「MyMemberID」をメンバーIDに変更 「MyPeerNodeEndpoint」をピアエンドポイントに変更 docker-compose-cli.yaml version: '2' services: cli: container_name: cli image: hyperledger/fabric-tools:1.4 tty: true environment: - GOPATH=/opt/gopath - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - FABRIC_LOGGING_SPEC=info # Set logging level to debug for more verbose logging - CORE_PEER_ID=cli - CORE_CHAINCODE_KEEPALIVE=10 - CORE_PEER_TLS_ENABLED=true - CORE_PEER_TLS_ROOTCERT_FILE=/opt/home/managedblockchain-tls-chain.pem - CORE_PEER_LOCALMSPID=MyMemberID - CORE_PEER_MSPCONFIGPATH=/opt/home/admin-msp - CORE_PEER_ADDRESS=MyPeerNodeEndpoint working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: /bin/bash volumes: - /var/run/:/host/var/run/ - /home/ec2-user/fabric-samples/chaincode:/opt/gopath/src/github.com/ - /home/ec2-user:/opt/home 引き続き、Cloud9で作業 コンソールで以下を順次実行 サンプルの実行環境の構築 docker-compose -f docker-compose-cli.yaml up -d sudo /usr/local/bin/docker-compose -f docker-compose-cli.yaml up -d 証明書の設定 Cloud9で作業 コンソールで以下を順次実行 証明書の作成準備 aws s3 cp s3://ap-northeast-1.managedblockchain/etc/managedblockchain-tls-chain.pem /home/ec2-user/managedblockchain-tls-chain.pem openssl x509 -noout -text -in /home/ec2-user/managedblockchain-tls-chain.pem 「fabric-ca-client」を修正し、直接コンソールで実行 「AdminUsername」を管理者ユーザ名に変更 「AdminPassword」を管理者パスワードに変更 「$CASERVICEENDPOINT」をFabric認証機関エンドポイントに変更 fabric-ca-client fabric-ca-client enroll \ -u 'https://AdminUsername:AdminPassword@$CASERVICEENDPOINT' \ --tls.certfiles /home/ec2-user/managedblockchain-tls-chain.pem -M /home/ec2-user/admin-msp 引き続き、Cloud9で作業 コンソールで以下を順次実行 生成した証明書のコピー cp -r /home/ec2-user/admin-msp/signcerts admin-msp/admincerts チャンネルの作成 Cloud9で作業 「configtx.yaml」を修正し、ホームディレクトリ(/home/ec2-user)に保存 「MemberID」(2ヶ所)をメンバーIDに変更 configtx.yaml ################################################################################ # # Section: Organizations # # - This section defines the different organizational identities which will # be referenced later in the configuration. # ################################################################################ Organizations: - &Org1 # member id defines the organization Name: MemberID # ID to load the MSP definition as ID: MemberID #msp dir of org1 in the docker container MSPDir: /opt/home/admin-msp # AnchorPeers defines the location of peers which can be used # for cross org gossip communication. Note, this value is only # encoded in the genesis block in the Application section context AnchorPeers: - Host: Port: ################################################################################ # # CAPABILITIES # # This section defines the capabilities of fabric network. This is a new # concept as of v1.1.0 and should not be utilized in mixed networks with # v1.0.x peers and orderers. Capabilities define features which must be # present in a fabric binary for that binary to safely participate in the # fabric network. For instance, if a new MSP type is added, newer binaries # might recognize and validate the signatures from this type, while older # binaries without this support would be unable to validate those # transactions. This could lead to different versions of the fabric binaries # having different world states. Instead, defining a capability for a channel # informs those binaries without this capability that they must cease # processing transactions until they have been upgraded. For v1.0.x if any # capabilities are defined (including a map with all capabilities turned off) # then the v1.0.x peer will deliberately crash. # ################################################################################ Capabilities: # Channel capabilities apply to both the orderers and the peers and must be # supported by both. # Set the value of the capability to true to require it. # Note that setting a later Channel version capability to true will also # implicitly set prior Channel version capabilities to true. There is no need # to set each version capability to true (prior version capabilities remain # in this sample only to provide the list of valid values). Channel: &ChannelCapabilities # V1.4.3 for Channel is a catchall flag for behavior which has been # determined to be desired for all orderers and peers running at the v1.4.3 # level, but which would be incompatible with orderers and peers from # prior releases. # Prior to enabling V1.4.3 channel capabilities, ensure that all # orderers and peers on a channel are at v1.4.3 or later. V1_4_3: true # V1.3 for Channel enables the new non-backwards compatible # features and fixes of fabric v1.3 V1_3: false # V1.1 for Channel enables the new non-backwards compatible # features and fixes of fabric v1.1 V1_1: false # Application capabilities apply only to the peer network, and may be safely # used with prior release orderers. # Set the value of the capability to true to require it. # Note that setting a later Application version capability to true will also # implicitly set prior Application version capabilities to true. There is no need # to set each version capability to true (prior version capabilities remain # in this sample only to provide the list of valid values). Application: &ApplicationCapabilities # V1.4.2 for Application enables the new non-backwards compatible # features and fixes of fabric v1.4.2 V1_4_2: true # V1.3 for Application enables the new non-backwards compatible # features and fixes of fabric v1.3. V1_3: false # V1.2 for Application enables the new non-backwards compatible # features and fixes of fabric v1.2 (note, this need not be set if # later version capabilities are set) V1_2: false # V1.1 for Application enables the new non-backwards compatible # features and fixes of fabric v1.1 (note, this need not be set if # later version capabilities are set). V1_1: false ################################################################################ # # SECTION: Application # # - This section defines the values to encode into a config transaction or # genesis block for application related parameters # ################################################################################ Application: &ApplicationDefaults # Organizations is the list of orgs which are defined as participants on # the application side of the network Organizations: Capabilities: <<: *ApplicationCapabilities ################################################################################ # # Profile # # - Different configuration profiles may be encoded here to be specified # as parameters to the configtxgen tool # ################################################################################ Profiles: OneOrgChannel: Consortium: AWSSystemConsortium Application: <<: *ApplicationDefaults Organizations: - *Org1 引き続き、Cloud9で作業 コンソールで以下を順次実行 Ordererの作成 docker exec cli configtxgen -outputCreateChannelTx /opt/home/mychannel.pb -profile OneOrgChannel -channelID mychannel --configPath /opt/home チャンネルの作成 export ORDERER=「サービスエンドポイントの注文」の値 docker exec cli peer channel create -c mychannel -f /opt/home/mychannel.pb -o $ORDERER --cafile /opt/home/managedblockchain-tls-chain.pem -tls docker exec cli peer channel join -b mychannel.block -o $ORDERER --cafile /opt/home/managedblockchain-tls-chain.pem -tls チェーンコード(SmartContract)の実行 Cloud9で作業 コンソールで以下を順次実行 チェーンコードの設定 docker exec cli peer chaincode install -n mycc -v v0 -p github.com/chaincode_example02/go docker exec cli peer chaincode instantiate -o $ORDERER -C mychannel -n mycc -v v0 -c '{"Args":["init","a","100","b","200"]}' --cafile /opt/home/managedblockchain-tls-chain.pem -tls docker exec cli peer chaincode list --instantiated -o $ORDERER --C mychannel --cafile /opt/home/managedblockchain-tls-chain.pem –tls docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}' 100という値から10を引くコマンドを実行 docker exec cli peer chaincode invoke -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}' -o $ORDERER --cafile /opt/home/managedblockchain-tls-chain.pem -tls docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}' 感想 CLIばかりで訳が分かりませんが、何度も試したり、スクリプト等の中身を確認し、理解したいと思います。 後始末 作成したものを削除していきます。 Cloud9 インスタンス Managed Bockchain ピアノード メンバー ネットワーク
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Python、Lambda、API GatewayでLINEチャットBotを作る

今回はline-bot-sdk-pythonを使わずにAWSのLambdaとAPI Gatewayでオウム返しLINEチャットボットを作ったので投稿します。AWS初心者が初めてのLambdaとAPI Gatewayに挑みました。 LINE Developersへのチャネル登録 https://developers.line.biz/ja/services/messaging-api/ を開いて「今すぐはじめよう」を押してチャンネルを作成してください。 AWS Lambdaの関数の作成 Lambdaの画面に遷移して関数を一から作成しましょう。 関数名はLINEBot、ランタイムはPython 3.8 にします。そして関数の作成を押しましょう。 あとLambdaの環境設定を編集しましょう 値のところにMessaging APIのChannel access token(めちゃくちゃ長いやつ)をコピペして保存してください。 ここから「lambda_function.py」を編集して実際にコードを書いていきます。 lambda_function.py の編集 lambda_function.py import logging import os import urllib.request import json logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): logger.info(event) # bodyの中身がJSONの文字列でeventsをループで回す for message_event in json.loads(event['body'])['events']: logger.info(json.dumps(message_event)) url = 'https://api.line.me/v2/bot/message/reply' # リクエストヘッダー headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + os.environ['ACCESSTOKEN'] } # リクエストボディ data = { 'replyToken': message_event['replyToken'], 'messages': [ { "type": "text", "text": message_event['message']['text'], } ] } req = urllib.request.Request(url=url, data=json.dumps(data).encode('utf-8'), method='POST', headers=headers) with urllib.request.urlopen(req) as res: logger.info(res.read().decode("utf-8")) return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') } loggerはCloud Watchでlogを出力しているのでなくてもいいです! https://developers.line.biz/ja/reference/messaging-api/#send-reply-message 公式に下記のような方法でPOSTリクエストすれば良いと書いてありました。 HTTPリクエスト POST https://api.line.me/v2/bot/message/reply リクエストヘッダー Content-Type application/json Authorization Bearer {channel access token} リクエストボディ replyToken Webhookで受信する応答トークン messages 送信するメッセージ そしてオウム返しするには下記のような構造になっていたので "events":[{ "replyToken":"xxxxxxxxxxxxxxxxxxx", "message":{"type":"text","id":"xxxxxxxxxxxxxxx","text":"こんにちは"} }] "text": message_event['message']['text']でオウム返しできる。 API Gatewayの設定 Lambdaの先ほど作成したLINEBotの「関数の概要」より、「トリガーを追加」ボタンを押します。「トリガーを選択」では「API GateWay」、「APIを作成する」をそれぞれ選択し、APIタイプは「HTTP」を選択します。セキュリティは今回は「オープン」を選択します。ここまでできたら「追加」ボタンを押します。 そして作成したトリガーのAPIエンドポイントをコピーしてMessaging APIのWebhookのURLに貼り付けます。  完成 そうするとこのようにオウム返しチャットbotの完成です !!  参考文献 ・ https://qiita.com/taku-0728/items/c80bcf65aba318ac6db0 ・ https://blog.5000164.jp/2017/8/14/line-bot/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ansibleでrundeckサーバを作ってみた

前提条件 ・使用するもの  AWSアカウント  EC2(Amazon Linux) ・2台構成とし、以下の呼び方とする  Ansibleサーバ:AnsibleがインストールされているEC2  rundeckサーバ:rundeckをインストールさせたいただのEC2(ansibleコマンドにてrundeckがインストールされる予定) 大まかな流れ 上記を実施する為の大まかな流れは以下の通り ⑴ansibleサーバの準備 ⑵ansibleのファイル構成を考えて作成 ⑶ansible-playbookコマンドの実行=rundeckインストール 手順⑴ ①ansibleサーバを作るべく、ansibleをインストールする # sudo amazon-linux-extras install ansible2 ⇦インストールする # ansible --version ⇦バージョンを確認する ②公開鍵を作成する # cd /home/ec2-user/.ssh ⇦ディレクトリを移動する # ssh-keygen -t rsa ⇦公開鍵を作成する ③作成した公開鍵をrundeckサーバへコピーする # ssh-copy-id ec2-user@rundeckサーバのIPaddress ④ansibleサーバからrundeckサーバへログインできることを確認する # ssh ec2-user@rundeckサーバのIPaddress 手順⑵ ここから作業は作成したansibleサーバ内で行います。 ①iventory.iniファイルを作成する # iventory.ini [rundeck_servers] rundeckサーバのIPアドレス ②main.ymlを作成する # main.yml --- - hosts: rundeck_servers become: yes tasks: - include_tasks: rundeck.yml ③propertiesファイルを作成する # rundeck-config.properties.txt #loglevel.default is the default log level for jobs: ERROR,WARN,INFO,VERBOSE,DEBUG loglevel.default=INFO rdeck.base=/var/lib/rundeck #rss.enabled if set to true enables RSS feeds that are public (non-authenticated) rss.enabled=false # change hostname here grails.serverURL=http://rundeckサーバのIPアドレス:4440 ⇦作成したrundeckサーバのIPアドレスを指定して記載 # framework.properties.txt # framework.properties - # # ---------------------------------------------------------------- # Rundeck server connection information # ---------------------------------------------------------------- framework.server.name = localhost framework.server.hostname = localhost framework.server.port = 4440 framework.server.url = http://rundeckサーバのIPアドレス:4440 ⇦作成したrundeckサーバのIPアドレスを指定して記載 # ---------------------------------------------------------------- # Installation locations # ---------------------------------------------------------------- ④rundeck.ymlを作成する --- - name: Install java yum: name: java state: present - name: get a repository yum: name: http://repo.rundeck.org/latest.rpm state: present - name: Install rundeckd yum: name: rundeck state: present - name: create directory file: path: /var/lib/rundeck/lib state: directory owner: rundeck mode: 0755 - name: install wget yum: name=wget state=installed - name: install JDBC ⇦mysqlと紐付けを実施したい場合は配置する必要がありました get_url: url: https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.23/mysql-connector-java-8.0.23.jar dest: /var/lib/rundeck/lib - name: enable and start rundeckd systemd: name: rundeckd enabled: yes state: started - name: Install rundeck-cli yum: name: rundeck-cli state: present - name: Set a hostname ansible.builtin.hostname: name: rundeck - name: restart rundeckd systemd: name: rundeckd state: restarted - name: copy rundeck-config.properties copy: src: /home/ec2-user/roles/rundeck/templates/rundeck-config.properties.txt dest: /etc/rundeck/rundeck-config.properties backup: no - name: copy framework.properties copy: src: /home/ec2-user/roles/rundeck/templates/framework.properties.txt dest: /etc/rundeck/framework.properties backup: no 手順⑶ ①ansible-playbook コマンドを実行する # ansible-playbook -i iventory.ini main.yml --ask-become-pass ※「--ask-become-pass」を付けないとsudo権限がなく実行出来ないとのエラー発生したので必要でした。 次回はmysqlとの紐付けをしたymlを公開したいと思います。 ご覧いただきありがとうございました。 参考にさせていただいたもの
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Fargateにコンテナを構築してみた

はじめに  昨今、コンテナ技術の普及やクラウドサービスの発展により、AWSのマネージドサービスを提供する、コンテナ向けサーバーレスコンピューティングエンジンであるAWS Fargateが注目されているようです。  今回、AWS Fargate上にコンテナを構築し、AWSのサービスを利用して運用・監視してみました。本記事では、AWS Fargateにコンテナ適用を検討している方向けに、今回利用したAWSのサービスやAWS Fargate上のコンテナの構築・運用・監視について簡単にまとめます。  以降では、対象としたAWSの構成と、その構成を構築してコンテナを運用・監視する際に利用したAWSのサービスや気になるポイントを説明していきます。(※Dockerやコンテナ、AWSの基本的な知識を有することを前提とします。)  AWSのサービスの具体的な利用手順は説明していないので公式サイトなどを参照してください。 AWS Fargateとは  AWS Fargateは、Amazon ECSとともに使用して、サーバレスでコンテナを管理します。そのため、コンテナを実行するサーバ(Amazon EC2のインスタンス)の管理・運用を意識する必要がなくなるといった利点があります。 AWSの構成  次のAWSの構成を構築してみました。          上の図では、クライアント端末からAWS Fargate上のコンテナ(APサーバを構築)に、リバースプロキシサーバとロードバランサ(ELB)を経由してHTTPリクエストを送信します。コンテナのデータはDBサーバに格納します。 コンテナ構築  AWS Fargate上にコンテナを構築するために、次の①から⑤の流れを行いました。  ※Dockerfileの作成やコンテナイメージの作成には、別途、作業用のAmazon EC2を用意しました。  ① Dockerfileの作成  ② コンテナイメージの作成  ③ コンテナレジストリにコンテナイメージの格納  ④ AWS Fargateのクラスター、サービス、タスク定義の作成  ⑤ タスクの実行(コンテナの起動)  コンテナ構築では、セキュア設計やコンテナ管理を容易にするために、シークレットな情報をコンテナから切り離したり、コンテナイメージからソフトウェアの設定ファイルなどを切り離すことなどがポイントになります。 ■ IPアドレス  AWS Fargateでは、コンテナを再起動するたびに、コンテナに動的にIPアドレスが割り当てられます。そのため、直接コンテナにローカルIPアドレスやAWSのElastic IPアドレスを設定できません。  起動したコンテナに適切にリクエストを送るために、AWS Fargateの前段にロードバランサ(ELB)を配置し、次のAWS Fargateのサービスのロードバランシングの設定画面からロードバランサ(ELB)を設定1しました。  これにより、コンテナ起動時に、対象のロードバランサ(ELB)のターゲットグループ(ターゲットとなるIPアドレス)が自動的に更新され、起動したコンテナに適切にリクエストを振り分けることができるようになります。 ■ Amazon ECR  AWS Fargateでは、コンテナレジストリ(Docker HubやAmazon ECR)に格納されたコンテナイメージを元にコンテナを構築します。今回は、自作したDockerfileからコンテナイメージを作成し、Amazon ECRに格納しました。  Amazon ECRは、格納されたコンテナイメージを自動でスキャンして脆弱性を検査します。さらに、コンテナイメージを暗号化することもできるため、セキュリティ面も安心です。 ■ Amazon EFS  コンテナの管理を容易にするために、AWSのファイルシステムを提供するAmazon EFSを利用2しました。  コンテナイメージには、コンテナ上で動作するソフトウェアの設定ファイルなどを含めることができますが、設定を変更するたびにコンテナイメージを作り替える必要があり、コンテナの管理に手間がかかります。Amazon EFSを利用することで、設定ファイルなどをコンテナイメージから切り離すことができ、設定変更時にコンテナイメージの作り替えが不要になるため、コンテナ管理が容易になります。  あらかじめ、ソフトウェアの設定ファイルなどをAmazon EFSに格納し、AWS Fargate上でコンテナ起動時に自動で読み込ませることができます。      ■ AWS Systems Manager  DB接続情報(ユーザ名やパスワードなど)は、AWS Systems Manager パラメータストアに保存することで、ソフトウェアの設定ファイルからシークレットな情報を切り離しました。  AWS Systems Manager パラメータストアは、設定データの管理と機密管理のためのストレージです。パスワード、データベース文字列、Amazon マシンイメージ (AMI) ID、ライセンスコードなどのデータをパラメータ値として保存でき、パラメータ値はプレーンテキストまたは暗号化されたデータとして保存できます。次はパラメータの保存例です。  上記のパラメータ値を環境変数としてAWS Fargate上のコンテナで利用するには、次に示すように、タスク定義の「コンテナの編集」画面から「環境変数」欄にAWS Systems Manager パラメータストアのパラメータ名を設定します。 コンテナ運用  コンテナ運用では、システム安定稼働のための設定がポイントになります。今回はコンテナの負荷に応じたスケーリングで可用性を向上するために、AWS FargateにAuto Scalingを設定しました。 ■ Auto Scaling  Auto Scalingは、常時必要なコンテナの起動台数や、負荷に応じてスケールイン/スケールアウトしたときのコンテナの最小/最大起動台数を設定します。さらに、自動タスクスケーリングポリシーを作成すると、リソース使用量のしきい値に応じたスケーリングやスケーリングのクールダウン期間(※)などを設定できます。  AWS Fargateでは、コンテナの負荷に応じて柔軟にコンテナ台数をスケーリングすることが可能です。また、ホストを管理する必要がないため、スケールアウト時にサーバリソースを増強する必要などがなく、コストの削減になります。 ※秒単位でスケーリングの間隔を指定します。 コンテナ監視  コンテナ監視では、運用時と同様にシステム安定稼働のための設定がポイントになります。今回はコンテナの保守性を向上するために、コンテナのログやリソース使用状況を監視しました。また、Prometheusに対応した形式の、コンテナの詳細なリソース状況やソフトウェアの統計情報、Java VMのパフォーマンスなどといったメトリクス3(Prometheusメトリクス)も監視しました。 ■ Amazon CloudWatch  コンテナのログやリソース使用状況を監視するために、Amazon CloudWatchを使用しました。AWS Fargateでは、デフォルトでコンテナのログやリソース使用状況をAmazon CloudWatchに送信します。  Amazon CloudWatchでは、アラームを作成することで、コンテナのエラーメッセージの出力やリソースの異常値を検知したときにメール通知(※)することも可能です。 ※メール通知にはAmazon SNSの設定が必要です。 ■ Amazon CloudWatch エージェント  Prometheusメトリクスを監視するために、Amazon CloudWatch エージェントを構築しました。Amazon CloudWatch エージェントを利用すると、自動でコンテナのPrometheusメトリクスを監視し、Amazon CloudWatchに送信してくれます。  Amazon CloudWatch エージェントの構築には、Amazon CloudFormationのテンプレートを使用しました。テンプレートを使用すると、Amazon CloudWatch エージェントの構築に必要なIAMロール、AWS Systems Manager パラメータ、AWS Fargateのサービスやタスク定義などのAWSリソースが自動的に生成されるため、構築が容易です。  AWS Fargateの場合、テンプレートは次のコマンドを実行して取得します。 # curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/master/ecs-task-definition-templates/deployment-mode/replica-service/cwagent-prometheus/cloudformation-quickstart/cwagent-ecs-prometheus-metric-for-awsvpc.yaml  主なテンプレート編集箇所は「task_definition_list」で、以下の例のように定義することで監視したいタスク(コンテナ)を指定できます。 "task_definition_list": [ { "sd_job_name": "prometheus", // メトリクスを出力したいAmazon CloudWatchのログストリーム名 "sd_metrics_ports": "8080", // メトリクスが出力されるポート "sd_container_name_pattern": "^container$", // 正規表現を使用したコンテナ名 "sd_task_definition_arn_pattern": ".*:task-definition/.*sample-task.*:[0-9]+", // 正規表現を使用したタスク定義名 "sd_metrics_path": "/metrics" // メトリクスが出力されるエンドポイント } ]  上記を設定するとAmazon CloudWatchのロググループ「aws/ecs/containerinsights/<クラスター名>/prometheus」の、"sd_job_name"に設定した名前のログストリーム配下にPrometheusメトリクスが出力されます。 まとめ  AWS Fargate上にコンテナを構築して、運用・監視してみました。  AWS Fargateは、オンプレやAmazon EC2のDocker上にコンテナを適用する場合と比べて、ホストとなるサーバ(インスタンス)やDockerを意識する必要がないので、コンテナ管理が容易で、AWSマネジメントコンソールの操作で簡単にコンテナを構築できました。また、AWSのサービスと連携することにより、効率的にコンテナを構築・運用・監視できそうです。  次は、他クラウド環境との比較や、運用費などのコスト面についても調べて比較してみたいです。 ・Amazon Web Services、“Powered by AWS”ロゴ、[およびかかる資料で使用されるその他のAWS商標]は、米国その他の諸国における、Amazon.com, Inc.またはその関連会社の商標です。 ・Docker は、Docker Inc. の米国およびその他の国における登録商標もしくは商標です。 ・その他記載されている会社名、製品名はそれぞれ各社の商標および登録商標です。 単一のロードバランサを設定する場合はAWSマネジメントコンソールの操作で設定できますが、複数のロードバランサを設定する場合は、サービス定義パラメータを使用してAWS CLIで設定する必要があります。 ↩ AWS Fargateのプラットフォームバージョンが1.4.0の場合のみ利用できます。 ↩ ソフトウェアによっては、Prometheusメトリクス出力のために別途プラグインなどを適用する必要があります。 ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Djangoで既存のPostgreSQLを利用

はじめに Djangoチュートリアル③(モデルの作成、Django Admin)ではデフォルトの SQLite データベースの設定を行った。本記事では、PostgreSQL の設定を試してみる。あらかじめ存在している AWS 上に構築されている PostgreSQL を利用するため、①データベースの設定、②データベースからモデルを定義、③マイグレーションまで行う。Integrating Django with a legacy database を参考にした。 ①データベースの設定 まず config/settings.py におけるデフォルト設定(SQLite)を以下に示す。SQLite の 'NAME' は使用するファイルの絶対パスを指定している。 config/settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } } 上記を以下のように変更する。 config/settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': [database_name], 'USER': [user_name], 'PASSWORD': [password], 'HOST': ***.amazonaws.com, 'PORT': '5432' } } SQLite では 'ENGINE' として 'django.db.backends.sqlite3' としていたのを、'django.db.backends.postgresql' に変更しており、あとは DB の設定で必要とされるものを順に指定している。 さらに以下コマンドで PostgreSQL のドライバとして paycopg2-binary をインストールする。 $ pip install psycopg2-binary 上記で行ってきたデータベースの設定で正しく接続できているかは以下コマンドで確認できる。 $ python manage.py dbshell ②データベースからモデルを定義 既存のデータベースを使用しているため、当然モデルの定義がされておらず、Django ORM を使用することができない。Django ではデータベースからモデルを自動生成する inspectdb コマンドが準備されているので、それを利用してモデルを定義する。以下コマンドでは、出力結果をそのまま [app_name]/models.py に保存している。 $ python manage.py inspectdb > [app_name]/models.py 各モデルクラス内のサブクラスである class Meta の項目が意味するものは以下。 - managed:各テーブルの作成、変更、および削除を管理するかどうか。デフォルトでは False。 - db_table:テーブル名。 モデルを定義できたので、有効化するために config/settings.py の INSTALLED_APPS に登録しておく。登録する方法はDjangoチュートリアル③(モデルの作成、Django Admin)のモデルの有効化と同様。 ③マイグレーション 以下コマンドでマイグレーションを行う。 $ python manage.py makemigrations [app_name] $ python manage.py migrate テーブルのアクセスは以下コマンドなどで確認できる。 $ python manage.py shell >>> from [app_name].models import [model_name] >>> [model_name].objects.all() おわりに 既存のデータベースからモデルを自動作成でき、非常に便利なことがわかった。新規データベースでも、モデルを定義するよりデータベースを先に作ってそれからモデルの自動作成をした方が楽なのかも。わかったことがあれば、追記していきたい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS ELB(Elastic Load Balancing)

概要 エラスティック ロード バランサーの説明 RDS(★)と同じ要領でEC2を複製していた(Webサーバーを複製した)場合に起きる問題 ・インターネットゲートウェイのアクセスポイントが分かれてしまう ・サーバーが正常化チェックする問題 ・直接Webサーバーにアクセスさせるのはセキュリティ的に良くない。セキュリティに伴う処理の負荷の問題  → 本来コンテンツを提供する役割のWebサーバーに、通信の複合サーバーリソースの効率的な使い方とはいえない ELBは複数のAZにリクエストを振り分けることができます。ターゲットグループに登録されているリソースに通信を振り分け、インスタンスID,IPアドレス,Lambda関数を設定できます 負荷分散 ロードバランサにはDNS名のアクセスポイントが付与される  → アクセスポイントを一つにし、負荷を分散させる 片方のEC2が忙しそうなら別のEC2に自動でリクエストを流す ヘルスチェック ヘルスチェック機能がある  → 異常なインスタンスを認識し、通信をストップさせ、正しい動きをしているインスタンスのみに通信を流す(ロードバランサーから切り離すと言われる) SSLターミネーション セキュリティが高いが、暗号化された通信の処理が重い ・ELBに証明書を付与することでSSL通信の終端となる + ELBより先はHTTP通信となる  → HTTPS通信を複合する処理を担う  → セキュリティが高いまま、HTTP通信が可能なので処理が軽くなる ELBの種類 ALB アプリケーション ロード バランサー HTTPやHTTPSのリクエストの負荷分散に使える その他特徴 ・レイヤー 7 に対応、HTTP/HTTPS リクエストの負荷分散。 ・クライアントとロードバランサーの間の HTTPS ターミネーションをサポート。(NLBもリスナーにTLSを選択することで、HTTPSターミネーションが可) ・セキュリティグループによるアクセス制限が可能。 ・スティッキーセッションを使って、同一のクライアントからのリクエストを同一のターゲットにルーティングが可能。 NLB ネットワーク TCP,TLS,UDPのトラフィックの負荷分散に使える CLB クラシック 古いタイプのモノ 積極的に使用する必要はない 主な構成 ELBのみパブリックサブネットに配置 それ以外をプライベートサブネットに配置することが多い ※メンテナンス時はメンテナンス用のEC2を用意してそこからメンテナンスをする踏み台サーバーを準備するケースがある 3階層アーキテクチャ ELB作成時に内部向けか、外部向けか選択することができる 外部接続時はALB、内部の接続時はNLBを使用するのが良い 参考 この記事はAWS初学者を導く体系的な動画学習サービス 「AWS CloudTech」の課題カリキュラムで作成しました。 https://aws-cloud-tech.com
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

冗長性のあるブログサービス(冗長構成)を構築してみる

実装デモ 障害を想定した試験として  ①メインのEC2を手動で停止してブログが見れるか確認  ②メインのRDSを停止してもブログが見れるか確認 注意 RDSのDBインスタンスを削除しないと 実装デモ終了時は9~10円/時間かかります。 RDS<アクション<削除でOK 最終スナップショットを作成すると、いつでも復旧可能になる 準備 ・同じリージョンの別AZにメインとサブそれぞれにEC2とRDSを作成。 ・ELBを配置して2台のEC2にhttp通信が振り分けられる様に設定しておく。 ・どちらのEC2が起動しているか見分けがつきやすいように、htmlファイルに見分けがつきやすい様に変化をつけておく ロードバランサー作成 EC2のダッシュボードページ<ロードバランシング<ロードバランサーを選択 ロードバランサーの作成をクリック<ALB作成をクリック 1, ロードバランサーの設定 名前(任意),スキームはインターネット向け,IPアドレスタイプはipv4,リスナーはHTTPの80番ポートのまま,AZはVPCとAZを選択、パブリックサブネットを選択 2,セキュリティ設定の追加を選択 (※注意※)HTTPSプロトコルを使用する様警告がでますが、デモだとHTTP接続で進める 3,新しいセキュリティグループを作成するを選択、セキュリティグループ名(任意)を入力 4,ルーティングの設定<ターゲットグループ 名前(任意),ターゲットの種類をインスタンス,プロトコルをHTTPの80番ポート,プロトコルバージョンはHTTP1を選択 ヘルスチェック HTTPの/でも良いが/readme.htmlを指定 詳細設定でEC2インスタンスのヘルスチェック間隔を設定できる 正常のしきい値を2、間隔を10秒に変更(10秒毎にヘルスチェック通信を飛ばして2回OKならそのインスタンスは正常とみなす設定になる) 5,ターゲットの登録 どのインスタンスをターゲットグループに追加するか選択できる 準備した2つのインスタンスを選択、登録済みに追加をクリック これで2つのインスタンスに通信が振り分けられる設定になる 確認、作成をクリックし完了 ↑の確認でEC2のダッシュボードページ<ロードバランシング<ターゲットグループを選択 今回作成したロードバランサーを選択、targetsを選択すると、どのWebサーバーに対してヘルスチェックの状態を確認できます。 RDSの中に設定されているサイトアドレスをロードバランサーのDNS名に書き換える どちらかのウェブサーバーにログインして下のコマンドでRDSに接続します mysql -h database-1.xxxxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -u wordpress -p 解説 mysql -h RDSのエンドポイント) -u wordpress -p -uでwordpressインストール時に設定したユーザー名に-pオプションをつける 実行してパスワードを入力 (※)wordpressのテーブルを使用する宣言) USE wordpress (※)↓テーブルの名前やオプションを表示 SELECT * FROM wp_options WHERE option_name IN ('siteurl', 'home'); (※)option_value欄がサーバーのパブリックIPアドレスと同じという点を確認しておく UPDATE wp_options SET option_value = 'ロードバランサーのDNS名' WHERE option_name IN ('siteurl', 'home'); (※)上のSELECT文を実行後、書き変わっているか確認 <確認> ・このDNS名をブラウザに打ち込んで正常にブログが開くか ・更新を何度か繰り返してみて、区別できるように準備編でhtmlファイルの違いがみられるか セキュリティグループの設定変更 今の状態だと全て接続元からの80番ポートからの通信が許可されている → ロードバランサーからのセキュリティグループからのアクセスのみに許可するよう設定を変更する EC2<セキュリティグループ<適切なセキュリティグループを選択<インバウンドルール<インバウンドルールを編集 ↓ 80番ポートの0.0.0.0/0を削除 ↓ 同じく80番ポートにロードバランサーで作成したセキュリティグループを選択<ルールを保存 表示に問題ないか確認 障害テスト(EC2) 障害を想定したテストを実施するため、EC2インスタンス片方だけシャットダウンする EC2のページ<インスタンスの状態<インスタンスを停止 <確認> 振り分けが行われず、更新しても停止していないサイトのみが表示し続けられる RDSも冗長化構成 Amazon RDS<データベースを選択<該当するDBを選択して変更をクリック DBインスタンスの設定<可用性と耐久性<マルチAZ配置<スタンバイインスタンスを作成するにチェックをつける 続行→ 変更スケジューリング(デモなので今すぐ変更を選択) 障害テスト(RDS) 先程冗長構成を選択肢たDBを選択<アクション<再起動 DBインスタンスをフェイルオーバーで再起動 <確認> ・Webサイトが正常に動作するか ・DB<ログとイベントの最近のイベントに〇〇 instance failover startedや 〇〇 instance failover completedログが残っているか 参考 この記事はAWS初学者を導く体系的な動画学習サービス 「AWS CloudTech」の課題カリキュラムで作成しました https://aws-cloud-tech.com
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CloudWatch メモ

概要 サービス形態 ー SaaS ・AWSの監視マネージドサービス ・AWSリソースの状態を監視する ・条件に合致した場合、アラームで通知を行う  → (例)EC2のCPU使用率が90%など高負荷まで上がったら通知を出すなど ・条件に合致した場合、アクションを設定できる 全体像 収集、監視、アクション、分析といった機能がある 収集 AWSのリソースの状態(EC2やRDSなど各種サービスのCPU使用率)をはじめとした様々な情報を収集する。 ログファイルなども収集できる この収集する情報のことを メトリクス と言う 監視 CloudWatchのエージェントをインストールすれば、オンプレのサーバーも同じ仕組みで監視できる CPU使用料が90%(しきい値)を超えるとサービスが安定稼働できない → 監視条件を設定するのがAlarmの役目 アクション Alarmが起動したら様々なアクションを設定できる 条件の設定ができて、それぞれの場面、重要度に応じた設定も作成できる ・メール通知、AWS Lambdaを自動的に発動 ・EC2のAuto Scalingを発動 ・EC2アクションの停止、削除、再起動も設定で発動できる 分析 収集した情報をグラフなどで可視化したものをダッシュボードで表示 使用すべき理由 ・自動でメトリクスを収集する AWSリソースを作成した時点でデフォルトのメトリクスが収集される EC2ならCPU使用率やディスクの読み書きのパフォーマンス、ネットワークの流入出の量もデフォルトで収集される ・従量課金性 メトリクスを補完しすぎると補完使用料金が別途かかる(課金対象となる可能性あり) 独自で監視システムを構築するというスタートダッシュ時の料金がオンプレ(★)で構築する監視システムの場合と比べてメリットがある ・高解像度の監視可能 基本は5分感覚でメトリクスを取得するのは無料だが、 詳細モニタリングといった1分間や、1秒間といった高解像度の監視も可能(追加料金) ・オンプレも監視可能 サーバーにCloudWatchのエージェントを入れることにより、一元管理(クラウドもオンプレも)できる 既にオンプレで監視システムを動かしている場合移行は難しいケースも多い可能性もあるが、検討してみる価値あり メトリクス CloudWatchで収集した情報のこと 標準メトリクス あらかじめAWSが用意したメトリクス (例)CPU使用率、NWパフォーマンス,Disk I/Oなど カスタムメトリクス ユーザーが独自に設定したメトリクス 自分でCloudWatchに送る設定を行う必要がある (例)メモリ使用率、ディスク使用率など (補足)CloudWatchエージェント ・CloudWatchエージェントをEC2にインストールする ・EC2にIAMロールをアタッチする ・適切なネットワークルートを設定する アラーム評価 評価軸 設定には3つの評価軸がある 1,Period・・・評価感覚 2,Evaluation Period・・・直近、何個のPeriodを評価対象とするか(評価期間) 3,Datapoints to Alarm・・・評価対象のうち、何個のPeriodがしきい値を超過したか (例) しきい値 - CPU使用率が30%以上 Period - 1分間隔 Evaluation Period - 3個 Datapoints to Alarm - 3個 1分間隔(Period)でCPU使用率を計測し、評価期間中(Evaluation Period)に何回越えたか(Datapoints to Alarm)という設定となる アラームのステータス OK・・・しきい値内の値 ARARM・・・しきい値外の値 INSUFFICIENT・・・収集し始めた場合などの理由により、アラームの状態を判断するのには不十分な値 欠落データの取扱 欠落データ・・・CloudWatchになぜか1分感覚で設定されているのに、データが送信されてこない状態のこと この時CloudWatchがどのように振る舞うのか設定できる Missing・・・見つかりません→ 直近のアラームの状態が保持される Good・・・適正→ 欠落データはしきい値内である Ignore・・・無視→ 過去のデータポイントに遡る Bad・・・不正→ 欠落データはしきい値外である サーバーがダウンしてメトリクスが全て欠落した場合 Missing・・・見つかりません→ INSUFFCIENT(OKでもNGでもなく判断できない状況) Good・・・適正→ OK状態 Ignore・・・無視→ 現在のステータスを保持 Bad・・・不正→ アラーム状態 (例1) CPU使用率ならBadを設定するのが良い → なんらかの不具合によってメトリクス自体を送信できていない可能性があるのでそこを検知するため (例2) エラーが発生した場合のみにメトリクスが作成される場合 → 欠落データをGood(適正)するのが良い 参考 この記事はAWS初学者を導く体系的な動画学習サービス 「AWS CloudTech」の課題カリキュラムで作成しました。 https://aws-cloud-tech.com
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AutoScaling メモ

概要 期間限定のキャンペーンなどで負荷が増加した際、EC2インスタンスを増設して一時的な処理の増加に対応したり、逆に負荷が低下した状態ならEC2インスタンスを減らしたりできる スケールアウトは複数のアベイラビリティゾーンで均等のサーバー数になるようにスケールアウトされます。 数が均等な場合は、ランダムにスケールアウトされます。 起動テンプレート EC2を起動するテンプレートのようなもので、何のAMIを使うか、インスタンスタイプは何か、キーペアはどれか、セキュリティグループなど通常EC2を手動で設定する内容をひとまとめにした機能 何のインスタンスを動かすか、起動テンプレートを作成する ※起動設定(旧版) 起動テンプレートは、内容を更新する際にバージョン管理ができる点に対して 起動設定は別のファイルとして管理しなければならない AWSは起動テンプレートの使用を推奨しています AutoScalingグループ 起動テンプレート作成後に設定する どの起動テンプレートを使用するかを設定するため、先に使用する起動テンプレートと紐付ける 他にELBのターゲットグループと紐付けできる EC2をどれくらい作成していくかを指定する。 設定内容は最小、希望、最大 希望とはAutoScalingグループ作成直後のEC2インスタンスの作成される数 Auto Scalingグループを作成するときは、起動設定を指定する必要があります。複数のAuto Scalingグループに同じ起動設定を指定することができます。ただし、Auto Scalingグループに対して1つの起動設定のみを指定でき、作成後に起動設定を変更することは出来ません。 したがって、Auto Scalingグループの起動設定を変更する場合は、起動設定を作成してから、Auto Scalingグループを新しい起動設定で更新する必要がある。 スケーリングポリシー CloudWatchでメトリクスが発行され、設定したアラームと紐づけることで、EC2を追加したり削除したりできるルールのことで、一つのAutoScalingに対し、複数条件を設定できる (例)アクセス数の増減により↓ ・負荷が70%を越えた状態ならEC2を1つ追加(限度は最大まで) ・負荷が30%を切っていたらEC2を1つ削除(限度は最小まで) 運用について AutoScalingにはスケジュールに基づくスケーリングを設定することができます。例えば毎朝午前 8:30 に業務を開始する場合、処理の増加を予め見越して8:00 からスケーリングを開始すると十分余裕が得られます。 定期的に処理が集中するシステムの運用はスケジュールを利用したスケーリングを設定すべきです。 ネットワークトラフィックの増加を検知してからスケールアウトを行うと業務に間に合わない可能性があります。 また、リザーブドインスタンスやスポットインスタンスを利用する方法も予測に対するアプローチとしては間違いです。 実装の流れ 参考 この記事はAWS初学者を導く体系的な動画学習サービス 「AWS CloudTech」の課題カリキュラムで作成しました。 https://aws-cloud-tech.com
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AutoScaling 起動テンプレート作成 ハンズオン

作成方法 EC2<インスタンス<テンプレートの起動を選択 起動テンプレートを作成をクリック (注意) (=〇〇)→ 作成したテンプレートに実際に設定した内容をメモしています。 起動テンプレート名と説明 起動テンプレート名前を入力、 テンプレートのバージョン説明ではバージョン番号を指定できる(=1.0.0)、 AutoScalingのガイダンスとは、AutoScalingでこのテンプレートを使用する場合にチェックボックスを選択 テンプレートタグ→ このテンプレート自体にタグを追加する。必要に応じてタグを追加(コストタグ) ソーステンプレート→ 既にテンプレートを作成している場合元となるテンプレートを指定して作成し、1から設定する手間を省ける。 続いて AMI(=自分のAMI)、 インスタンスタイプ(=t2.micro)、 キーペア(=既存のキーペア)、 ネットワーキングプラットフォーム(=VPC)、 セキュリティグループはここでは一旦保留にしてENIで設定する、 ストレージも指定できる(=ここではそのまま) リソースタグ(この起動テンプレートを元に立ち上げたEC2インスタンスに対して、アタッチされるタグを指定できる。) ネットワークインターフェース セキュリティグループをENIと紐付ける(既存のEC2インスタンスと同じように設定) パブリックIPアドレスの自動割り当てを有効化に変更(このEC2が立ち上がった際ssh接続、つまり外からこのEC2インスタンスにログインできる設定) 高度な詳細 EC2インスタンスを作成する際に色々な整備機能を指定できる。(今回はデフォルト) <起動テンプレートを作成> 起動テンプレートの特徴 起動テンプレートを変更した際、テンプレートのバージョンを指定して更新することができる。 既存のEC2インスタンスから作成する方法 EC2<インスタンス<アクション<イメージとテンプレート<インスタンスからテンプレートを作成を選択 実際のEC2インスタンスの設定を反映した状態の起動テンプレート作成画面になり、自動的にソーステンプレートにソースインスタンスが表示される 参考 この記事はAWS初学者を導く体系的な動画学習サービス 「AWS CloudTech」の課題カリキュラムで作成しました。 https://aws-cloud-tech.com
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

New Relic SyntheticsモニターのIP範囲をセキュリティグループに反映させるPythonスクリプト

概要 AWS上のサーバーに対してNew Relic SyntheticsによってURL監視をする際に、セキュリティグループで制限をかけている場合に、インバウンドルールにNew Relic SyntheticsモニターのIPを許可ルールに追加したいことがある。その追加・更新のPythonスクリプトを書いた セキュリティグループの更新スクリプト 内容 New Relicで公開されているIPアドレス一覧を取得し、任意のロケーションのIPアドレスを指定のセキュリティグループに対して、その許可ルールを設定する。 https://docs.newrelic.com/docs/synthetics/synthetic-monitoring/administration/synthetic-public-minion-ips/ 新規追加と更新に対応しており、将来、上記のIPアドレスリストに変更があった場合に、その変更も反映できる。 インバウンドルール更新時のルールの識別 セキュリティグループのルールにはIDがなく、ルールを指定して更新することができない。 そこで、各ルールの「Description」を利用し、本スクリプトで更新対象とするルールかどうかの識別を行う。 ルール追加時に New Relic Synthetics Monitor を識別文字列としてルールのDescriptionに設定し、ルールの更新時にはこのDescriptionが設定されているルールが対象となって更新される。 更新の流れ AWS APIの関係で、対象となったルールは変更がなくても一度全て削除されて改めて追加されるという流れになっている。これは、セキュリティグループ内の全てが対象ではなく、Descriptionによって更新対象と識別されたもののみ。 スクリプトの利用 ライブラリインストール (初回のみ) pip install boto3 pip install requests コード update_sg.py import boto3 import copy import requests URL_NR_SYNTHETICS_IP_RANGE = "https://s3.amazonaws.com/nr-synthetics-assets/nat-ip-dnsname/production/ip.json" SG_DESCRIPTION = "New Relic Synthetics Monitor" # Set location labels NR_LOCATIONS = [ "Tokyo, JP", "San Francisco, CA, USA" ] def get_nr_synthetics_ip_range(locations: list): res = requests.get(URL_NR_SYNTHETICS_IP_RANGE) ips_per_location = res.json() ips = [] for location in locations: ips.extend(ips_per_location[location]) ip_ranges = ["{}/32".format(ip) for ip in ips] return ip_ranges def update_sg(security_group_id: str, port: int, protocol: str, cider_ips: list, desc: str, aws_profile: str = None, aws_region: str = "ap-northeast-1", ): """ Update security group """ if aws_profile is not None: session = boto3.session.Session(profile_name=aws_profile, region_name=aws_region) client = session.client("ec2") else: client = boto3.client("ec2") print("Describe current rules.") res = client.describe_security_groups(GroupIds=[security_group_id,]) security_groups = res["SecurityGroups"] if len(security_groups) < 1: return security_group = security_groups[0] print(security_group) del_ip_permissions = [] for ip_perm in security_group["IpPermissions"]: if ip_perm.get("FromPort") == port and ip_perm.get("ToPort") == port and ip_perm.get("IpProtocol") == "tcp": del_ip_ranges = [ip_range for ip_range in ip_perm["IpRanges"] if ip_range.get("Description") == desc] del_ip_perm = copy.deepcopy(ip_perm) if len(del_ip_ranges) > 0: del_ip_perm["IpRanges"] = del_ip_ranges del_ip_permissions.append(del_ip_perm) if len(del_ip_permissions) > 0: print("Delete current rules.") print(del_ip_permissions) client.revoke_security_group_ingress( GroupId=security_group_id, IpPermissions=del_ip_permissions, ) else: print("No deletion targets.") print("add rules") added_ip_ranges = [] for cidr_ip in cider_ips: ip_range = { "CidrIp": cidr_ip, "Description": desc } added_ip_ranges.append(ip_range) print(added_ip_ranges) client.authorize_security_group_ingress( GroupId=security_group_id, IpPermissions=[ { 'FromPort': port, 'IpProtocol': protocol, 'IpRanges': added_ip_ranges, 'ToPort': port, }, ], ) if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description="Update security groups to allow New Relic Synthetics Monitor access.") parser.add_argument('sg_id', type=str, help="Security Group ID") parser.add_argument('--port', type=int, default=80) parser.add_argument('--protocol', type=str, default="tcp") parser.add_argument('--description', type=str, default=SG_DESCRIPTION) parser.add_argument('--aws-profile', type=str, default=None) parser.add_argument('--aws-region', type=str, default=None) args = parser.parse_args() ips = get_nr_synthetics_ip_range( NR_LOCATIONS ) update_sg(args.sg_id, args.port, args.protocol, ips, args.description, args.aws_profile, args.aws_region, ) 実行例 python update_sg.py {セキュリティグループID} --aws-profile {AWSプロファイル} --aws-region {AWSリージョン} 実行すると、このように設定される。 リポジトリ 補足 ポートおよびプロトコル単位での設定となる (デフォルトはTCP:80)。指定する場合は、実行時に --portや --protocol フラグで指定可能 ルールのDescriptionを変更する場合は--description フラグで指定可能 Syntheticsのロケーションを変更する場合は、コード内の NR_LOCATIONS を編集
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS SAMでのCORS(Cross-Origin Resource Sharing)設定

背景 AWS SAMを使うとローカルで開発・テストしてLambdaにデプロイするのが楽になるが、CORSをどう設定すれば良いのかわかりにくかったので、試行錯誤して分かった最終形をここに残しておく。 設定 sam-confとapp.jsに設定が必要。sam-confの書き方は特殊で、AllowMethodsなどの設定を"''"で囲む必要があるので注意。 (Originアクセスを許可したいドメインをORIGIN_DOMAIN_NAMEと記載したので、自身の環境に合わせて置換してください。) sam-conf Globals: Api: Cors: AllowMethods: "'OPTIONS,GET'" AllowHeaders: "'*'" AllowOrigin: "'ORIGIN_DOMAIN_NAME'" app.js exports.lambdaHandler = async (event, context) => { const responseHeaders = { "Access-Control-Allow-Methods": "OPTIONS,GET", "Access-Control-Allow-Headers" : "*", "Access-Control-Allow-Origin": "https://ORIGIN_DOMAIN_NAME" } // any application code const response = { 'statusCode': 200, headers: responseHeaders, 'body': JSON.stringify({ message: "Access allowed" }) } return response; 確認 上記設定でデプロイしたら、ちゃんと設定できているかcurlで確認する。 ({}の中身は自身の環境に合わせて変更してください) $ curl -v -X GET https://{restapi_id}.execute-api.{region}.amazonaws.com/{stage_name}/{endpoint_name} ... 雑多なログ < access-control-allow-origin: https://ORIGIN_DOMAIN_NAME < access-control-allow-headers: * < access-control-allow-methods: OPTIONS,GET
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】AWSアカウント取得したら、すぐやること

AWSアカウント取得したら、すぐやること 以下を実施 rootユーザのMFA化(多要素認証) 管理者IAMユーザーの作成 料金アラートを設定 rootユーザのMFA化(多要素認証) MFA 「multi-factor authentication」の略 rootユーザのMFA化(多要素認証) 管理者IAMユーザーの作成 AWS アカウント ID のエイリアスの作成 料金アラートを設定 CloudWatch で概算請求額をモニタリングする ステップ 2: 請求アラームを作成する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

シンプルでセキュアなRails on ECSのTerraformによる実装

TL;DR 3行で。 シンプルで セキュアな Ruby on Rails on ECS by Terraform を作りました。 目次 はじめに 本構成のテーマ リポジトリ アーキテクチャ Terraform側のTips Rails側のTips さらなるカスタマイズ はじめに ここ数年、業務やプライベートで様々なパターンのRuby on Rails + AWS ECS構成を構築してきました。 例えば、構築したことがるパターンを要素ごとに列挙するとざっと以下のようになります。 フロント部分 ALBのみ CloudFront -> ALB assetsのみCloudFront ECS 起動タイプEC2 起動タイプFargate 2種の混在 デプロイパイプライン 全部GitHub Actions Capistrano + ecs-cli CodePipeline + CodeBuild CodePipeline + CodeBuild + CodeDeploy 他にも、 「本番環境/テスト環境でAWSアカウントが分離しているかどうか」、 「ログにfirelens使うかCloudWatch Logs使うか」、 「ECSタスクとIAM Roleをどう対応させるか」、 「ECRへの接続にVPC Endpointを使うか」等、 細かい点を上げるといろんな構成があります。 これらの組み合わせは無限大ですが、いくつも構築してみて、やっとしっくり来る組み合わせに行き着いたので、その構成とTerraformによる実装を紹介したいと思います。 本構成のテーマ テーマは シンプル & セキュア です。 しっくり来る組み合わせに行き着いたと言っても、サービスの要件次第では構成は微妙に変えていかなければいけません。 なので、要件に合わせて柔軟にカスタマイズできる構成であることと、構築にかかるコストをなるべく小さくしたいことから、シンプルな構成であることを目指して検討しました。 また、せっかくきちんと設計し実装を公開する以上、「○○やってみた」レベルの実装ではなく、実際に本番環境での運用に耐えうるレベルの設計・実装を目指しました。 具体的には、Well-Architected FrameworkやSecurity Hubで紹介されるベストプラクティスに則り設計しています。(いちおう筆者は AWS Certified Solutions Architect - Professional と AWS Certified Security - Specialty を保有してます) リポジトリ 実装したものは以下のリポジトリで公開しています。 リポジトリはRails側とTerraform側(インフラ)で分けています。 これはおそらく最も一般的なリポジトリ分割パターンかなと思います。 担当エンジニア、リリースサイクル、CIなどの観点から自然とこの粒度のリポジトリになるでしょう。 余談: ぶっちゃけ、この実装があればフリーランスの案件普通にこなせるんじゃないかなと思ってる。 よく「サービスとCI/CDパイプラインの構築」という案件目にするので。 Terraform Rails アーキテクチャ この構成のアーキテクチャに関して図を交えながらいくつかの観点で紹介していきます。 全体概要 CloudFront, ALB, ECS, Auroraを利用したシンプルなアーキテクチャです。 CloudFrontにはWAFを設定しXSSやSQLi等の攻撃をブロックします。 CloudFront, ALBのドメインはRoute53で管理しています。 いずれもMulti-AZレベルの可用性をもつように設計しているため、任意のAZで障害が発生してもサービスは継続できる構成です。 ECSは当然起動タイプFargate一択です。 令和の時代にサーバー管理はしたくないんじゃ。 え? rails c したい? Execute Command でOK! ネットワーク VPC内のSubnetは上記のように用途ごとに細かく分けています。 Security Group Security Groupも用途ごとに分けた設計になっています。 Security Group間のインバウンドルールのソースに別Security Groupを指定することで、最低限の通信しか許可していません。 また、VPC Endpointを設定することでインターネットを経由せずにS3やECRと通信できるように設定しています。 CDパイプライン CDパイプラインは上記のようにECRへのイメージプッシュをトリガーに、CodePipelineで実行されます。 ECRへのプッシュをトリガーにすることで、Railsアプリケーション開発者とインフラエンジニアの自然な責任境界を実現できます。 参考:ECS用のCDパイプラインに対する考察 イメージビルドはGitHub Actions側で行います。 rails db:migrate をCodeBuildで実行します。 デプロイはCodeDeployを採用しており、全トラフィックを一括で新バージョンに切り替えることで、デプロイ時にassets参照が404エラーにならないように配慮しています。 Terraform側のTips モジュール利用 これはTipsというより設計方針です。 Terraformでは公開されているものや自作のモジュールを使うことで実装を簡潔にできたりします。 特にAWS公式が提供しているとても便利で、短い記述でAWSのリソースを作成することができます。 https://registry.terraform.io/namespaces/terraform-aws-modules ですが、モジュール側が対応していないため、TerraformやProviderのバージョンを更新できないといった場面に出くわすこともあります。 また、モジュールでは制御できないが、普通にaws providerを使った実装の場合は設定可能な属性がある場合もあります。 aws providerの最新バージョンで追加されたリソースをいち早く使いたいケースなんかもあります。 ですので、多少工数はかかりますが、メンテナンスコスト等を加味してAWS公式モジュール等は利用せずに、aws providerをそのまま使った実装としています。 もちろん簡潔な記述や細かい知識不要で構築できる公式モジュールにも大きなメリットはあるので、「モジュール利用は駄目!」などと言うつもりはなく、使い分けだと思います。 セキュリティ対策 Well-Architected FrameworkやSecurity Hubによるベストプラクティスなどに従い、下記のセキュリティ対策を実施しています。 CloudFrontを前段に配置することによるDDoS対策 WAFのマネージドルールによるXSSやSQLi等の攻撃のブロック RDSの暗号化設定 SSMパラメータストアを利用した秘匿情報の管理 ECRによる脆弱性スキャン tfsecによるTerraformコード静的解析によるセキュリティ指摘 ロギング 以下のログ設定を行っています。 可能な限りログは取得するべきです。(このリポジトリではWAFのログは取得していませんが) CloudFront ALB VPC Flow Log S3 Access Log このリポジトリではあくまでRails on ECS部分の構成がメインなので、AWSアカウントを作成した際に設定すべき、下記のセキュリティ設定は含んでいません。 GuardDuty CloudTrail IAMパスワードポリシー EBSのデフォルト暗号化 証明書とDNSレコード このリポジトリでは、route53.tf の実装のようにRoute53で取得したドメインを利用しています。 もし、ドメインを別の方法で取得している場合でも、Route53から設定できるように移譲するのが良いでしょう。 Route53でドメインを設定できると、acm.tf のようにACMの検証などもスムーズに実装できます。 ACM証明書とその検証DNSレコードの実装: resource "aws_acm_certificate" "main" { domain_name = local.domain subject_alternative_names = ["*.${local.domain}"] validation_method = "DNS" } resource "aws_acm_certificate_validation" "main" { certificate_arn = aws_acm_certificate.main.arn validation_record_fqdns = [for record in aws_route53_record.acm : record.fqdn] } カスタムヘッダーによるALBへのリクエストをCloudFront限定にする CloudFrontで以下のカスタムヘッダーを設定します。 resource "aws_cloudfront_distribution" "main" { origin { custom_header { name = "x-pre-shared-key" value = data.aws_kms_secrets.secrets.plaintext["cloudfront_shared_key"] } # ... } # ... } ALBのリスナールールで、上記ヘッダーが付与されたリクエストのみ、ECSへ流すように設定します。 resource "aws_lb_listener_rule" "app_from_cloudfront" { listener_arn = aws_lb_listener.app.arn priority = 100 action { type = "forward" target_group_arn = aws_lb_target_group.app["blue"].arn } condition { http_header { http_header_name = "x-pre-shared-key" values = [data.aws_kms_secrets.secrets.plaintext["cloudfront_shared_key"]] } } # NOTE: Ignore target group switch lifecycle { ignore_changes = [action] } } このように設定することで、CloudFrontを経由せずに直接ALBへリクエストする経路を塞ぐことができます。 CodeDeployによりローリングアップデートを回避する 複数台のサーバーにRailsをローリングアップデートでデプロイすると、一部のjsやcss等のassets系ファイルの参照が404エラーになる瞬間が発生します。 参考: メドピア AWS勉強会 ECS編 これは、新サーバーからhtmlを取得し、その中のjsを旧サーバーへ取得しにいくと発生します。 この問題を回避する方法は様々ありますが、ここではシンプルにCodeDeployを利用しローリングアップデートを実施しないことで回避しています。 deployment_config_name = "CodeDeployDefault.ECSAllAtOnce" を指定することで、全リクエストを同時に新バージョンへ切り替えることができます。 初期構築時のダミー用ECSタスク定義 プロダクトの構築初期段階など、まだRailsアプリが用意できていない場合に最低限ヘルスチェックにだけ合格する軽量イメージとそれを利用したECSタスク定義が欲しくなります。 medpeer/health_check イメージを使うことで指定したパスのヘルスチェックに合格するだけのECSタスク定義が作成できます。 resource "aws_ecs_task_definition" "app" { # ... # NOTE: Dummy containers for initial. container_definitions = <<CONTAINERS [ { "name": "web", "image": "medpeer/health_check:latest", "portMappings": [ { "hostPort": 3000, "containerPort": 3000 } ], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "${aws_cloudwatch_log_group.app.name}", "awslogs-region": "${local.region}", "awslogs-stream-prefix": "web" } }, "environment": [ { "name": "NGINX_PORT", "value": "3000" }, { "name": "HEALTH_CHECK_PATH", "value": "/health_checks" } ] } ] CONTAINERS } Availability Zoneの繰り返しにはfor_eachを使う 将来、AZが追加されるケースを考慮して、Subnet等AZの数だけ作成するリソースは for_each を利用します。 例えばpublic subnetは以下のように作成します。 resource "aws_subnet" "public" { for_each = local.availability_zones vpc_id = aws_vpc.main.id availability_zone = each.key cidr_block = cidrsubnet(local.vpc_cidr, 8, local.az_conf[each.key].index) tags = { Name = "${local.name}-public-${local.az_conf[each.key].short_name}" } } ここでは、以下のように az_conf という変数を定義しています。 locals { az_conf = { "ap-northeast-1a" = { index = 1 short_name = "1a" } "ap-northeast-1c" = { index = 2 short_name = "1c" } "ap-northeast-1d" = { index = 3 short_name = "1d" } } } cidrsubnet関数 を利用することで、一定ルールでのCIDRの管理を楽に実現できます。 Subnetのidのリストが欲しい場合は以下のコードで生成できます。 values(aws_subnet.public)[*].id KMSを利用した秘匿情報管理 秘匿情報はKMSで暗号化し、このリポジトリに含めることでシンプルに管理できます。 aws_kms_secrets を利用することで、複合はTerraformがplan時apply時に行います。 利用方法は以下のとおりです。 KMSを使い秘匿情報を暗号化する。 $ aws kms encrypt --key alias/terraform --plaintext "secret_value" --output text --query CiphertextBlob aws_kms_secrets データリソースを作成する。 locals { secrets = { foo = "encrypted_value" } } # NOTE: register all secrets data "aws_kms_secrets" "secrets" { dynamic "secret" { for_each = local.secrets content { name = secret.key payload = secret.value } } } SSMパラメータストアやDBのパスワード等、復号した値を利用したい部分に以下のコードを記述する。 data.aws_kms_secrets.secrets.plaintext["foo"] # set decrypted value Rails側のTips イメージビルド GitHub Actionsでイメージビルドを行います。 docker/build-push-action を利用することで、イメージビルドとプッシュを簡潔に記述できます。 Dockerfile の実装のようにマルチステージビルドを利用する実装になっています。 最終的なイメージ以外にbuilderステージもECRをプッシュし、 --cache-from オプションに指定することで、次のビルド時にキャッシュとして利用できるようにしています。 # cache-from に前回の builder ステージのイメージを指定 - name: Build and Push uses: docker/build-push-action@v2 env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} with: push: true cache-from: | type=registry,ref=${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:builder tags: | ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ github.sha }} ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:latest # 今回のbuilderイメージを保存 - name: Save builder cache uses: docker/build-push-action@v2 env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} with: target: builder push: true build-args: | BUILDKIT_INLINE_CACHE=1 tags: | ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:builder ヘルスチェック okcomputer gem を利用することで、ヘルスチェックをシンプルに設定できます。 /health_checks/all にアクセスすることで、追加で指定したDB等へのヘルスチェックも行えるため疎通確認や障害の調査などで非常に便利です。 環境変数から読み込む 以下は環境変数から読み込むようにすることで、特定のインフラとの密結合を避けています。 データベースの接続情報: DATABASE_URL データベースの接続情報(リードレプリカ): READER_DATABASE_URL また、秘匿情報をセキュアに管理するため、 RAILS_MASTER_KEY も環境変数で受け取るようにしています。 さらなるカスタマイズ 今回はさまざまな構成のベースにできるようなシンプルなアーキテクチャとしました。 要件次第ではいろいろとカスタマイズが必要でしょう。 例えば以下のようなカスタマイズはよく要求としてあがってきます。 RedisとSidekiqを利用したWorkerサービスの追加 GitHub Deployment APIを用いたデプロイの管理 CodeDeployによるカナリアリリースの導入 イメージ軽量化によるビルド・デプロイ時間とスケール速度の改善 RailsのレスポンスをCloudFrontでキャッシュして高速化 フロントエンドをSPA構成で配信し、RailsはAPIに徹する どの構成も基本は今回紹介したアーキテクチャをベースに実現できるはずです。 (もちろん今回のアーキテクチャ以外をベースにしたほうが構築が楽なケースも当然あります) さいごに シンプルでセキュアなRails on ECS構成、参考になりましたでしょうか? 特に個人的には、この構成のCDパイプラインの境界とシンプルさが気に入っています。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS SAMを使ったLambda開発

AWS Lambdaを使った開発を行う機会があったので、AWS SAMを使ってみました。 Lambda開発といえばServerless Frameworkが有名みたいですが、今回はAmazon公式という点とテンプレートが充実していそうという点でAWS SAMを採用しました。 AWS SAMとは AWS SAMとは、サーバーレスアプリケーション構築用のフレームワークであり、AWS CloudFormationテンプレートの拡張機能です。 Lambda関数やロール、API Gatewayの作成などをYAMLを使ったテンプレートで定義できます。 アプリの構築にはAWS SAM CLIを使います。テンプレートで定義されたアプリの構築、テストを行うコマンドラインツールです。 準備 AWS CLIのインストール まずはAWS CLIをインストールします。 AWS SAM CLIを使うにはAWS CLIも必要になるので、導入していない場合は併せてインストールが必要です。 ドキュメント沿ってやっていきます。 Installing, updating, and uninstalling the AWS CLI version 2 on Linux - AWS Command Line Interface curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip sudo ./aws/install AWS CLIがインストールできたら認証プロファイルの設定もしておきます。 aws configure AWS SAM CLIのインストール 続いてAWS SAM CLIのインストールを行います。 こちらもドキュメントを参考に。 Installing the AWS SAM CLI on Linux - AWS Serverless Application Model curl -L "https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip" -o "awssamcli.zip" unzip awssamcli.zip -d awssam sudo ./awssam/install これで準備は完了です。 テンプレートをダウンロードする sam initで既存のテンプレートを使って、プロジェクトを初期化できます。 言語ごとにクイックスタートが用意されており、はじめて触る場合はここから慣れていけばよさそうです。 今回はPython3.8のHello Worldを選択。LambdaはZipファイルまたはコンテナイメージでデプロイできますが、今回はZipファイルで行います。 $ sam init Which template source would you like to use? 1 - AWS Quick Start Templates 2 - Custom Template Location Choice: 1 What package type would you like to use? 1 - Zip (artifact is a zip uploaded to S3) 2 - Image (artifact is an image uploaded to an ECR image repository) Package type: 1 Which runtime would you like to use? 1 - nodejs14.x 2 - python3.8 3 - ruby2.7 4 - go1.x 5 - java11 6 - dotnetcore3.1 7 - nodejs12.x 8 - nodejs10.x 9 - python3.7 10 - python3.6 11 - python2.7 12 - ruby2.5 13 - java8.al2 14 - java8 15 - dotnetcore2.1 Runtime: 2 Project name [sam-app]: Cloning app templates from https://github.com/aws/aws-sam-cli-app-templates AWS quick start application templates: 1 - Hello World Example 2 - EventBridge Hello World 3 - EventBridge App from scratch (100+ Event Schemas) 4 - Step Functions Sample App (Stock Trader) 5 - Elastic File System Sample App Template selection: 1 ----------------------- Generating application: ----------------------- Name: sam-app Runtime: python3.8 Dependency Manager: pip Application Template: hello-world Output Directory: . Next steps can be found in the README file at ./sam-app/README.md Python3.8のHello Worldの場合は以下のファイルが作られます。 sam-app/ ├── README.md ├── __init__.py ├── events # ローカル実行用のEvent │ └── event.json ├── hello_world # Lambda本体のコード │ ├── __init__.py │ ├── app.py │ └── requirements.txt ├── template.yaml # AWS SAMのテンプレート └── tests # テストコード ├── __init__.py ├── integration │ ├── __init__.py │ └── test_api_gateway.py ├── requirements.txt └── unit ├── __init__.py └── test_handler.py Lambdaコード Lambdaで実行されるhello_world/app.pyの中身は以下の通り。 import json # import requests def lambda_handler(event, context): """Sample pure Lambda function Parameters ---------- event: dict, required API Gateway Lambda Proxy Input Format Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format context: object, required Lambda Context runtime methods and attributes Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html Returns ------ API Gateway Lambda Proxy Output Format: dict Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html """ # try: # ip = requests.get("http://checkip.amazonaws.com/") # except requests.RequestException as e: # # Send some context about this error to Lambda Logs # print(e) # raise e return { "statusCode": 200, "body": json.dumps({ "message": "hello world", # "location": ip.text.replace("\n", "") }), } 今回のサンプルはAPI Gatewayをトリガーとして実行し、レスポンスボディにメッセージを返すだけの簡単なコードです。 コードのコメントにも記載がありますが、lambda_handlerの引数、返り値はAPI Gatewayのフォーマットに合わせる必要があります。 SAMテンプレート アプリケーションの構成を定義しているtemplate.yamlの中身はこちら。 AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sam-app Sample SAM Template for sam-app # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 3 Resources: HelloWorldFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: hello_world/ Handler: app.lambda_handler Runtime: python3.8 Events: HelloWorld: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /hello Method: get Outputs: # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function # Find out more about other implicit resources you can reference within SAM # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api HelloWorldApi: Description: "API Gateway endpoint URL for Prod stage for Hello World function" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" HelloWorldFunction: Description: "Hello World Lambda Function ARN" Value: !GetAtt HelloWorldFunction.Arn HelloWorldFunctionIamRole: Description: "Implicit IAM Role created for Hello World function" Value: !GetAtt HelloWorldFunctionRole.Arn 基本的にはAWS CloudFormationのテンプレートと同じ構造でリソースを定義できますが、AWS SAMではTransform: AWS::Serverless-2016-10-31が必要になります。 これを設定しておくことで、AWS SAMによる拡張をCloudFormation準拠のテンプレートに変換する処理を行っています。 アプリケーションのリソース定義はResourcesで行っています。 Lambda関数の作成にはAWS::Serverless::Functionを使用しており、LambdaとLambdaに関連するリソースをまとめて定義できます。 今回のサンプルではRuntimeでPython3.8が、EventsのTypeでApi(API Gateway)が指定されていることが確認できます。 ビルド sam buildコマンドでアプリケーションをビルドします。 $ sam build Building codeuri: /home/****/sam-app/hello_world runtime: python3.8 metadata: {} functions: ['HelloWorldFunction'] Running PythonPipBuilder:ResolveDependencies Running PythonPipBuilder:CopySource Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Invoke Function: sam local invoke [*] Deploy: sam deploy --guided ビルドに成功すると.aws-sam/buildにアプリケーションの依存関係を含めたデプロイ用のファイルが作られます。 テスト ローカルで実行するにはAWS Lambdaの実行環境を再現するためdockerイメージが使用されます。 sam local invokeコマンドでLambdaをローカルで実行できます。 $ sam local invoke Invoking app.lambda_handler (python3.8) Image was not found. Building image....................................................................................................................................................................................................................................................................... Skip pulling image and use local one: amazon/aws-sam-cli-emulation-image-python3.8:rapid-1.22.0. Mounting /home/daisuke/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container START RequestId: e80b6598-1f4d-43d0-ab92-38c7482817d3 Version: $LATEST END RequestId: e80b6598-1f4d-43d0-ab92-38c7482817d3 REPORT RequestId: e80b6598-1f4d-43d0-ab92-38c7482817d3 Init Duration: 0.11 ms Duration: 60.86 ms Billed Duration: 100 msMemory Size: 128 MB Max Memory Used: 128 MB {"statusCode": 200, "body": "{\"message\": \"hello world\"}"} レスポンスが正しく確認できました! デプロイ sam deployコマンドでアプリケーションをデプロイします。 --guidedオプションをつけることで、デプロイ設定を対話的に実行できます。 $ sam deploy --guided Configuring SAM deploy ====================== Looking for config file [samconfig.toml] : Not found Setting default arguments for 'sam deploy' ========================================= Stack Name [sam-app]: AWS Region [ap-northeast-1]: #Shows you resources changes to be deployed and require a 'Y' to initiate deploy Confirm changes before deploy [y/N]: y #SAM needs permission to be able to create roles to connect to the resources in your template Allow SAM CLI IAM role creation [Y/n]: HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y Save arguments to configuration file [Y/n]: SAM configuration file [samconfig.toml]: SAM configuration environment [default]: Looking for resources needed for deployment: Not found. Creating the required resources... Successfully created! Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-**** A different default S3 bucket can be set in samconfig.toml ~~~~(省略) Save arguments to configuration file [Y/n]:と聞かれるのでYと答えておくと、デプロイ時の設定ファイルが作成されるので、次回からはsam deployのみでデプロイできます。 はじめてSAMを利用する場合は、S3のバケットを作成するCloudFormationが走ります。 これはビルドしたアプリケーションをアップロードするために使用されます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

冗長性のあるWordPressをAWSで構築する

概要 冗長性のあるブログサービスを今回は構築していきます。 今回は第二弾で前回の続きから行っていくものとします。 前回はこちら https://qiita.com/kohei_abe/items/456cc6c0aa91b76d56ea 前回作成した構成図 前回作成していった構成がこちらです! こちらの問題点としてはEC2, RDSともにシングル構成のため単一障害点が生まれます。 もしAZが何かしらの障害があった場合サービスが停止してしまいます。 またEC2のCPUに負荷がかかり、サービスが落ちた場合これもサービスが停止してしまいます。 またデータベースも複製されていないためこれは極めて危険な状況です。 今回作成する構成図 今回はこのような構成にしていきます。 まずはデータベースですがmasterとslave構成にしていきます。 こちらでデータを複製していきます。 これによりmasterがダウンしても自動的にslaveに切り替えることがAWSは簡単にできます! またEC2も2台配置し、それをELBで分散させています。 ELBはDNS名のアクセスポイントが付与されるといった特徴があります。 つまりアクセスポイントを一つにし負荷分散をさせるということです。 このELBがないとwebサーバーのアクセスポイントが2つになってしまうため、どちらにアクセスして良いかわからなくなってしまいます。 また一つのサーバーがダウンするともう一つが動いていたとしてもダウンしているサーバーにいくと404ページが返ってくるようになります。 これでは意味がないですよね。 つまりELBにアクセスポイントを一つに集中させて、そこから2台のEC2に負荷分散させていくのです。 さらにELBにはヘルスチェック機能が備わっています。 ヘルスチェック...以上なインスタンスを認識し通信をストップする つまりwebサーバーに異常を感じたらそちらの通信はストップしアクセスできないようにします。 これで一つのサーバーがダウンした際にも負荷分散ができるわけです。 さらにELBに証明書を付与することでSSLの通信の終端となります。 図でみていくとわかり安いかと思います。 つまりPCからELBのアクセスポイントに通信する際はSSLで暗号かします。 ただELBからEC2にアクセスする際はHTTP通信で行います。 HTTPSは暗号化するため通信が重くなります。 これによりセキュリティの高さと処理の速さの2つを実現することができます! これをSSLターミネーションといいます。 これは現場でよく使われる技術だそうです。 ロードバランサーは全部で3種類あります。 ALB...httpやhttpsの負荷分散に使用する NLB...TCPなどの負荷分散に使用する CLB...こちらは現在は使われていないので気にしなくて大丈夫です。 ではELBがわかったところで早速手を動かしていきましょう!!! 準備 まずは前回作成したEC2にsshでログインしましょう! ssh -i my-key.pem ec2-user@パブリックIP sudo su - cd /var/www/html/ vi index.php cdコマンドでWordPressのディレクトリに移動します。 viコマンドでindex.phpを編集します。 pタグでweb server1という目印をつけましょう! webサーバー1がブログに入るのがわかったかと思います! EC2を複製する ではEC2を2台に増やすために同じEC2 を作成していきます。 まずは既存のEC2を停止しましょう! 次にアクションからイメージとテンプレート→イメージを作成をクリックします。 イメージ名とイメージの説明をWeb Serverとしイメージを作成します。 これは何をしたかというとイメージのAMIを作成しています。 つまりEC2を作成する際にこのAMIを選択することで簡単にWordPress環境の同じEC2が作成できてしまうということです!!! ではインスタンスのページに行ってインスタンスを起動をクリックします。 こちらのマイAMIにいくと先ほど作成したWebServerのAMIがあります。 こちらを選択していきます! my-vpcでサブネットはpublic2の方を選択します。 この辺りも構成図を確認していくととてもわかりやすいかと思います! 自動割り当てパブリックIPも有効であとはデフォルトの設定で大丈夫です。 その次ストレージはそのままで大丈夫です。 その次のタグの追加でNameタグでWeb Server2としましょう! セキュリティグループは既存のwebサーバーのセキュリティグループを選択しましょう! 基本的にセキュリティグループは揃えましょう! こちらで起動と作成です。 ではwebserver2が作成できたので、停止していたwebサーバー1を起動にしましょう! これで2つのWebServerが立ち上がったかと思います! ではWebServer2とわかるようにこちらも編集していきましょう。 こちらのパブリップIPをコピーします! 一応アクセスできるかも確認しておきましょう! ssh -i my-key.pem ec2-user@13.231.190.5 sudo su - こちらでログインします! cd /var/www/html ll こちらでしっかりとWordPressのファイルがあることが確認できるかと思います! vi index.php こちらで先ほどと同様に今回はwebServer2の目印をつけます :wqa!で上書き保存します! こうするとWeb server2の目印がつきます。 では2つのEC2が目印で作成してできたところでこちらをELBで負荷分散させていきます。 ロードバランサーの作成でALBを選択します。 名前は今回はLB-1とします スキームはインターネット向け my-vpcのpublic-subnet1,2にアベイラビリティゾーンは設定します。 こちらでで次にセキュリティグループの作成を行っていきます。 名前はLB-SG-1としておきます。 こちらで次に進みなす。 ターゲットグループはTG-1としヘルスチェックのパスは/readme.htmlとします。 ターゲットの登録で負荷分散するターゲットを選択していきます。 2台のEC2を選択し登録済みに追加をクリックします! こちらで確認と作成を選択です! では次にデータベースに設定されているDNS名をロードバランサーに書き換えていきます! mysql -h RDSのエンドポイント -u wordpress -p こちらでまずmysqlに入ります。 USE wordpress SELECT * FROM wp_options WHERE option_name IN ('siteurl', 'home'); とすると現在はWebServerのパブリックIPになっているのが確認できるかと思います! こちらを変更しましょう UPDATE wp_options SET option_value = 'http://LB-1-571701307.ap-northeast-1.elb.amazonaws.com' WHERE option_name IN ('siteurl', 'home'); http://の後ろはELBのDNS名を選択しましょう! ロードバランサー→説明で確認ができます。 これで変更できました SELECT * FROM wp_options WHERE option_name IN ('siteurl', 'home'); これで確認が取れたかと思います!! ではDNS名でブログが閲覧できるか確認しましょう! 先ほど入力したDNS名を今度はブラウザに貼り付けてみましょう!! リロードしてみるとわかるかと思いますが、1と2がランダムに切り替わると思います! これでロードバランサーがランダムにwebServer1と2で負荷分散をしていることが確認できました! ではこれで接続が確認できたのでwebServerのセキュリティグループをELBだけに限定しましょう!! 現在だと全てのソースから通信を受け入れることになっています。 こちらをELBのセキュリティグループに変更しましょう!! ブログが問題なく動作しているのが確認できたら成功です ではテストで一つのEC2がダウンした時のテストをしてみましょう!!! EC2を1台停止させます。 2の方を停止させましょう! 停止しても1の方でブログが閲覧できることが確認できました!! リロードしてもずっと1のはずです! つまり本番サービスで仮にどちらかのサーバーが停止した際ももう一つのサーバーが動いているのでユーザーはサイトが観覧できる。 といったことが確認できました!!! テストが終わったらサーバーはまた起動しておきましょう!! 最後にRDSを冗長化する 最後にRDSを冗長化していきます。 構成図をみるとわかるかと思いますが、 master, slave構成の部分です。 ここは超簡単にできます。 データベースの設定画面がから変更を押します。 スタンバイインスタンスを作成するにチェックを入れましょう!! これで続行です。 変更スケジュールは今すぐ変更をクリックします。 これで変更すると。 RDSがmaster, slave構成になります。 これで最後にRDSのテストをしていきましょう!! RDSを再起動しましょう フェイルオーバーで再起動にします! データベースが再起動中になっているのがわかるかと思います! サイトにアクセスしてみてください。 実際にアクセスできることが確認できたかと思います!! こちらで最初の構成図の冗長化構成が完了になります。 最後にRDSは起動しっぱなしだと課金されていくので削除しておきましょう! 削除する際にスナップショットをとりますか?と聞かれるのでこちらを選択しておきます!! こうすることでいつでもデーターベースを復元できることができます! お疲れ様でした!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS CLI EC2 Reserved Instance を一覧(CSV)にする

AWS CLI を使って EC2 リザーブドインスタンスを一覧にします。 aws ec2 describe-reserved-instances --filter Name=state,Values=active | \ jq -r ".ReservedInstances[] | [.Duration, .End, .InstanceCount, .InstanceType, .ProductDescription, .State, .InstanceTenancy, .RecurringCharges[0].Amount, .OfferingClass, .OfferingType, .Scope] | @csv" 解説 2つのコマンドをパイプで繋いでいます。 JSON 取得 aws ec2 describe-reserved-instances --filter Name=state,Values=active これでアクティブな EC2 Reserved Instance が JSON で取得できます。 結果は次のようになります。 { "ReservedInstances": [ { "Duration": 31536000, "End": "2020-04-30T07:17:45+00:00", "FixedPrice": 0.0, "InstanceCount": 1, "InstanceType": "t2.micro", "ProductDescription": "Linux/UNIX (Amazon VPC)", "ReservedInstancesId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "Start": "2019-04-30T07:17:46+00:00", "State": "active", "UsagePrice": 0.0, "CurrencyCode": "USD", "InstanceTenancy": "default", "OfferingClass": "standard", "OfferingType": "No Upfront", "RecurringCharges": [ { "Amount": 0.01000, "Frequency": "Hourly" } ], "Scope": "Region" }, アクティブでないものも取得したい場合は --filter を削除します。 JSON を CSV に変換 jq コマンド を使ってCSVに変換します。 AWS CloudShell でも使えます。 jq -r ".ReservedInstances[] | [.Duration, .End, .InstanceCount, .InstanceCount, .ProductDescription, .State, .InstanceTenancy, .RecurringCharges[0].Amount, .OfferingClass, .OfferingType, .Scope] | @csv"
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS認定ソリューションアーキテクト・アソシエイト(SAA)を一度落ちてからなんとか合格した話

AWSソリューションアーキテクト・アソシエイト 受験レポート 2021/4にAWSソリューションアーキテクト・アソシエイト(SAA)に合格しました。 題名の通りで、実は直近の2021/3に一度落ちてから再度受験して合格しています。 いろいろな諸事情があってなんとか年度内に取得を目指していたのですが、見事に惨敗。 失敗した経験なども含んだ内容になるため、特にこれから受験する方で不安に思っている方に見てもらえればと思っています。 私自身は受験前にメンタルを保つためいろいろな人のQiitaの記事を拝見していましたが、一発合格の人も結構多くて割とプレッシャーを感じたりしてました。 それでもこんな人もいるんやで、という感じで参考になれば幸いです。 受験経緯 会社のとある先輩が取得していて、お前も受けてみれば的なノリで受験を決めました。 実際社内や所属していたチームでも取得を推奨されている資格なので、とりあえず勉強してみようという気になりました。 まず第一段階として2021/2にクラウドプラクティショナーを受験して合格しています。 これまで取得してきた資格としては基本的にアプリ開発に直結するような技術に関わるものだったので、なんだか新鮮でした。 AWSのサービスは覚え切れないくらい多い、と聞いたことはあったのですが出題範囲以外も含めると予想以上に多すぎてドン引きしました。 ただ、データベース系のサービスに関しては業務でも多少調べたり実装したアプリと連携させる機会があったので一番最初に興味を持って学習できました。 今後業務で使う可能性が高いので、AWSの幅広い体系的な知識の証明になるものが欲しくて学習に取り組みました。 学習方法 CLFと同様で、書籍とUdemyのコンテンツを組み合わせた学習方法にしました。 Udemyに関してはセールを狙って安価に購入するのが圧倒的にオススメなので、タイミングを見計らって迷ったら買っちゃいましょう。 学習期間は基礎的な部分からはじめたので、約3ヶ月間じっくりと学習に費やしました。 基本的なサービスの知識をインプットするのに時間をかけ、一通り頭に入ったと思った段階で問題演習に移行していきました。 また、以下には記載していませんがブラックベルトも少しのぞいてみました。 (EFS・CloudFront・Route53・Kinesis‥‥etc) 不安な部分の理解を深めるためにはわかりやすくて適していると思うのですが、出題範囲以外の内容が含まれていたりするものもあったので途中からはほぼ問題演習を優先しました。 この部分は人それぞれだと思います。 1. AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 単行本 まずは定番オレンジ本の一番最新(2021/1発売)を購入して読んでみることにしました。 直近の変更点なども網羅されているため、学習のはじめに読む書籍としては非常に良いものだと感じました。 個別のサービスごとに深く特徴を知るために活用できると思います。 1周読んだ後に付録の模擬試験(45問)を解き、あとはわからないことがあった場合の辞書的な使い方をしました。 2. これだけでOK! AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座(SAA-C02試験対応版) はじめは知らないサービスばかりだったので、基本ハンズオンをとばしながら一通りの動画をみていきました。 動画の内容としては、料金体系なども含めて説明してくれるのでコストパフォーマンス系の知識は一緒に身についたような気がします。 また、気になったところをメモに残せる機能があったので、細かい特徴などを押さえるために使っていました。 書籍と組み合わせて学習することでかなり基礎知識はインプットできるので、時間がある方は組み合わせて活用するのが良いと思います。 短期間で取得を目指している方の場合は、模擬試験が2回分ついているので知っている部分を端折ってどんどん問題演習に入っていく方が良さそうです。 (はじめに不正解だらけになるとモチベーションが下がってしまいそうなので、私の場合はインプットにじっくり時間をかけました) ちなみに模擬試験の正答率推移は以下の通りでした。 (各最後の一回は再受験直前に行いました) 模擬試験①:67%⇨93%⇨89%⇨92% 模擬試験②:63%⇨87%⇨95%⇨86% 3. 【SAA-C02版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集(6回分390問) 受験の2週間前頃からガンガン問題演習して仕上げをするために活用しました。 これまで行ってきた学習でインプットした内容をかなりの問題数を解きながらアウトプットすることで、より知識を定着させることができました。 何回も解き直していると答えを覚えてくるので、一つ一つなぜ正解なのかを考えながら間違っている選択肢を除外できるように意識して取り組みました。 問題を解いたあとに解説を読んで理解する時間もそれなりに使ったような気がします。 また、基礎的な問題と難しめな問題で分かれているので徐々に難しくなっていく印象でした。 高難易度④・高難易度⑤に関してはC02版にアップデートされてからの問題が中心になっているので、最新の傾向で問題演習ができました。 各模擬試験の正答率推移は以下の通りでした。 (こちらも各最後の一回は再受験直前に行いました) 基礎①  :60%⇨78%⇨87%⇨95% 高難易度①:56%⇨76%⇨90%⇨92% 高難易度②:41%⇨87%⇨92%⇨87% 高難易度③:58%⇨83%⇨90%⇨89% 高難易度④:56%⇨81%⇨86% 高難易度⑤:49%⇨72%⇨81% +α. 模擬試験 こちらはCLFのときと同様で本番よりも少ない20問の公式な模擬試験で2000円です。 CLFに合格してると一回無料で受験することができます。(ピアソンVUEではなくPSIのみ対象) 問題文や選択肢が長いものが多いので、雰囲気を知るためにはオススメです。 Udemyや書籍の問題だけに慣れているとそれはそれで本番焦ってしまうことも予想されるので、数日前に受けるのがベストだと思います。 ちなみにUdemyの試験がほぼほぼ解ける状態になってから受けたのですが、なんとなくギャップを感じて50%しか取れませんでした。 20問で30分なので本番と時間配分が違うとはいえ、この点数はさすがにやばいと思ってとても危機感を覚えた記憶があります。 試験概要 試験時間:130分 問題数:65問 受験料:15,000円(税別) 時間も長くてお金もかかるので割とプレッシャーを感じます。 (CLFの合格特典で初回は50%引きで受験ができました) 2時間以上の長丁場になるので、集中力を保つのが結構大変です。 試験結果(1回目) 結果:不合格 得点:699点 ※合格ラインは720点 なんとも悔しい結果となりました。(おそらく大体あと1問くらい) 自分自身決して手を抜いていたとか何かやり残したことはないつもりだったので、なんとも言えない気持ちになりました。 ザブングル加藤みたいな顔をしながらテストセンターから出た記憶が今でも忘れられません。 2021/3のギリギリで受験したため、この時点で目標としていた年度内の取得は未達となってしまいましたとさ。 とはいえこのまま引き下がるわけにもいかず、とりあえず数日やけ酒してから気持ちを入れ替えて対策を練ってから再受験することを決意しました。 本番形式の模試を受けたことにして切り替えることができました。 再受験に向けての学習方法 ひとまず初回の受験で使用した教材や問題集を復習するのは前提として、別の書籍も取り入れました。 実際に受験してみて気づいたこととしては、AWSリソースを組み合わせたレジリエントアーキテクチャやセキュアな設計部分での知識がまだまだ足りていないことです。 出題範囲としてはどちらも大きい部分になるので、試験に合格するための一番の近道として苦手な部分を集中的に学習しようと思いました。 基礎的な個々のAWSサービスの知識はある程度身についている気がしたので、ベストプラクティスとしてどのような組み合わせが考えられるか学習することにフォーカスしました。 一夜漬け AWS認定ソリューションアーキテクト アソシエイト[C02対応]直前対策テキスト 単行本 出題される4つの分野ごとにベストプラクティスをそれぞれ解説してくれる内容になっていました。 いろいろな人の記事でこの書籍を利用している印象があったため、再受験に向けての対策に使ってみることにしました。 実際、一度目の受験時に迷ったような設計構成や組み合わせが記載されていたりしたので、個人的には選んで正解だったと思います。 また、各ページで図を使った説明も多くてイメージしながら進めやすい印象がありました。 試験結果(2回目) 結果:合格 得点:737点(前回比+38点) ※合格ラインは720点 再受験が前回から2週間後から可能なので、知識が頭に残っているうちにすぐに再度受験しました。 2回目なのでオーバーキルする勢いで挑んだのですが、めちゃくちゃギリギリでした。(あと1問間違えてたらやばかった) 喜んでいいのかどうかよくわからない‥とはいえ結果としては見事合格でき、すごくホッとしたのを覚えています。 毎日夢に出るレベルで一応勉強はしていたので、終わってからはとても安眠できました。 セキュアな設計部分の理解度としてはまだまだ伸ばさないといけないところがありそうです。 レジリエントアーキテクチャは前回より点数がよかったみたいです。 実際に受験してみた感想 一度落ちて浪人(といっても約2週間だけど)したときは割と落ち込みましたが、めげないでなんとかメンタルを保ちながら頑張りました。 ちょっとした挫折経験ができたので、一発合格を目指している方には参考にしていただければと思います。 学習する上で、自分が理解できていない部分はどこなのか?合格するためには何をすればいいか?を考えながら取り組んできたつもりなのでなんとか結果に結びついて嬉しく思っています。 自分自身の今後のキャリアのためにも重要な資格の一つとして位置付けていたため、なんとか合格できてよかったです。 今までただがむしゃらにアプリ開発の実装に携わってきた人間なので、クラウドを通してインフラに関する知識も習得することができて一石二鳥感がありました。 幅広いサービスの理解を全体的に深められたのでハンズオンをとばしていた分、今度は業務で使えるように実践的なトレーニングもしていきたいと思います。 あと、これまで受験した資格の中だと割と長い期間勉強したので一旦何か自分にご褒美をあげたいです。(牛タン食べたい) たまに業務が忙しい時期も被ったりしたので、改めて業務をこなしながら資格取得する大変さを感じました。 AWSの資格学習は一旦ここまでにして、ちょっと休憩してからまた別の資格にも挑戦してみようかなと思っています。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon IVS の録画機能を動画配信プラットフォームサービスに組み込む

概要 Amazon IVSが 2020/04/08 に S3 への録画機能を開始した。 https://aws.amazon.com/jp/about-aws/whats-new/2021/04/amazon-interactive-video-service-adds-support-recording-live-streams-amazon-s3/ 今まではライブ配信機能のみを提供していたが S3への録画機能が提供されたことでライブ配信とアーカイブの両方が利用可能になる。 本記事では、S3の録画機能を自前の動画配信プラットフォームと連携するために必要な処理について解説する。 なお最新版のAWS SDKで本機能は利用可能である。 本記事で作成した動画配信プラットフォームに関しては以下を参照されたい。 https://qiita.com/clom/items/697d5fe87461d633d043 S3への録画設定 S3 への録画を行う場合は IVS へ記録設定を行う必要がある。 その際、バケットを新規作成するか、既存のバケットを利用するか選択が可能になるが、利用するIVSのAPIと同じリージョンに属していることが必須である。 今回の場合はIVSがオレゴンに作成しているためS3バケットもオレゴンに作成している。 この記録設定と既存のチャネルや新規チャネルを連携させてS3への録画設定が可能になる。 録画を行った場合、動画データは以下に格納される /ivs/v1/{AWSアカウントID}/{チャネルARNのリソースID}/{年}/{月}/{日}/{ライブ配信単位のユニークID}/ 録画されるS3ファイルの構成 録画された動画データはIVS側から提供される events, 1分おきに生成されるサムネイル画像や各解像度別のtsファイルが格納されている media の2つが存在する。録画完了した動画データを再生する場合は media/hls/master.m3u8をHLSなどが再生できるプレイヤーに入れて再生すると視聴が可能になる。 events には以下のデータが格納されており、録画の開始・終了時刻、レンディションの情報やサムネイルの情報などが含まれている。録画開始時にはrecording-started.json、 録画終了時にはrecording-ended.json が生成される。 recording-ended.json recording-started.json { "version": "v1", "recording_started_at": "2021-04-12T14:49:15Z", "recording_ended_at": "2021-04-12T15:00:30Z", "channel_arn": "arn:aws:ivs:us-west-2:0000000000:channel/aaaaaaaaaa", "recording_status": "RECORDING_ENDED", "media": { "hls": { "duration_ms": 672133, "path": "media/hls", "playlist": "master.m3u8", "renditions": [ { "path": "480p30", "playlist": "playlist.m3u8", "resolution_width": 852, "resolution_height": 480 }, { "path": "360p30", "playlist": "playlist.m3u8", "resolution_width": 640, "resolution_height": 360 }, { "path": "160p30", "playlist": "playlist.m3u8", "resolution_width": 284, "resolution_height": 160 }, { "path": "720p30", "playlist": "playlist.m3u8", "resolution_width": 1280, "resolution_height": 720 } ] }, "thumbnails": { "path": "media/thumbnails" } } } チャネル発行時連携 PHPの場合、チャネルを発行する際に recordingConfigurationArn を追加し、記録設定を作成した際の ARN を用いることで、チャネル発行時に記録設定に設定したS3バケットに対して録画したデータを格納している。 $result = $ivs->createChannel([ 'latencyMode' => 'LOW', 'name' => $uuid->toString(), 'type' => 'STANDARD', 'recordingConfigurationArn' => env('AWS_RECORDING_CONFIGURATION'), ]); 記録設定で使用する ARN は↓の形式で登録されている。 arn:aws:ivs:us-west-2:123456789012:recording-configuration/aabbccddeeff 録画開始・終了の通知受け取り AWSから録画開始、録画終了の通知は EventBridge を通じて受け取ることが可能である。 IVS Recording State Change のイベントを通じて処理が進むためEventBridgeでルールの設定を行い、 Lambdaなどのターゲットを設定して以降の処理を実行させる。 なお、イベントパターンは事前定義がまだ追加されていないためカスタムパターンで追加を行う。 { "source": ["aws.ivs"], "detail-type": ["IVS Recording State Change"] } IVS Recording State Change では 4種類のイベントタイプを提供している。 event description Recording Start ストリームへの処理が開始され S3 への putObject 開始時に通知されるイベント Recording End ストリームへの処理が終了し S3への putObject が終了した際に通知されるイベント Recording Start Failure S3にバケットがない場合などで録画開始が出来ない場合に通知されるイベント Recording End Failure 録画中にエラーが発生し、録画が中止した場合などに通知されるイベント 録画開始、終了のみを検知できればいい場合は Recording Start, Recording End のイベントを受け取り処理を行えるようにする。 通知されるイベントの内容に関しては以下の内容で通知される。 { "version": "0", "id": "12345678-1a23-4567-a1bc-1a2b34567890", "detail-type": "IVS Recording State Change", "source": "aws.ivs", "account": "123456789012", "time": "2020-06-23T20:12:36Z", "region": "us-west-2", "resources": [ "arn:aws:ivs:us-west-2:123456789012:channel/AbCdef1G2hij" ], "detail": { "channel_name": "Your Channel", "stream_id": "st-1F6jDj0t3zV01cXKe5dScIJ", "recording_status": "Recording Start", "recording_status_reason": "", "recording_s3_bucket_name": "r2s3-dev-channel-1-recordings", "recording_s3_key_prefix": "ivs/123456789012/AbCdef1G2hij/2020-06-23T20-12-32.152Z/a1B2345cdeFg" } } イベントは recording_status に記載されており、この値を用いて必要な処理を行う。 recording_s3_key_prefix に該当の動画情報が記録されるためこの値を利用する。 prefixのデータのみでは再生はできないため、動画プレイヤーで再生が行えるようにプレイリスト用のURLを別途生成する必要がある。 受け取ったイベントの値を元に以下のURLを構成することで動画プレイヤーでの再生が可能になる。 https://${s3 URL}/${recording_s3_key_prefix}/media/hls/master.m3u8 stream_id は1配信においては終了まで同一IDとして処理が行われるため、ライブ配信単位でデータを管理したい場合にstream_idをkeyとして持っておくと生成開始・終了イベントが追いやすくなる。 EventBridge から Lambda Function でイベントを受け取り、録画開始・終了に対応したエンドポイントをサービス側に定義している場合、以下のような形でハンドリングが可能になる。 ※実装コードに合わせてパラメーターを定義しているため、実際に運用する場合は送られてくるイベントに合わせて定義する必要がある。 var request = require('request'); const HOST = ''; const EVENT_RECORD_START = 'Recording Start'; const EVENT_RECORD_END = 'Recording End'; const ARCHIVE_START_ENDPOINT = ''; const ARCHIVE_STOP_ENDPOINT = ''; exports.handler = function(event, context) { var actionEndpoint = null; const params = { arn: event.resources[0], stream_id: event.detail.stream_id, playback_path: event.detail.recording_s3_key_prefix } console.log(event.detail.recording_status); console.dir(params); switch (event.detail.recording_status) { case EVENT_RECORD_START: actionEndpoint = ARCHIVE_START_ENDPOINT; break; case EVENT_RECORD_END: actionEndpoint = ARCHIVE_STOP_ENDPOINT; break; default: return; } const options = { uri: HOST + actionEndpoint, headers: { "Content-type": "application/json", }, json: params }; request.post(options, function(error, response, body){}); } まとめ 本記事では、Amazon IVS をすでに利用している場合に今回追加された録画機能を組み込む処理について紹介した。 今まではライブ配信のみの提供でアーカイブ機能を作成する場合は自前でライブ配信を録画する必要があったが、この機能追加により気軽にライブ配信のアーカイブ化が容易となった。 再生時の認証(Playback Auth)やS3への録画(Auto-Record to AmazonS3)などの機能が増えてきたことで動画配信サービスとしてのSaaSの選択肢の一つとして選ばれるようになるのではと思われる。 参考 実装コード
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む