default eye-catch image.

AWS SAM CLIを使ってローカルでLambda関数をビルド・実行・デプロイする

Lambdaで何かをするときチマチマAWSコンソールを触らないといけないとなると面倒すぎる。 ローカルでデバッグ・デプロイできるとかなり楽になる。AWS SAMを使ってみる。 AWS SAM(Serverless Application Model)。広くAWSのServerlessサービスがまとめられている。 AWS SAM CLIのGAは2020年8月。それから何回かアップデートされている。 AWS SAMの実体はCloudFormation。CloudFormationを使ってリソースの構築が走る。 普段CloudFormationを使っていないとSAMのコマンドがコケた時に意味不明なエラーで悩むことになる。 で、悩みながらHelloWorldしてみた。 [arst_toc tag=\"h4\"] Permissions CloudFormationで各種リソースを作る仕組みであるため、同等のPermission設定が必要。 https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-permissions.html AWS SAM は、AWS リソースへのアクセスを制御するために、AWS CloudFormation と同じメカニズムを使用します。詳細については、AWS CloudFormation ユーザーガイドの「Controlling access with AWS Identity and Access Management」を参照してください。 サーバーレスアプリケーションを管理するためのユーザー権限の付与には、3 つの主なオプションがあります。各オプションは、ユーザーに異なるレベルのアクセスコントロールを提供します。 - 管理者権限を付与する。 - 必要な AWS 管理ポリシーをアタッチする。 - 特定の AWS Identity and Access Management (IAM) 許可を付与する。 必要な管理ポリシーは以下。 AWSCloudFormationFullAccess IAMFullAccess AWSLambda_FullAccess AmazonAPIGatewayAdministrator AmazonS3FullAccess AmazonEC2ContainerRegistryFullAccess 触るユーザーにロールを割り当て、上記の管理ポリシーをアタッチしておくこと。 aws configureでprofileを設定しておいて、samコマンドのオプションにprofileを渡せる。 インストール homebrewでインストール。 $ brew tap aws/tap $ brew install aws-sam-cli $ sam --version SAM CLI, version 1.37.0 初期化 sam initでプロジェクトディレクトリを作成できる。 対話的に雛形を作るか、またはテンプレートを読み込む。 Lambdaで使える言語は割と多いが、NodejsとPythonがほとんどとのこと。 NodejsがMost popular runtimeとして扱われてるんだな。 Python書きたくないなというか。all right $ mkdir samtest && cd samtest $ sam init Which template source would you like to use? 1 - AWS Quick Start Templates 2 - Custom Template Location Choice: 1 Cloning from https://github.com/aws/aws-sam-cli-app-templates Choose an AWS Quick Start application template 1 - Hello World Example 2 - Multi-step workflow 3 - Serverless API 4 - Scheduled task 5 - Standalone function 6 - Data processing 7 - Infrastructure event management 8 - Machine Learning Template: 1 Use the most popular runtime and package type? (Nodejs and zip) [y/N]: y Project name [sam-app]: ----------------------- Generating application: ----------------------- Name: sam-app Runtime: nodejs14.x Architectures: x86_64 Dependency Manager: npm Application Template: hello-world Output Directory: . Next steps can be found in the README file at ./sam-app/README.md プロジェクト内は以下のような構成となった。 sam-app/ │ .gitignore │ README.md │ template.yaml ├─events │ event.json └─hello-world │ .npmignore │ app.js │ package.json └─tests └─unit test-handler.js app.jsがコード本体. Hello World.が書かれている。 eventを受け取るlambdaHandlerというアロー関数があって200を返してる。 // const axios = require(\'axios\') // const url = \'http://checkip.amazonaws.com/\'; let response; /** * * Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format * @param {Object} event - API Gateway Lambda Proxy Input Format * * Context doc: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html * @param {Object} context * * Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html * @returns {Object} object - API Gateway Lambda Proxy Output Format * */ exports.lambdaHandler = async (event, context) => { try { // const ret = await axios(url); response = { \'statusCode\': 200, \'body\': JSON.stringify({ message: \'hello world\', // location: ret.data.trim() }) } } catch (err) { console.log(err); return err; } return response }; ビルド そもそもどういう仕組みなのかというと、Lambdaの実行環境をエミュレートしたコンテナが背後にあり、 その中でコードを実行する、ということになっている。それがゴニョゴニョと隠蔽されている。 Lambda関数のコードをビルドしてデプロイ用の「アーティファクト」を作る。 $ sam build Building codeuri: /Users/ikuty/ikuty/samtest/sam-app/hello-world runtime: nodejs14.x metadata: {} architecture: x86_64 functions: [\'HelloWorldFunction\'] Running NodejsNpmBuilder:NpmPack Running NodejsNpmBuilder:CopyNpmrc Running NodejsNpmBuilder:CopySource Running NodejsNpmBuilder:NpmInstall Running NodejsNpmBuilder:CleanUpNpmrc Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Invoke Function: sam local invoke [*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch [*] Deploy: sam deploy --guided ローカルで実行 そしてローカルで実行。 Lambdaをエミュレートするコンテナが動いてapp.jsにあるアロー関数が評価される。 1発目は重いが2発目以降は結構速い。 $ sam local invoke Invoking app.lambdaHandler (nodejs14.x) Image was not found. Removing rapid images for repo public.ecr.aws/sam/emulation-nodejs14.x Building image..................................................................................................................................................................................................................................................................................................................................................................................................................... Skip pulling image and use local one: public.ecr.aws/sam/emulation-nodejs14.x:rapid-1.37.0-x86_64. Mounting /Users/ikuty/ikuty/samtest/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container START RequestId: e0bbec88-dafd-4e3c-8b5e-5fcb0f38f1fa Version: $LATEST END RequestId: e0bbec88-dafd-4e3c-8b5e-5fcb0f38f1fa REPORT RequestId: e0bbec88-dafd-4e3c-8b5e-5fcb0f38f1fa Init Duration: 0.47 ms Duration: 195.40 ms Billed Duration: 196 ms Memory Size: 128 MB Max Memory Used: 128 MB {\"statusCode\":200,\"body\":\"{\"message\":\"hello world\"}\"}⏎ デプロイ 以前はもっと面倒だったらしい。新しいSAMではコマンド1発でデプロイできる。 ただし、1回目と2回目以降でフローが異なる。 1回目ではsamconfig.tomlという設定ファイルを作成する。 2回目以降、作成済みのsamconfig.tomlを使ってデプロイが行われる。 $ sam deploy -g 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]: y #Preserves the state of previously provisioned resources when an operation fails Disable rollback [y/N]: y HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y Save arguments to configuration file [Y/n]: y SAM configuration file [samconfig.toml]: SAM configuration environment [default]: Looking for resources needed for deployment: Creating the required resources... Successfully created! Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-h0aw0pxx8pxv A different default S3 bucket can be set in samconfig.toml Saved arguments to config file Running \'sam deploy\' for future deployments will use the parameters saved above. The above parameters can be changed by modifying samconfig.toml Learn more about samconfig.toml syntax at https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html ... (省略) 最後の文節にあるように、samconfig.tomlを変更することで構成を変更できる。 この後、実際にCloudFormationスタックのアップロード/実行が走りリソースが組み上がる。 2回目以降、-gオプション抜きでsam deployを実行すると以下。 $ sam deploy File with same data already exists at sam-app/e32dcdf231268fbcad9915436e787001, skipping upload Deploying with following values =============================== Stack name : sam-app Region : ap-northeast-1 Confirm changeset : True Disable rollback : True Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-h0aw0pxx8pxv Capabilities : [\"CAPABILITY_IAM\"] Parameter overrides : {} Signing Profiles : {} Initiating deployment ===================== File with same data already exists at sam-app/9a813032a850e5b7fb214dffc5ac5783.template, skipping upload Waiting for changeset to be created.. Error: No changes to deploy. Stack sam-app is up to date Webコンソールで動作確認 Webコンソール上、生成されたLambda関数を確認できる。 HelloWorldが書かれたapp.jsが見える。 Testでサンプルイベントを送るとHelloWorldが200で返ってきた。OK。

default eye-catch image.

ACID特性 (ACID Property)

経験的にトランザクションの性質を知っている気になっているけれど、 ではACID特性のそれぞれを言葉で説明してみて, と言われると難しい. おそらくAtomicityだけをACID特性と言ってきた気がする. Wikipediaから. トランザクション分離レベルもこの際まとめておく. [arst_toc tag=\"h4\"] 不可分性(Atomicity) トランザクションに含まれるタスクが複数ある場合、全てのタスクが完全に完了するか、または全く実行されないか、いずれかであることを保証すること。 口座Aから口座Bに対して1万円送金する. 口座Aから1万円を引くタスクと口座Bに1万円を足すタスクの片方だけが実行されるとおかしなことになる. 両方のタスクが成功して取引引きが完了するか、両方のタスクが失敗して取引が失敗するかいずれか 一貫性 (Consistency) トランザクションの開始から終了までの間、操作対象のデータが正常範囲内に収まることを保証すること. 口座Aから口座Bに送金するケースで、口座Aに1万円しかないのに2万円送金しようとして一時的に口座Aが-1万円になることは一貫性に反する. 一貫性に反するイベントが発生したときにトランザクションを終了する. 独立性 (Isolation) トランザクション内の複数の操作は外部からは隠蔽されることを表す. 外部からはトランザクションの入りと出だけを知ることができる. 口座Aから口座Bに送金するケースで、口座Aから口座Bに1万円を送金する際に、中間状態として口座Aから1万円を減らしただけの状態が発生するものとする. 外部からは中間状態は見ることができず、口座Aから1万円が減り口座Bに1万円が足された状態のみを知り得る. 永続性 (Durability) DBMSの管理上の話. トランザクションが完了した場合,障害を受けたとしても完了後の状態を保持できることを表す. 通常、トランザクション操作はトランザクションログとしてストレージに記録される. トランザクションログはトランザクションの履歴で巻き戻したりできる. システムに異常が発生した場合、トランザクションんログを使って異常発生前の状態まで復旧できる. ACIDの現実 ACID特性を厳密に実装しようとすると、より広範囲のデータにアクセスする必要が発生する. 広範囲のデータにロックを掛けたり更新したりなどでパフォーマンスが落ちる. 実際はある程度妥協して実装される. ACID特性を実現する処理自体が失敗する可能性もある. ファイルシステムやバックアップ方式の工夫により冗長化する. 全ての処理を一度に実行することが求められるが、それは現実的には難しい. ログ先行書き込みとシャドウページング. トランザクション分離レベルを設定することで、トランザクションの並列実行時の厳密性とパフォーマンスのトレードオフを制御できる トランザクション分離レベル Dirty read. トランザクションAとトランザクションBが並列実行. AはBの途中の状態を見ることができる. Non-repeatable read (Fuzzy read). トランザクションAとトランザクションBが並列実行. Aが同じデータを2度読む. 1度目はBが書いていない. 2度目はBが書いている. Aから見て1度目と2度目のデータが異なるか消えているように見える. Phantom read. Non-repeatable readと似ているが、特にAの繰り返し読み込みの間にBがデータを挿入し、Aから見て突然新しいデータが出現したように見えること. 微妙な違いだが、過去から現在に渡って存在しているものの過去の状態が見えることと、過去存在していないが現在見えることは異なり、それぞれ名前がついている. ACID特性の厳密な実装にはパフォーマンス劣化とのトレードオフがあるため、 概念的に、使う側がトレードオフをコントロールできるようになっている. それがトランザクション分離レベル. あくまで概念のためDBMSによってその扱いが異なる. 分離レベル Dirty read Non-repeatable read Phantom read Read Uncomitted発生する発生する発生する Read Comitted発生しない発生する発生する Repeatable Comitted発生しない発生しない発生する Serializable発生しない発生しない発生しない

default eye-catch image.

Auroraの機能など

知識がないのに経験だけ積んだって力にならないんだよね。という話を聞いて腑に落ちた。 資格を取るために学んだことは、日々悩み考える色々な出来事を説明するための武器になる。 今自分は何をやろうとしていているのか、経験して後から回想するのでは余りに効率が悪い。 今回はAurora。やはり高いので個人では手が出ないのだけれど、 それなりの仕事であれば第1選択になり得る。 RDSと比較して圧倒的に高機能で運用時に困りそうなユースケースが通常の機能として既に備わっている. 参考書を1周したので、(著作権侵害にならないように)要約して自分の言葉でまとめていく。 [arst_toc tag=\"h4\"] クォーラムモデル コンピューティングリソースとストレージが分離している. コンピューティングとストレージを独立して管理する. コンピューティングリソース、ストレージ共に3AZに分散してレプリケートする. 1AZにコンピューティングリソース1台、ストレージ2台. 6台のストレージのうち2台が故障しても読み書き可. 3台が故障すると書き込みが不可となるが読み込み可. RDSはスタンバイレプリカとリードレプリカが別扱いだが Auroraはスタンバイ、リード共に共通. プライマリ、レプリカ、ストレージ(ボリューム)をセットでクラスタと呼ぶ. 可用性 読み書き可能なクラスターエンドポイント. 読み取り専用エンドポイント、任意のインスタンスにつなぐエンドポイントなどなど. クラスタ内の1台が読み書き用, 他は読み取り専用なので、読み書き用が落ちたときに読み取り専用が読み書き用に昇格する. これがフェイルオーバーの概念. クラスターエンドポイントに繋いでおくと、エンドポイント先で障害時に勝手にフェイルオーバーが発生する レプリカにはフェイルオーバー優先度をつけられる. 優先度が高い方が優先的にフェイルオーバー先になる. 同じだとインスタンスの大小で決まる. 多くの場合、フェイルオーバーの時間はRDSよりも短い. 通常、プライマリにのみキャッシュが効く. フェイルオーバーでキャッシュヒットしなくなる. クラスターキャッシュ管理をONにするとフェイルオーバー時に引き継がれる. 複数のリージョンに跨ってクォーラムモデルを配置するAuroraグローバルデータベース. DR対策. リージョン間のデータコピーは1秒未満. 複数のリージョンに跨ってクラスタを配置するクロスリージョンレプリケーション. DR対策. レプリカ間のデータコピーに時間がかかる. 通常クラスタ内の1台が読み書き可能で他は読み取り専用だが、全てを読み書き可能にできる. パフォーマンス 書き込み性能を上げるにはインスタンスサイズを上げる. Auroraレプリカはスタンバイレプリカ、リードレプリカを兼ねる. リードレプリカとして使うと読み込み性能が上がる. 読み込みエンドポイントは全ての読み込み用レプリカを代表する. アプリ側からは1個だが中は数台. Aurora AutoScaling. 読み込みクラスタのCPUまたは接続数が閾値以下になったときに自動スケールする. Aurora Serverless. インスタンス数,インスタンスサイズを自動スケールする. 未使用時に勝手に落ち,高負荷時に勝手に上がる. Aurora Serverlessは, 前提として利用頻度が少なくほとんど未使用だが、変化するときは大きく変化する、というアプリに適している. スケールアップは限界がある. つまり重量級のクエリの高速化には限界がある. スケールアウトはより柔軟なので多数のクエリの同時実行はより簡単に対応できる. セキュリティ 基本的にRDSと同様. VPC内に設置する. NACL、SGを使ってアクセス制御する. データ格納時・転送時に暗号化する. IAMロールを使ったクレデンシャルレス化. Auroraの監査機能は Advanced Auditing. 記録するクエリ種別を選択できる. CloudWatchLogsに転送可. コスト Auroraレプリカ1台ごとの稼働時間で課金. Aurora Serverlessはキャパシティユニット単位で課金. (cf.DynamoDB) RDSはインスタンスとストレージが密結合しているためストレージ容量はインスタンスに紐づく. インスタンス作成時に確保した量に課金. Auroraはストレージが分離しているためAuroraレプリカとは関係なく使った容量だけ重量課金. データを削除して未使用領域が出ると自動的に課金対象が減る. 通信はVPC外へのアウトバウンドにのみ課金. メンテナンス メンテナンスウインドウまたは即時で実行. Auroraではクラスター単位でパラメータを管理する.設定はクラスタ内のレプリカ全てに適用される. インスタンス単位のパラメータ管理もできる. ZDP(Zero Day Patch). ベストエフォートでダウンタイムなしのパッチ適用をおこなう. パッチ適用中も接続が維持される. バックアップ システムバックアップはメンテナンスウインドウで日時で行われる. データバックアップは継続的かつ増分的な自動バックアップ. 保持期間中の任意の時点へ復元できる. (PITR) データバックアップの保持期間は1日-35日. 0日(無効)には出来ない. S3に保存される. 手動でスナップショットを取得可能. システムバックアップ、データアップバック共に復元先は新しいAuroraクラスター. 保持期間の任意の時点を指定する. Auroraクローン. ストレージではなくコンピューティング部分のみをコピーする. リードレプリカ複製による読み取り性能向上. 1回でも書き込みしようとするとストレージ部分がコピーされる. データエクスポート、分析等読み込み専用のタスクに使う. Aurora MySQLでのみバックトラックを使用可能. 最大24時間前までSQL操作を遡れる. S3エクスポート. RDSはスナップショット作成操作だが, AuroraはSQLクエリ操作. モニタリング CloudWatchによるメトリクス監視. 拡張モニタリングによる詳細メトリクス監視. コンピューティングに関わる(CPU,メモリ等)をインスタンス単位のメトリクスとしてCloudWatchLogsで監視. ストレージに関わるクラスタ単位のメトリクスとしてCloudWatchLogsで監視. 監視が上手くいっているかを確認するため、障害を自力でシミュレートできる. 障害挿入クエリ. DBインスタンス,Auroraクラスタ,ディスクの障害. CloudWatchLogsよりもリアルタイム性があるデータベースアクティティストリーム. Amazon Kinesisにリアルタイムで入る. Kinesisに入ったデータストリームをElasticSearch等で可視化する. その他 Aurora MySQL. SQLからLambda関数を呼べる. Aurora MySQL. SQLからSageMakerエンドポイントを呼べる.

default eye-catch image.

RDSの機能など

参考書を1周した. 普段RDSを道具として使っているだけでは経験しない知識を得ることができた. インフラ系の仕事をしないと使わない可能性がある知識もあるが、アプリケーションエンジニアとしては、 RDSがここまでやってくれると知っていることで無駄な機能を作り込んだり、余計な心配をしなくて済む. [arst_toc tag=\"h3\"] 可用性 スケールアウトすることで何が冗長化されるのか. いざフェイルオーバーが発生したときどういう挙動になるのか. まとめ プライマリインスタンスとスタンバイレプリカを別AZに配置することで可用性を得る プライマリとスタンバイの間で常にデータ同期がおこなわれる プライマリに障害が発生した場合スタンバイにフェイルオーバーすることでDB接続を継続する スタンバイはトラフィック処理しない. 読み取り性能を上げるためにはリードレプリカを追加する スタンバイがある場合、スタンバイを対象にRDSのスナップショット取得がおこなわれ、プライマリのトラフィックに影響を与えない マルチAZの場合、スタンバイとのデータ同期によりシングル構成よりも書き込み・コミットでわずかにレイテンシが上がる AZの変更 プライマリのスナップショットを作成後、セカンダリとして復元し同期 AZ変更時はプライマリのパフォーマンスに影響する フェイルオーバー RDSの外からはエンドポイントでつなぐ プライマリに障害が発生した場合、エンドポイントの先が自動的にスタンバイにつなぎ変わる 切り替えにかかる時間は60秒-120秒. DNSキャッシュのTTLを60秒以内にしておくことが推奨されている AWSコンソールから手動でフェイルオーバー時の挙動を確認できる パフォーマンス スケールアップで何が良くなるのか。スケールアウトではどうか。 スケールアップさせることを前提にできるのか。 まとめ データベースのパフォーマンスは主にデータの読み書きのパフォーマンス 汎用SSD.3IOPS/GB. バースト(一時的に)100-10,000IOPS. プロビジョンドIOPS. 常に1,000-30,000IOPS. ストレージ容量の残量が10%以下の状態が5分以上続いた場合、5GBまたは割り当て容量の12%のどちらか大きい方が自動的に追加される 容量を頻繁に拡張できるわけではない.1度変更すると6時間変更できない. Storage Auto Scalingに頼るべきではない リードレプリカ 読み込み性能は、プライマリを複製したリードレプリカを増やすことで対応. トラフィックがリードレプリカに分散される 書き込み性能は、スケールアップにより対応 プライマリとリードレプリカの同期は非同期. 微妙に異なる. プライマリのスナップショットからリードレプリカが作成され複製される.従って作成直後は異なる リードレプリカは最大5個 プライマリとリードレプリカのインスタンスサイズは異なっていても良い 手動でリードレプリカをプライマリに昇格可能 マルチAZ可能. DR対応で別リージョンにリードレプリカを作成可能. リードレプリカのエンドポイントはそれぞれ異なる.負荷分散する場合、Route53等で1つのDNSレコード先を分散させる RDBMSごとの制約 SQLServerの場合、特定エディション以上でリードレプリカを使用可能 SQLServerの場合、マルチリージョン、マルチAZリードレプリカを作成不可 Oracleの場合、特定エディション以上でリードレプリカを使用可能 Oracleの場合、OracleのActiveDataGuargeにより同期がおこなわれる RDS Proxy アプリケーションがDBにアクセスする際、一度作成したコネクションをプーリングして使い回す機能 昔、LambdaからRDSにつなぐ際、コネクションがプールされずすぐに最大接続数を超過していたがこれで解決した RDS Proxyはプライマリインスタンスのみ対応 セキュリティ アプリケーションが個人情報の暗号化を意識する必要があるのか。RDSが透過的に面倒を見てくれるのか。 まとめ RDSを設置するVPCには少なくとも2つのサブネットが必要 VPCのACL、SGでアクセス制御する SGの送信元にはSGを指定できる.SGとSGの接続を定義できる 暗号化 データ格納時の暗号化と通信時の暗号化の2つ KMSのキーを使用して格納するデータを暗号化. KMSキーを別管理することでRDS内のデータが漏れても保護できる KMS暗号化は透過的におこなわれる. アプリケーションは特に意識しなくても良い 暗号化の対象は以下の通り DBインスタンスに格納するデータ 自動バックアップ リードレプリカ スナップショット ログファイル DBインスタンス作成時にのみ暗号化可能. 未暗号化インスタンスのスナップショットを作成して復元時に暗号化 プライマリだけ、リードレプリカだけ、のように非対称に暗号化することはできない KMSはリージョンを跨げないためリージョン間スナップショットを取る場合はコピー先のリージョンでコピー元とは異なるKMSキーを指定する必要がある SSL/TLSにより伝送中データの暗号化 AWSからルート証明書をDLしアプリケーション側でSSL/TLS通信時に取得したルート証明書を使う ルート証明書は定期的に失効する. 都度ダウンロードして更新すること IAMによるDBアクセス認証 MySQLとPostgreSQLに限り、IAMを使用したDBアクセス認証を利用できる. RDSへアクセス可能なIAMロールを作成. アプリケーション側は作成されたIAMロールを使ってRDSにアクセス アプリケーション側で接続情報を管理しなくてもよい 監査ログ DBエンジンがもつ監査ログ機能を利用できる. 監査ログはCloudWatchに転送され、管理・監視できる コスト アプリケーション側をチューニングする人的コストと、インスタンスに使うコスト。 何に料金がかかるということを把握して、アプリケーション側でやるべきこと/AWS側に振ることを意識する. まとめ RDSで発生するコストはインスタンス料金、ストレージ料金、データ通信料金 インスタンス料金 コストは1秒単位.ただし1時間未満は最低10分から. 2AZに配置した場合、リードレプリカを設置した場合、インスタンス数が2倍になるのでインスタンス料金も2倍になる DBエンジンの種類によって若干インスタンス料金が異なる.MySQL<postgreSQL<oracle 1年または3年の前払い制(リザーブドインスタンス)により割安になる.損益分岐点あり インスタンスを停止するとインスタンス料金の課金は止まる.ただし1週間止めておくと自動的に起動してしまう. ストレージ料金 インスタンスを止めていてもストレージ料金の課金は止まらない 利用中のストレージサイズと同サイズまでのバックアップには課金されない.それを超えたところから課金される.ただし超えた分は安い データ転送料金 RDSへのINは無料 RDSからVPC外部、またはインターネットへの通信は課金される. 通常VPC内部でEC2とやりとりする場合は無料だが、VPC外部とやりとりする場合注意 メンテナンス 作ったアプリが保守フェーズに移行した後、アプリケーション側は何を意識しなければならないか. まとめ AWSが実施するメンテナンスの実行時間を指定できる.(メンテナンスウインドウ) 22:00-06:00の間の30分. 大きなメンテナンスの場合1時間かかる場合がある.余裕をみて1時間設定する メンテナンスウインドウ期間中、いくつかのメンテナンスによりインスタンスが一時的にオフラインになる メンテナンス種別は「必須」と「利用可能」. 「必須」は無期限延期できない. 「利用可能」はできる. アプリケーションの動作に影響がありそうなものは開発環境で事前に検証すること マルチAZのメンテナンス まずスタンバイについてメンテナンスを実行 スタンバイをプライマリに昇格. 降格した元プライマリにメンテナンスを実行.そのままスタンバイになる 全体としてインスタンスがオフラインになることがない. ストレージ追加、インスタンスタイプの変更は任意またはメンテナンスウインドウ DBエンジンのアップグレード メジャーバージョンアップはユーザ自身が実施 マイナーバージョンアップは設定次第で自動でやってくれる. 手動でも可. パラメータグループ 設定値(パラメータ)のグループ. 例えばMySQLのconfに書くような設定値が集まったもの. DBエンジンごとに様々なパラメータが存在する デフォルトパラメータグループ ユーザは変更できない. ユーザが独自のパラメータグループを作成しデフォルトパラメータをオーバーライド すぐに適用される「動的パラメータグループ」.再起動が必要な「静的パラメータグループ」 追加設定はオプショングループ.デフォルトのパラメータは変更できず,ユーザが作成してオーバーライド バックアップ これも, 保守フェーズに移行した後アプリケーション側で何を意識しないといけないか. 自動バックアップと手動バックアップ 自動バックアップ 自動的にスナップショットを保存. 保存日数はデフォルト7日.0(無効)-35日. スナップショットは不可視のS3に保存される. 初回のスナップショットはフル. 2回目以降は差分. バックアップはメンテナンスウインドウで作成される. シングルAZの場合一時的にオフラインになる. マルチAZの場合オフラインにならない 手動バックアップ 任意のタイミングでバックアップできる. 手動バックアップは自動的に削除されない. DR目的で別リージョンへのスナップショットコピー 別リージョンに手動でスナップショットをコピーできる 暗号化用KMSキー、オプショングループは自動でコピーされないので自力でコピー先に作る 別アカウントとスナップショット共有 手動バックアップしたスナップショットを別アカウントと共有できる 暗号化済みの場合、KMSキーを共有先にアクセス許可する 暗号化していない場合、格納された個人情報にアクセス可能となる スナップショットの復元 既存のRDSインスタンスに復元できない.新しいRDSインスタンスを復元する エンドポイントが変わるのでアプリケーション側の再設定が必要 パラメータグループはインスタンスに紐づくため復元時に復元元のパラメータグループを使用する PITR(ポイントインタイムリカバリ) スナップショットとは別にトランザクションログがS3に5分単位で保存される スナップショット復元と合わせて最短で5分前までの状態に復元が可能. S3へのエクスポート スナップショットからS3にエクスポートできる 不可視のS3ではなく、Amazon Parquet形式でS3バケットにデータをエクスポートできる Athena、Redshift等別サービスからS3上のファイルを検索、分析できる モニタリング 作ったアプリがショボすぎて速度が出ない! ピンチを救うAWSの機能. 保守フェーズ移行, 劣化やユーザ数増加により受けた影響の調査. 他. インスタンスが効率的に使われているかを調べるためにリソース使用状況を監視できる CloudWatchにメトリクスが展開される. CloudWatchAlarmによりメトリクスの変化に伴ってSNS通知などアクションを実行できる DBエンジンが出力するログはCloudWatchLogsに転送できる ログに含まれる特定のエラー文字列を見つけてSNS通知するなどのユースケース 拡張モニタリングにより詳細なリソースデータを監視できる. パフォーマンスインサイト. パフォーマンスに関するデータを可視化する. ユーザ自身が可視化ツールを用意しなくてもある程度は確認できる スロークエリ、実行計画の確認などができる. パフォーマンスチューニングの初手に使える フェイルオーバーや再起動などをトリガーとしてSNS通知できる

default eye-catch image.

ansibleでaws-cliをインストールする (+S3)

やりたいことは以下の2つ。 ansibleでaws-cliをインストールする ansibleでインストールしたaws-cliでs3コマンドを打てるようにする なお、相手には既にpipがインストールがしてあるものとします。 ansibleを実行するために最小構成でPythonをインストールしたもののpipは入れていない、 という状況であれば、先にpipをインストールする必要があります。 リージョン、S3のkey,secretは仮に以下とします。 事前にAWSのコンソールで設定,取得してください。 region: ap-northeast-1 s3.key: AHJKOKODAJOIFAJDJDIOA s3.secret: AugioaiARJOIfjop20FJIOADOiFJAODA ファイル達 構成は以下の通りです。(※)のファイルが核心です。 stagingとかになってますが、もちろん成立する範囲で修正してください。 ├──provision.yml (※) ├──ansible.cfg ├──group_vars │ └───staging.yml (※) ├──hosts | └───staging ├──host_vars | └───default.yml └──roles └─awscli (※) ├─templates | └─config.conf.j2 | └─credentials.conf.j2 └─tasks └─main.yml group_vars/staging.ymlに設定を書きます。 user: ubuntu s3: region: ap-northeast-1 # S3.region key: AHJKOKODAJOIFAJDJDIOA # S3.key secret: AugioaiARJOIfjop20FJIOADOiFJAODA # S3.secret roles/awscli/templates/config.conf.j2にaws-cliの設定を書きます。 s3.regionが評価され値が入ります。相手の~/.aws/configに配置します。 [default] output = json region = {{s3.region}} roles/awscli/templates/credentials.conf.j2にs3の設定を書きます。 s3.keyとs3.secretが評価され値が入ります。相手の~/.aws/credentialsに配置します。 [default] aws_access_key_id = {{s3.key}} aws_secret_access_key = {{s3.secret}} rokes/awscli/tasks/main.ymlに状態を定義します。 内容は以下の通りです。 1) aws-cliがpip installされた状態 2) ~/.aws/以下に設定ファイルがコピーされた状態 --- - name: install aws-cli pip: name: awscli - name: create .aws dir file: dest: /home/{{user}}/.aws state: directory owner: \"{{user}}\" group: \"{{user}}\" - name: copy config template: src: config.conf.j2 dest: /home/{{user}}/.aws/config owner: \"{{user}}\" group: \"{{user}}\" - name: copy credential template: src: credential.conf.j2 dest: /home/{{user}}/.aws/credentials owner: \"{{user}}\" group: \"{{user}}\" ~ ~ Playbook(provision.yml)は以下の通りです。 - hosts: remote_machine remote_user: \"{{ user }}\" gather_facts: \"{{ check_env | default(True) }}\" become: yes become_method: sudo roles: - { role: awscli } 実行結果 Playbookを実行します。 $ ansible-playbook -i hosts/staging provisiong.yml 相手のユーザディレクトリに.awsというディレクトリが作られ、中にファイルが作られます。 ~/ └─.aws ├─config └─credentials 相手側でaws s3 lsコマンドを打って設定しろと言われなければ成功です。 $ aws s3 ls 2019-10-20 11:11:20 hogehoge おわり。

default eye-catch image.

稼働中のEC2のコピーを作成してALB下で切り替えた話 WordPress Update Blue Green

稼働中のEC2を落とさないでALB下で切り替えた作業記録を書いてみます。 こちら↓の方が詳しく書いてあります..。今回書いた記事の特徴は以下となります。 AutoScalingグループを使わない ALBの下で切り替える deploy手順をAWSの外に用意する [clink implicit=\"false\" url=\"https://qiita.com/keitakn/items/6abe6c971e4dec3b69ef\" imgurl=\"https://camo.qiitausercontent.com/08bed869c98443e0474ce8ce78bdbe964a09f1e9/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f37313839392f62303437313164612d623035362d313262662d646164612d3439653930333231663366342e6a706567\" title=\"AWS CodeDeploy でEC2のBlue/Greenデプロイを作成する\" excerpt=\"AWS CodeDeploy を使ってBlue/Green デプロイの仕組みを構築する為の手順を紹介します。Blue/Greenデプロイとは?現在稼働している環境と別にもう1つ稼働環境を作成し、ロードバランサー等のルーティングを新環境に向けるデプロイ方法です。常にリクエストを受けている稼働中のサーバを置き換えるよりも安全にデプロイ可能なのがメリットになります。\"] [arst_adsense slotnumber=\"1\"] 現状と動機 WPCoreアプデとセキュリティパッチはマメに当てないといけないと痛感して、 仕方なくBlue Green的な方法を導入してみた。 ALBの下にWebサーバ1台。Webサーバの下にDB用EC2が1台(非RDS)。 アップデート対象はWebサーバのみ。 Webサーバ内でWordPressが12個、SNIで動いてる。 x.smallクラス。CloudWatchを見るとLoadAverageは常時30%くらい。 全てのサイトで、pluginでファイルとDBをS3にバックアップしている。 localで開発/WPCore,plugin update/動作確認後、止めずにansibleでdeploy。 deploy実行前に\"メンテナンス中\"に設定。deploy完了後に解除する。 アップデート中は管理画面操作禁止を通達。 deploy、パッチ当てでコケると、S3から戻すまで止まる! S3から戻らないと終わる。 やったこと deploy、アップデート時にのみ、WebサーバのEC2をコピーする。 ALBのターゲットグループにコピーしたEC2を追加する。 元のEC2に対してansibleでdeployする。 元のEC2に対してパッチアップデートする。 ALBの先を元のEC2に戻す。 コピーしたEC2を削除する。 メディアライブラリにファイルをアップロードすると差分が発生するため、 元EC2と一時EC2のファイル達を同期させないといけないけれど、 メンテ中は、管理画面操作を禁止できるという状況であることと、 もともとEC2が1台なのでその仕組みを作っていないから、それは2台以上に増えたときに..。 AMI作成 まずAMIを作成。AMIとはAmazon Machine Imageの頭文字。 [clink implicit=\"false\" url=\"https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instances-and-amis.html\" imgurl=\"https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/images/architecture_ami_instance.png\" title=\"インスタンスと AMI\" excerpt=\"Amazon マシンイメージ (AMI) は、ソフトウェア構成 (オペレーティングシステム、アプリケーションサーバー、アプリケーションなど) を記録したテンプレートです。AMI から、クラウドで仮想サーバーとして実行される AMI のコピーであるインスタンスを起動します。以下の図に示すように、1 つの AMI の複数のインスタンスを起動することができます。\"] 手順は以下。 ダッシュボードからコピーしたいインスタンスを選択 アクション->イメージ->イメージの作成を選択 デフォルトだと、AMI作成時にコピー元インスタンスが自動的に停止し、コピー後に自動的に再起動する。 \"再起動しない\"にチェックをいれることで、コピー元インスタンスの停止/再起動を抑止できる。 \"再起動しない\"にチェックをいれないでAMIを作成すると、コピー元が止まってしまうので注意! イメージの作成を押下すると、作成処理が始まる。 EBSが30GiBだと、完了まで1時間程度要してしまった。 ダッシュボード -> AMI から AMIの作成状況を確認できる。 ステータスが available になれば完了。 インスタンスの起動 作成済みAMIからインスタンスを起動する。 ダッシュボード -> AMI を開く 起動したいAMIを選択する アクション -> 起動を押下 すると、インスタンスタイプを聞かれる。 進捗状況はEC2ダッシュボードで確認できる。 ALBのターゲットグループ変更 既にALBのターゲットグループに元EC2が属していて、 セキュリティグループが正しく設定済みで、ヘルスチェックが通っている前提。 現状、ALBの下は元EC2だけなので、AvailabilityZoneは1種類だけ。 ダッシュボード -> ターゲットグループ そこに、新しく作成したインスタンスを追加する。 新しいインスタンスのセキュリティグループを旧インスタンスに合わせて ALBからのInboundを受けられるようにすること。 新しいインスタンスのヘルスチェックが無事通って2台構成になった図。 元のEC2をターゲットグループから削除 元のEC2をターゲットグループから削除する。 EC2ダッシュボードのモニタリングタブをみて、CPU使用率などに変動があることを確認する。 元のEC2に対してゴニョゴニョする ALBのターゲットグループから外れた元のEC2に対してdeployなりパッチ当てを実行する。 元のEC2にElasticIPを当てておけば、再起動してもIPアドレスは変わらない。 この手順においては、新規作成したEC2にElasticIPを当てる必要はない。 元のEC2のセキュリティグループを0.0.0.0/0:80からアクセスできるようにして、 hostsにElasticIPを書いてアクセスするなどの方法で、元のEC2にアクセスする。 このためだけにALBを作って置いておくとそのALBに対して課金されてしまう。 新規作成したEC2を無料枠でやったりしてスペックが低いとパフォーマンスが下がる。 非稼働のEC2に当てたElasticIPで課金される。 一時EC2をターゲットグループから外し、元のEC2を投入する 上の手順を逆から実施。つまり、一時EC2をターゲットグループから外し、元のEC2を投入する。 [arst_adsense slotnumber=\"1\"]

default eye-catch image.

AWS常時SSL リダイレクトループしない.htaccessの書き方

HTTPSを強制するために .htaccess に細工をするのは有名。例えば以下のような書き方が王道。 RewriteEngine on RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L] これをそのままElasticBeanstalkにデプロイするとリダイレクトループが発生する。正確に書くとリバースプロキシ(ロードバランサ)が有効になっている場合にリダイレクトループが発生する。 原因 原因についてはココが詳しい。ざっくりまとめると、 ロードバランサが443へのアクセスを80へのアクセスに変換する .htaccess内の RewriteCond ${HTTPS} が永遠に on にならず、リダイレクトの度にRewriteRule が走ってしまう 元々のアクセスが https か http のどちらかが分かれば良いのだが、上記の挙動のせいで、https にリダイレクトしたとしても http からアクセスされたことになり、これが永遠に繰り返されてしまう。 解決策 (記事主さんが)無茶苦茶泥臭く挙動を追跡したところ、ロードバランサに到着した元のアクセスが http のときに限り、X-Forwarded-Proto というヘッダが付与され値が入るらしい。なので、X-Forwarded-Protoヘッダの内容を http か https かの判断基準にすれば良い、というのが基本的なアイデア。本人も言っているが、it\'s just an empiric result... である。 その .htaccess が以下 RewriteEngine On # Force HTTPS RewriteCond %{HTTP:X-Forwarded-Proto} !=https RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R,L] これを ElasticBeanstalkにデプロイすると見事に動作する。 [arst_adsense slotnumber=\"1\"] 開発環境との共存 開発もAWSで行っていればこれで良いのだがそうでない場合も多いと思う。 上記のAWS用.htaccessを非AWSな開発環境に持ってくると今度は RewriteCond %{HTTP:X-Forwarded-Proto} !https が常に真になり、リダイレクトループが発生する。 あっちが立てばこっちが立たない! いろいろ試行錯誤した結果、以下なら両立できた。(2017/7/8訂正) RewriteEngine On # Force HTTPS RewriteCond %{HTTPS} !=on RewriteCond %{HTTP:X-Forwarded-Proto} !=https RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R,L] 根拠となる X-Forwarded-Proto がとっても経験的!なので、いつの日か使えなくなる日が来るかもしれない。 [arst_adsense slotnumber=\"1\"]

default eye-catch image.

無料でSSL/TLC証明書を手に入れる EC2/ElasticBeanstalk編

Certbotを使って Conoha+Kusanagi(nginx/centos7) に無料でSSL/TLC証明書をインストール・自動更新する方法は過去に書いた。\"無料でSSL/TLC証明書を手に入れる\" CertbotサイトにOSとWebサーバの組み合わせを入力すると対応するインストール手順が表示される。メジャーな組み合わせであれば証明書の取得から自動更新まで全自動でやってくれる。 2016年7月現在、AWS(EC2)は未対応のため、Certbotツールを使って試行錯誤する必要がある。Certbotの一次情報をもとに何とかやってみたので記録を残しておく。 AWS(EC2)にCertbotでSSL/TLC証明書をインストールする ElasticBeanstalkのロードバランサに取得した証明書を登録しhttpsでアクセスできるようにする 自動更新のセットアップを行う AWS(EC2)にCertbotを使ってSSL/TLC証明書をインストールする いくつか前提がある。 ドメインは取得済みであること。 ドメインがElasticBeanstalkのIPアドレスを指すようにRoute53を設定済みであること。 EC2インスタンスにSSHでログインできるようにしておく。 Certbot利用時、外部からEC2インスタンスにhttpでアクセスを受ける。ElasticBeanstalkにRoutingを変更するようなアプリがデプロイされているとアクセスが失敗するのでDocumentRootにindex.phpがあるだけという状態にしておく。 SSL/TLC証明書をインストールするだけなら443番を開けておく必要はない。ロードバランサはデフォルトの80番だけ開けていれば良い EC2インスタンスのrootパスワードが設定済みであること AWS CLIがインストール済みであること。 IAMで証明書登録ポリシーを付与済みであること。 さっそくEC2インスタンスにログイン。基本的にec2-userで作業する。 一応下記を実行。 $ sudo yum install epel-release Loaded plugins: priorities, update-motd, upgrade-helper Package epel-release-6-8.9.amzn1.noarch already installed and latest version Nothing to do Certbotをダウンロードする。 $ wget https://dl.eff.org/certbot-auto $ chmod a+x certbot-auto Certbotを実行してみる。その際、--debugオプションを付けないと怒られる。would like to work on improving it と言っておきながら --debug がmust。きっと実行内容がCertbotに送られるのだろう。 $ ./certbot-auto WARNING: Amazon Linux support is very experimental at present... if you would like to work on improving it, please ensure you have backups and then run this script again with the --debug flag! 指示通り、--debugオプションを付けて実行してみる。 $ ./certbot-auto --debug ... Installed: augeas-libs.x86_64 0:1.0.0-5.7.amzn1 dialog.x86_64 0:1.1-9.20080819.1.5.amzn1 libffi-devel.x86_64 0:3.0.13-11.4.amzn1 python27-tools.x86_64 0:2.7.10-4.120.amzn1 system-rpm-config.noarch 0:9.0.3-42.27.amzn1 Complete! Creating virtual environment... Installing Python packages... Installation succeeded. Requesting root privileges to run certbot... /home/ec2-user/.local/share/letsencrypt/bin/letsencrypt --debug Version: 1.1-20080819 Version: 1.1-20080819 No installers are available on your OS yet; try running \"letsencrypt-auto certonly\" to get a cert you can install manually いろいろインストールされる。/home/ec2-user/.local/share/letsencrypt/ 以下にPython27 が入る。今回の試行錯誤では自力でPythonを上げなかった。たぶん、自力でPythonのバージョンを上げなくてもコレが使われるんじゃないか。 肝心のインストーラはインストールされず、\"letsencrypt-auto certonly\"というコマンドを実行せよ、と出る。が、これはtypo。 No installers are available on your OS yet; try running \"letsencrypt-auto certonly\" to get a cert you can install manually ディレクトリを移動する。 $ cd /home/ec2-user/.local/share/letsencrypt/bin ここにある certbot コマンドを叩く。ドメイン名、メールアドレスを指定する。 sudo ./certbot certonly -d hoge.com --agree-tos -m hoge@hoge.com --debug すると、中途半端にグラフィカルな画面が表示される。簡易Webサーバを起動するか、現在のWebサーバのDocumentRootを教えるか、2択となる。簡易Webサーバだとどうしても上手くいかなかった。Webサーバを上げたまま(ElasticBeanstalkのヘルスチェックがOKの状態)、DocumentRootを指定すると上手くいった。 うまくいくと、以下のようなメッセージが表示される。 IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/arst.me/fullchain.pem. Your cert will expire on 2016-09-29. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run \"certbot renew\" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let\'s Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le /etc/letsencrypt/live に証明書が作られている。なお、live には ec2-user でアクセスできない。ここでrootに昇格。 $ su - # cd /etc/letsencrypt/live # ls hoge.com # cd hoge.com # ls cert.pem chain.pem fullchain.pem privkey.pem ElasticBeanstalkのロードバランサに証明書を登録する AWS CLI経由で証明書を登録する。その際、IAMにてポリシーを追加しておく必要がある。過去エントリを参照のこと。成功するとJSONで登録情報が返る。ここでは、HogeCertification という名前で登録を行っている。 $ aws iam upload-server-certificate --server-certificate-name HogeCertification --certificate-body file://cert.pem --private-key file://privkey.pem { \"ServerCertificateMetadata\": { \"ServerCertificateId\": \"ASCAI***********A6F5GI\", \"ServerCertificateName\": \"HogeCertification\", \"Expiration\": \"2016-09-29T01:57:00Z\", \"Path\": \"/\", \"Arn\": \"arn:aws:iam::281631559249:server-certificate/HogeCertification\", \"UploadDate\": \"2016-07-01T03:10:18.440Z\" } } ElasticBeanstalkのロードバランサの設定で、証明書欄から HogeCertification を選べるようになる。選んで 443/HTTPS を通すようにすれば、晴れて https://独自ドメイン/ で ElasticBeanstalk の URL が開く。 証明書の自動更新 更新自体はcertbot renewコマンドで行う。certbot renewコマンドは/var/www/html/.well-known/以下にファイルを置いて外部から開きにくる。困ったことに、CakePHPやLaravelアプリをデプロイしているとフレームワークのルーティング機能により上手くいかない。 以下の戦略で対応する。 certbot renew 時だけ、DocumentRoot を アプリ用からcertbot用に切り替える Laravel等のように DocumentRoot がサブディレクトリにオフセットされている場合に対応する ElasticBeanstalkで自動生成される環境を見ると、/var/www/html が /var/app/current へのシンボリックリンクとなっている。Certbot renew を叩くときだけ、シンボリックリンクを差し替える。 $ cd /var/app $ sudo mkdir -p certbot/project/public $ sudo chown -R webapp:webapp certbot $ cd /var/www $ sudo ln -s -f /var/app/certbot html また、certbot用の.well-knownディレクトリが /var/www/html 直下に作られる仕様になっている。DocumentRootはさらに project/public にオフセットされているため、/var/www/html/project/public/.well-known が /var/www/html/.well-known を指すようにシンボリックリンクを作成する。 $ cd /var/app/certbot/project/public $ sudo ln -s ../../.well-known この状態で certbot renew --dry-run を叩くと無事成功する。 $ pwd /home/ec2-user/.local/share/letsencrypt/bin $ sudo certbot renew --dry-run ** DRY RUN: simulating \'certbot renew\' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/ikuty.com/fullchain.pem (success) ** DRY RUN: simulating \'certbot renew\' close to cert expiry ** (The test certificates above have not been saved.) シンボリックリンクの作成は一度だけで良いが、アプリ用とCertbot用のシンボリックリンク張替は都度必要となる。 以下のシェルスクリプトをcronで叩けば良い。 #!/bin/bash cd /var/www sudo unlink html sudo ln -s -f /var/app/certbot html cd ~ pwd sudo ./.local/share/letsencrypt/bin/certbot renew --debug cd /var/www sudo unlink /var/www/html sudo ln -s -f /var/app/current html 不要な更新は実行されないため、1日2回の頻度で実行してよい旨、ドキュメントに記述がある。 Note: if you’re setting up a cron or systemd job, we recommend running it twice per day (it won’t do anything until your certificates are due for renewal or revoked, but running it regularly would give your site a chance of staying online in case a Let’s Encrypt-initiated revocation happened for some reason). Please select a random minute within the hour for your renewal tasks.

default eye-catch image.

VPC内にElastic Beanstalk + RDS の環境を構築して Laravel アプリをデプロイする [Laravel5アプリデプロイ編]

今後も何度か同じことを調べそうなので忘備録としてまとめておく。手順をstep by stepで記述するが、それぞれ分量が多いので以下の通り章立てを行ってエントリを分割する。 VPC構築編 VPCの作成 VPC、NetworkACL、SecurityGroupの確認、タグ付け VPCのDNSホスト名を有効にする サブネットの作成、タグ付け インターネットゲートウェイの作成、タグ付け、VPCにアタッチ パブリックサブネット用RoutingTableの作成 パブリックサブネット用RoutingTableにインターネットゲートウェイの関連付け 作成したサブネットをパブリックサブネット用RoutingTableに繋ぎかえる RDS構築編 MySQLの設定変更(DBパラメータグループの作成) DBサブネットグループを作成 RDS用セキュリティグループの作成 RDSインスタンスの作成 エンドポイントの確認、疎通確認 Elastic Beanstalk構築編 環境の構築 .ebextensionsによるカスタマイズ Laravel5アプリデプロイ編(本エントリ) gitリポジトリからclone .envの編集 アプリで使うDBのダンプファイルをRDSにコピー Laravelインストーラの準備 Laravel本体のインストール ビルトインサーバでの疎通確認 Elastic Beanstalkへのデプロイ gitリポジトリからclone 通常 Laravel5 にはデフォルトの .gitignore が作られており、Laravel本体は.gitignoreに登録されている。まず、アプリをcloneし、そのあとでLaravel本体をインストールする。 どこか、Laravel5の要件を満たすところでgitリポジトリからcloneする。 $ pwd /home/ikuty/www/ $ git clone ssh://servername/var/git/project.git project .envの編集 アプリケーションの設定を変更する。/config 内に各種設定ファイルが配置されているが、laravelでは.envを変更することで /config内のenv()関数に展開される仕組みになっている。だから、/config 内の各種ファイルを直接変更する必要はない。/config 内も git の構成管理に含めても良い。 cloneした先でenvを編集する。.env_example をリネームすると楽。 APP_KEY= *** 次項で示すようにキーを生成する DB_HOST : RDS編で設定したRDSエンドポイントを指定する DB_DATABASE, USERNAME, PASSWORD : RDS編で設定した各種設定を指定する APP_ENV=local APP_DEBUG=true APP_KEY=**** APP_URL=http://hoge.com/ DB_CONNECTION=mysql DB_HOST=rds-endpoint DB_PORT=3306 DB_DATABASE=hogedb DB_USERNAME=hoge DB_PASSWORD=fuga CACHE_DRIVER=file SESSION_DRIVER=file QUEUE_DRIVER=sync キーを生成する。以下のコマンドで .env の APP_KEY が差し替わる。 $ php artisan key:generate アプリで使うDBのダンプファイルをRDSにコピー 本来は Migration を使うべきだが...。Migration を利用しないでDBを作ってしまった場合は泥臭くやる...;;まず、ダンプ。 $ mysqldump -u hoge -p appdb > appdb.sql RDS側にDBを作成し権限を付与しておく。 $ mysql -h [rds-endpoint] -u hoge -p $ > CREATE DATABSE appdb; $ > GRANT ALL ON appdb.* to hoge@localhost; $ > FLUSH PRIVILEGES; $ > SHOW DATABSES; $ > ... RDS上のDBにダンプしたsqlを流し込む。 $ mysql -h [rds-endpoint] -u hoge -p -D appdb < appdb.sql Laravelインストーラの準備 composerを利用する。パスを通す。本エントリ作成時の最新は version1.3.3。 $ composer global require \"laravel/installer=~1.1\" $ echo \'export PATH=~/.composer/vendor/laravel/installer:$PATH\' >> ~/.bash_profile $ source .bash_profile $ laravel Laravel Installer version 1.3.3 Laravel本体のインストール composerが準備できたらcomposer installでLaravel本体をインストールする。 $ cd project $ composer install ビルトインサーバでの疎通確認 この状態でビルトインサーバを立ち上げ、疎通確認を行う。 $ cd project php artisan serve --host hoge.com Laravel development server started on http://hoge.com:8000/ Elastic Beanstalkへのデプロイ Elastic Beanstalk構築編にて、環境の準備が出来ているものとする。 eb deploy コマンドにより、カレントディレクトリ以下のファイルをデプロイする。また、.ebextension に DocumentRoot を設定する。カレントディレクトリと DocumentRoot の組み合わせを正しく設定する必要がある。 まず、DocumentRootを設定するため、.ebextensionディレクトリを作成し、設定ファイルを作成する。 $ pwd /home/ikuty/www/ $ mkdir .ebextensions $ cd .ebextensions $ vi 01_documentroot.config 01.documentroot_config は以下の通り。YAMLとして記述する必要がある。空白とタブの扱いがシビアなので、タブが入らないように注意する。ファイルの先頭の\"01\" は、ファイルが解釈される順番を表す。.ebextensions 内に、01,02,... のように設定を複数配置できる。 option_settings: - namespace: aws:elasticbeanstalk:container:php:phpini option_name: document_root value: /project/public DocumentRoot を /project/public と設定した場合に正しい構成になるように、カレントディレクトリを移動し、eb deployを実行する。~/www に移動して、/project 以下をデプロイすれば良い。 $ cd ~/www/ $ eb deploy Creating application version archive \"app-160630_130423\". Uploading: [##################################################] 100% Done... INFO: Environment update is starting. INFO: Deploying new version to instance(s). INFO: New application version was deployed to running EC2 instances. INFO: Environment update completed successfully. 設定が正しければ2分弱で完了する。

default eye-catch image.

VPC内にElastic Beanstalk + RDS の環境を構築して Laravel アプリをデプロイする [ElasticBeanstalk構築編]

今後も何度か同じことを調べそうなので忘備録としてまとめておく。手順をstep by stepで記述するが、それぞれ分量が多いので以下の通り章立てを行ってエントリを分割する。 VPC構築編 VPCの作成 VPC、NetworkACL、SecurityGroupの確認、タグ付け VPCのDNSホスト名を有効にする サブネットの作成、タグ付け インターネットゲートウェイの作成、タグ付け、VPCにアタッチ パブリックサブネット用RoutingTableの作成 パブリックサブネット用RoutingTableにインターネットゲートウェイの関連付け 作成したサブネットをパブリックサブネット用RoutingTableに繋ぎかえる RDS構築編 MySQLの設定変更(DBパラメータグループの作成) DBサブネットグループを作成 RDS用セキュリティグループの作成 RDSインスタンスの作成 エンドポイントの確認、疎通確認 Elastic Beanstalk構築編(本エントリ) 環境の構築 .ebextensionsによるカスタマイズ Laravel5アプリデプロイ編 gitリポジトリからclone .envの編集 アプリで使うDBのダンプファイルをRDSにコピー Laravelインストーラの準備 Laravel本体のインストール ビルトインサーバでの疎通確認 Elastic Beanstalkへのデプロイ 環境の構築 Elastic Beanstalk の各インスタンスを収める「環境」を作成する。この「環境」の中に、これまで作ってきたVPCの要素を追加する。 $ eb create hoge-production --sample # アプリケーションのデプロイは後で行う。今はSampleアプリケーションをデプロイ --cname com-sample-production --instance_type t2.micro --region ap-northeast-1 --tier webserver --vpc.ec2subnets subnet-b71eeac1 #VPCに作成したパブリックサブネット --vpc.elbsubnets subnet-b71eeac1 #VPCに作成したパブリックサブネット(同じにする) --vpc.id vpc-cc2b11a9 --vpc.securitygroups sg-23fe8447 #デフォルトセキュリティグループ --vpc.publicip --vpc.elbpublic 3分から5分程度時間を要する。 作成した環境のURLを開く $eb open http://com-sample-production.ap-northeast-1.elasticbeanstalk.com/ .ebextensionsによるカスタマイズ Laravel5アプリケーションをデプロイするにあたって、環境をカスタマイズする。(qiitaを参考にした) $ pwd /home/ikuty/www $ mkdir .ebextensions $ cd .ebextensions # timezoneを変更する vi 01_settimezone.config 各ファイルは以下の通り。なお、各ファイルは yaml形式であり、空白とタブの扱いがシビア。タブでインデントすると簡単に謎のエラーに悩まされる。空文字はタブではなく半角スペース。 01_settimezone.config command: 01-set_timezone: command: cp /usr/share/zoneinfo/Japan /etc/localtime