20201126のAWSに関する記事は21件です。

serverless framework DE typescript for AWS Lambda開発

既に作ったserverlessプロジェクトにTypescriptを入れたい

現在AWSでSlack Botを動かすために、開発環境を作れるserverless絶賛勉強中です。
プロジェクトを作る時にtypescript対応するのは見つかったのですが、
もう作っちゃったプロジェクトに追加する方法は見当たらなかったのでまとめます。

プロジェクト作成時の場合はcreateするときに-t aws-nodejs-typescriptというテンプレートを指定すればいいらしい。次はそっちでやってみます。
参考:ServerlessでTypeScriptの開発環境を作る

serverlessプラグインを追加

https://www.serverless.com/plugins/serverless-plugin-typescript/
serverless-plugin-typescriptという素敵なプラグインを見つけたので使います。

Features
・Zero-config: Works out of the box without the need to install any other compiler or plugins
・Supports ES2015 syntax + features (export, import, async, await, Promise, ...)
・Supports sls package, sls deploy and sls deploy function
・Supports sls invoke local + --watch mode
・Integrates nicely with serverless-offline

ローカル環境構築に使うserverless-offlineとの連携に自信ありとのことで、良いですね。
実際この後serverless-offlineも導入しましたが大体問題なく変換されています。

インストール

npm install -D serverless-plugin-typescript typescript

した後に、お約束のserverless.ymlのpluginsに下記を追加

plugins:
  - serverless-plugin-typescript

tsconfig.json

minimum exampleを見る限り、デフォルトで良ければtsconfig.json作らなくても動くっぽい。

tsconfig.json
{
  "compilerOptions": {
    "preserveConstEnums": true,
    "strictNullChecks": true,
    "sourceMap": true,
    "allowJs": true,
    "target": "es5",
    "outDir": ".build",
    "moduleResolution": "node",
    "lib": ["es2015"],
    "rootDir": "./"
  }
}

これがデフォルトで、outDirrootDir以外は上書きしていいよ!とのことです。
私はTypescript、細かいとこまで気が付くデキるやつだなぁ…くらいのノリで使ってるので、今のところ特に何も変更してません。

あとはsls deploy時に勝手にトランスパイルしてくれます。
(ディレクトリ含むファイル分割しても勝手に上手いことしてくれるのかはこれから検証…)

serverless-offlineと使う

時はserverless-plugin-typescriptが先に来るようにserverless.ymlに記述しないとダメらしいです。

serverless.yml
  plugins:
    ...
    - serverless-plugin-typescript
    ...
    - serverless-offline
    ...

serverless-dynamodb-localを使う時もなんか順番があるみたいですが、私はまだ使ってないのでよくわかりません。各自ご確認ください

aws-sdkの型定義ファイルを使う

他で使われていたので@types/aws-sdkというパッケージを見に行ったら、もう公式が提供してるから使わなくていいよと言われてしまったので公式を見に行きます。

https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/#Usage_with_TypeScript
まずは、というか実際@types/nodeをインストールするだけです。

npm install --save-dev @types/node

あとは.tsファイルからの読み込みを書き換えて完了!

import AWS from 'aws-sdk';

なぜかSlack Botが動かなくなった…

動かなくなりました。公式の言う通りimportした後、こんな感じでAWSオブジェクトの中のLambdaメソッドを呼び出していたのですが、
Lambdaはundifinedを参照していますみたいなエラーが出て、なぜかAWSの中身がからっぽということに…どうして、さっきまでこれで動いていたのに。

handler.ts
import AWS from 'aws-sdk';
const lambda = new AWS.Lambda()

serverless-offlineを使うと?distフォルダにコンパイル後のjsファイルが生成されているので、そこを見てみるとこんなことになってました。
勝手に入ってきた.default君、何?

handler.js
var aws_sdk_1 = require("aws-sdk");
var lambda = new aws_sdk_1.default.Lambda();

.default君がどこから何のために来たのか全然分からないんですが、とりあえずimport時に直接Lambdaメソッドを分割代入したら無事動いてくれました。

handler.ts
import { Lambda } from 'aws-sdk';
const lambda = new Lambda()

型定義を付けた値にserverless.ymlの環境変数を入れる時の注意

Lambda.invoke()に渡すパラメーターを設定する変数に型定義AWS.Lambda.InvocationRequestを付けた時のことです。

  const params: AWS.Lambda.InvocationRequest = {
    FunctionName: process.env.INVOKE_FUNCTION,
    InvocationType: "RequestResponse",
    Payload: JSON.stringify({ msg: "Hello" }),
  };

process.env.INVOKE_FUNCTIONのとこで下記のような、エラーがコンソールに湧き出ました。

api-lambda.ts (13,17): Argument of type '{ FunctionName: string | undefined; InvocationType: string; Payload: string; }' is not assignable to parameter of type 'InvocationRequest'.
  Types of property 'FunctionName' are incompatible.
    Type 'string | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.

ちなみにinvokeする関数のFunctionNameは、serverless.ymlで定義している「サービス名-ステージ名-functionsで定義した関数名」で生成されるので、serverless.ymlでファイル内参照しながら書く方が楽なんですよね。こんな感じで。
"${self:service}-${self:provider.stage}-<functions内で定義した関数名>"

まぁそれはともかく、エラーは「string型で定義したところに'string | undefined'の値は入れられません」とか言ってます。
どうやら.yml内から持ってきた値はtypescriptの方で中身がある無しを判断できないので自動的に'string | undefined'型と判定されるようです。

しかしそんなときの為にTypescriptさんが解決策を用意してくれていました

  const params: AWS.Lambda.InvocationRequest = {
    FunctionName: process.env.INVOKE_FUNCTION!,
    ...
  };

これで解決です。!つけるだけ。
Non-null assertion operator
要するにこれは末尾に付けた変数がnullでもundefinedでもありませんよというのを明示的に指定できる演算子のようです。

?を付ければOptional chaining

そういえば?をオブジェクトの末尾に付けると、途中でundifinedの中身を参照しようとしてもエラーを出さずにnullが帰ってくるというめちゃくちゃ良い感じの機能がありますね。
slackのレスポンスはオブジェクトがネストしてることも多いので、私が今のところそこまでよく分かってないtypescriptを入れたい理由の一つです。
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining

以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS EC2でサーバー構築①

概要

簡単にAWSでサーバー構築をしてアプリケーションをデプロイさせる
今回は ネットワークの構築 まで進めようと思います!

リージョンの変更

右上のリージョンから アジアパシフィック (東京) ap-northeast-1

VPC領域の作成

VPC とは(Virtual Private Cloud)の略
VPC を作成すると ユーザー毎に隔離されたネットワーク空間が作れます

AWS上のVPC領域はプレフィックス長が16以上を指定する必要があるので
CIDR ブロックは 10.0.0.0/16 にする必要がある

トップ画面 から 「VPC」 を選択
「名前タグ-オプション」 :好きな名前を入力
「IPv4 CIDR ブロック」: 今回は 「10.0.0.0/16」
「IPv6 CIDR ブロック」: 「IPv6 CIDR ブロックなし」 を選択
「テナンシー」:デフォルト を選択(専有にすると追加料金がかかる)
「VPCを作成」 を選択

サブネットの分割

CIDRブロックを更に小さく分割して使うのが一般的であり、細分化されたブロックを「サブネット」と呼ぶ
今回は「/16」で作成したブロックを「/24」の大きさで256分割にする

「VPC ダッシュボード」 から 「サブネット」 を選択
「サブネットの作成」 を選択
「VPC ID」 から 先ほど作成した「VPC」を選択
「サブネット名」: 好きな名前を入力
「アベイラビリティーゾーン」: 指定なし
「IPv4 CIDR ブロック」: 今回は 10.0.1.0/24 を指定
「サブネットを作成」 を選択

インターネットゲートウェイ

サブネットをインターネットに接続するには、「インターネットゲートウェイを設定する必要がある

「VPC ダッシュボード」 から 「インターネットゲートウェイの作成」 を選択
「名前タグ」: 好きな名前を入力
「インターネットゲートウェイの作成」 を選択
VPCアタッチ画面が表示されるので 作成した「VPC」を選択

ルートテーブルの作成

宛先IPアドレスの値により、どのネットワークに流すべきか区別する設定

「VPC ダッシュボード」 から 「ルートテーブルの作成」 を選択
「名前タグ」: 好きな名前を入力
「VPC*」: 作成した「VPC」を選択
「作成」を選択

ルートテーブル(インターネットゲートウェイ)の設定

作成したルートテーブルを選択
「ルートタブ」 を選択し、 「ルートの編集」を選択
「ルートの追加」 から 
送信先:「0.0.0.0/0」
ターゲット:「internet Gateway」を選択すると 作成されたインターネットゲートウェイが表示される

ルートテーブル(サブネット)の設定

作成したルートテーブルを選択
「サブネットの関連付け」 を選択し、 「サブネットの関連付けの編集」を選択
作成したサブネットを選択し、「保存」

今回はネットワークの設定まで終わったので
続きは次の会で説明しようと思います!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS でサーバー構築、アプリをデプロイ①

概要

簡単にAWSでサーバー構築をしてアプリケーションをデプロイさせる
今回は ネットワークの構築 まで進めようと思います!

リージョンの変更

右上のリージョンから 「アジアパシフィック(東京)ap-northeast-1」 に変更

VPC領域の作成

VPC とは(Virtual Private Cloud)の略
VPC を作成すると ユーザー毎に隔離されたネットワーク空間が作れます

AWS上のVPC領域はプレフィックス長が16以上を指定する必要があるので
CIDR ブロックは 10.0.0.0/16 にする必要がある

トップ画面 から 「VPC」 を選択
「名前タグ-オプション」 :好きな名前を入力
「IPv4 CIDR ブロック」: 今回は 「10.0.0.0/16」
「IPv6 CIDR ブロック」: 「IPv6 CIDR ブロックなし」 を選択
「テナンシー」:デフォルト を選択(専有にすると追加料金がかかる)
「VPCを作成」 を選択

サブネットの分割

CIDRブロックを更に小さく分割して使うのが一般的であり、細分化されたブロックを「サブネット」と呼ぶ
今回は「/16」で作成したブロックを「/24」の大きさで256分割にする

「VPC ダッシュボード」 から 「サブネット」 を選択
「サブネットの作成」 を選択
「VPC ID」 から 先ほど作成した「VPC」を選択
「サブネット名」: 好きな名前を入力
「アベイラビリティーゾーン」: 指定なし
「IPv4 CIDR ブロック」: 今回は 10.0.1.0/24 を指定
「サブネットを作成」 を選択

インターネットゲートウェイ

サブネットをインターネットに接続するには、「インターネットゲートウェイを設定する必要がある

「VPC ダッシュボード」 から 「インターネットゲートウェイの作成」 を選択
「名前タグ」: 好きな名前を入力
「インターネットゲートウェイの作成」 を選択
VPCアタッチ画面が表示されるので 作成した「VPC」を選択

ルートテーブルの作成

宛先IPアドレスの値により、どのネットワークに流すべきか区別する設定

「VPC ダッシュボード」 から 「ルートテーブルの作成」 を選択
「名前タグ」: 好きな名前を入力
「VPC*」: 作成した「VPC」を選択
「作成」を選択

ルートテーブル(インターネットゲートウェイ)の設定

作成したルートテーブルを選択
「ルートタブ」 を選択し、 「ルートの編集」を選択
「ルートの追加」 から 
送信先:「0.0.0.0/0」
ターゲット:「internet Gateway」を選択すると 作成されたインターネットゲートウェイが表示される

ルートテーブル(サブネット)の設定

作成したルートテーブルを選択
「サブネットの関連付け」 を選択し、 「サブネットの関連付けの編集」を選択
作成したサブネットを選択し、「保存」

今回はネットワークの設定まで終わったので
続きは次の章で説明しようと思います!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TerraformでAmazon API Gatewayを構築する(リソースポリシー編)

はじめに

API Gateway+Terraform記事第4弾。
TerraformのAWSプロバイダの3.16.0で2020/11/18にリソースポリシーの Terraform リソースが使えるようになったので、今回は、IPアドレスによる制限をさっそく試してみる。

Terraform

とはいっても、普通にIAMポリシーを書くだけである。

Condition(IpAddress)を使って許可をしてするよう、こんな感じで定義しよう。

resource "aws_api_gateway_rest_api_policy" "test" {
  rest_api_id = aws_api_gateway_rest_api.test.id
  policy      = data.aws_iam_policy_document.test.json
}

data "aws_iam_policy_document" "test" {
  statement {
    effect = "Allow"

    principals {
      type = "*"
      identifiers = [
        "*",
      ]
    }

    actions = [
      "execute-api:Invoke",
    ]

    resources = [
      "arn:aws:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.self.account_id}:${aws_api_gateway_rest_api.test.id}/*",
    ]

    condition {
      test     = "IpAddress"
      variable = "aws:SourceIp"

      values = [
        "xxx.xxx.xxx.xxx/32",
      ]
    }
  }
}

なお、resources の部分については、AWS公式の開発者ガイドでは、execute-api:/[ステージ名]/[メソッド]/[リソース名] にすれば良い感じに ARN に変換してくれるよ、と書いてあるのだが、良い感じに変換してもらえるがために、毎回 Terraform の差分として検出されるようになってしまうため、素直に↑のように ARN 形式で書いておこう。

"*" の部分については、上記の通り [ステージ名]/[メソッド]/[リソース名] で書くことも可能。

これで許容されていないIPアドレスでアクセスすると、

{"Message":"User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:ap-northeast-1:************:xxxxxxxxxx/prod/GET/xxxxxxxx"}

な感じでエラーが応答される。

アクセスログを設定している場合は、以下のように 403 応答を返したログが出力される。

{
    "requestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "ip": "xxx.xxx.xxx.xxx",
    "caller": "-",
    "user": "-",
    "requestTime": "26/Nov/2020:13:51:55 +0000",
    "httpMethod": "GET",
    "resourcePath": "/xxxxxxxx",
    "path": "/prod/xxxxxxxx",
    "status": "403",
    "protocol": "HTTP/1.1",
    "responseLength": "168",
    "integrationLatency1": "-",
    "integrationRequestId": "-",
    "integrationStatus1": "-",
    "integrationErrorMessage": "-",
    "integrationLatency2": "-",
    "integrationStatus2": "-",
    "responseLatency": "1",
    "errorMessage": "User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:ap-northeast-1:************:xxxxxxxxxx/prod/GET/xxxxxxxx"
}

あとは、AWS公式の開発者ガイドに書いてある

API 作成後にリソースポリシーを更新する場合は、更新後のポリシーをアタッチしてから API をデプロイし、変更を伝達する必要があります。ポリシーのみ、更新または保存した場合、API のランタイム動作が変更されることはありません。API のデプロイの詳細については、「Amazon API Gateway での REST API のデプロイ」を参照してください。

が注意点といったところか。

これで、API Gatewayをよりセキュアに運用できるようになった!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】Windows10にAWS-CLI ver.2をインストールしてみた

はじめに

AWSを勉強するために、ノートPCにAWS-CLIをインストールしてみたので、備忘として残しておきます。

PCスペック

  • OS:Windows 10 Home(バージョン 20H2(OSビルド 19042.630))
  • CPU:Intel Core i7-10510U 1.80GHz(2.30GHz)
  • RAM:16.0GB

目次

  1. インストール
  2. 設定

1. インストール

基本的には以下の公式サイトの通りインストールを進めればOKです。
Windows での AWS CLI バージョン 2 のインストール、更新、アンインストール

前提条件

インストールする前に事前に以下の確認が必要です。
* 64ビットバージョンのWindows XP以降のOS
* ソフトウェアインストール用の管理者権限

MSIインストーラをダウンロードする

最新版のインストーラをダウンロードします。
※特定のバージョンが欲しい場合はバージョンを指定してください。(公式サイトのリンクを参照してください。)
CLIv2(最新版)のインストーラ

インストールする

ダウンロードしたMSIインストールを実行し、ウィザードに沿ってインストールを進めます。
インストールが完了したら、スタートメニューからコマンドプロンプト(cmd)を開き、以下のコマンドを入力して確認します。

aws --version

aws-cli/2.1.4 Python/3.7.9 Windows/10 exe/AMD64

のように出力されればOKです。

インストールはこれだけです。
非常に簡単にインストールが出来ました。

2. 設定

インストールが完了したら、AWSに接続できるように諸々の設定を行います。
ここからは実際にコンソール画面から必要情報を取得したり、それをCLIのconfigに設定していきます。

アクセスキー/シークレットキーの取得

AWSコンソール画面から、IAMを検索しIAMサービスページに遷移してください。

IAMページから「アクセス管理」>「ユーザー」を選択してください。

任意の(CLIで利用したい)ユーザーを選択し、タブから「認証情報」を選択してください。

「アクセスキー」の欄にある、「アクセスキーの作成」ボタンを押します。
※アクセスキーとシークレットキーは絶対に外部に出ないように注意してください。

アクセスキー/シークレットキーがcsvファイルでダウンロードされます。
これを用いてCLIに設定をしていきます。

CLIの設定

スタートメニューから「cmd」を起動し、以下のコマンドを入力してください。

C:\> aws configure
AWS Access Key ID [None]:取得したアクセスキーを入力
AWS Secret Access Key [None]:取得したシークレットキーを入力
Default region name [None]:デフォルトで使用するリージョンを入力(東京の場合は、ap-northeast-1)
Default output format [None]:出力フォーマットを入力(json,yaml,yaml-stream,text,tableのいずれかを入力(今回はjsonを指定)。変更も可能)

出力フォーマットの説明は以下の通りです。(2020/11/26時点)
実行コマンドに--outputオプションを指定すれば、コマンド実行時に変更もできます。

形式 説明
json JSON 文字列形式で出力されます。
yaml YAML 文字列形式で出力されます。(AWS CLI バージョン 2 でのみ利用できます。)
yaml-stream 出力はストリーミングされ、YAML 文字列としてフォーマットされます。ストリーミングにより、大きなデータ型の処理を高速化できます。(AWS CLI バージョン 2 でのみ利用できます。)
text 複数行のタブ区切り文字列値の形式で出力されます。これは、grep、sed、または awk などのテキストプロセッサに出力を渡すのに役立ちます。
table セルの罫線を形成する文字列 +| - を使用して表形式で出力されます。通常、情報は他の形式よりも読みやすい「わかりやすい」形式で表示されますが、プログラムとしては役立ちません。

接続確認

cmdにて接続できるか確認してみます。
今回は、IAMユーザーの一覧を表示するコマンドを実行します。

C:\>aws iam list-users
{
  "Users":[
       {
         ...ここに作成済みのユーザが表示されます。
       }
   ]
}

と出力されれば完了です。

S3バケットの確認コマンドも念のため実行しておきます。

C:\>aws s3 ls

作成済みのS3バケットが表示されれば完了です。

プロファイル設定

CLIではプロファイルと呼ばれる設定のコレクションがあります。
デフォルトでは「default」プロファイルを使用しますが、実行コマンドに--profileオプションを指定すれば、作成済の各プロファイルにて実行が可能になります。

プロファイル作成

基本的に先ほどの設定手順と同じです。
今回は「devuser」というプロファイルを作成してみます。
出力フォーマットを変更してもらえると、差がわかりやすいかと思います。(json⇒textに変更しました。)

C:\> aws configure --profile devuser
AWS Access Key ID [None]:取得したアクセスキーを入力
AWS Secret Access Key [None]:取得したシークレットキーを入力
Default region name [None]:デフォルトで使用するリージョンを入力(東京の場合は、ap-northeast-1)
Default output format [None]:出力フォーマットを入力(json,yaml,yaml-stream,text,tableのいずれかを入力。変更も可能)

設定を確認してみます。

C:\>aws iam list-users --profile devuser
USERS arn:...

先ほどと表示されるフォーマットが変わっていれば完了です。

さいごに

今回は、Win10端末にAWS CLI2をインストールし、接続確認までを行いました。
今後CLIを用いた構築などを更新していければと思います。
また、CLIについてのユーザーガイドは以下をご確認ください。
AWS コマンドラインインターフェイスのドキュメント

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon Elasticsearch Serviceを使ってみての所感

この記事はLivesense AdvendCalendar 5日目の記事です。

背景・機運

転職会議では、口コミや求人データを扱う際にElasticsearchを使っています。
その際に、ElasticCloudというElastic社が提供するマネージドサービスを利用してきました。
Kibanaなどの周辺サービスも充実しており導入当初は良かったのですが、課題が徐々に露呈してきました

1. ネットワークがボトルネック

外部サービスのためVPC外にリクエストを投げることになり、場合によってはレスポンスが悪くなる。特に大量のリクエストを投げると顕著。
メルマガ配信時も使っており、配信時にリクエストのタイムアウトが頻発。

2. コスト・運用面

料金に応じたCPUやメモリのスペックが確保されるため運用用途にあった料金を設定できず、AWS NATの転送量による支払いもあり、総合してみると多額の支払いが発生。
移行すれば「1年でプリウスくらいは買えるくらい浮きそう」という結果に
また、転職会議ではDatadogでサービス・ミドルウェアの監視・通知を行っているのですが、ElasticCloudだけマネージドされた監視ツールを使っていたため独立しており、雑多な状態になっていました。

3. カスタムプラグインが特定のプラン以上でしか使えない

ElasticCloudでは料金プランがいくつか用意されていて、用途に合わせて契約することが可能です。
転職会議では最小プランのスタンダードを利用していましたが、カスタムプラグインが更に上のプランでしか利用できず、ユーザ辞書を追加して検索の精度改善を実施することができない状態でした。
プランを変更してもよいのですがコスト面が見合わず、しばらく使わない状態で運用していました。

4. パフォーマンス

辞書が使えなかったのでtermクエリを使うと想定外のドキュメントが取れてしまうので、それっぽいことをするためにAPIで取得する際にquery_stringで大量のドキュメントを取得し、そこからアプリ側でゴリッと色々とやっていました。。。。
結果APIのレイテンシーが徐々に悪化。ときにリクエストがタイムアウトを起こすこともありました。
またSLO改善の一環で、アプリ改修を含めこちらにも手を入れる必要がありました。

これらの課題を解決するためにElasticCloudを脱却することを決定。
当初はEKS上に自前でElasticsearchを立てる動きでした。

4月、AWSからのアナウンス

今年のはじめから少しずつ移行対応の検討と対応を行ってきましたが、なんとAmazon Elasticserch Service(以下 Amazon ES)側でカスタム辞書をサポート
Amazon ESではkuromojiしかサポートしておらず、kuromojiの辞書は更新がほとんどされてないため、想定とは異なる言語処理結果になってしまうことが多いです。これはかなり嬉しいアナウンスでした。
他にも調査してみると、EKSで自前で立てるのと彩色無く利用できそうだったのと、スロークエリログをCloudWatch Logsに流せるなど、他のAWSのサービスと親和性が高い。
また費用面でも自前よりは劣るが、それでも安くなるので急遽利用することに。

やったこと

  1. Amazon ES側にインデックスを作成、ElasticCloudと並行して差分インデクシングさせる
    1. アプリ側からもドキュメントの更新を行う処理があるので、差分が出ないように先に実施しておく
  2. バッチでAmazon ES側に作成し、aliasを書き換える
  3. アプリやサービスで参照しているエンドポイントの切り替え
  4. ElasticCloudを脱却

大きなことはやっておらず、負荷も考慮しながら少しずつ移行対応していきました。

運用してみて

移行してしばらく経ちますが問題なく動いています。辞書も使えてaggregationによるキャッシュも効かせられ、レイテンシーも改善。(オレンジの線の前後でレイテンシーが変わっていることが分かります。嬉しい、、、!)
スクリーンショット_2020-12-01_16_41_31.jpg
しかしAmazon ES特有の問題(癖というべきか、、)があり、かゆいところに手が届かない感じです。。。。

1. カスタム辞書の関連付けがterraform管理できない

Amazon ESで辞書を使うには、S3に指定のフォーマットでアップロードしてそれをパッケージとして紐付けます。
紐付けた際に発行されたリファレンスパスをuser_dictionaryとして追記し、インデックスを作り直す必要があります。

    "analysis": {
      "tokenizer" : {
        "sample_kuromoji_tokenizer" : {
          "type":"kuromoji_tokenizer",
          "user_dictionary": "analyzers/F123456789"
        }
      }

上記のanalyzers/F123456789が発行されたリファレンスパスに当たります。

AWSのリソースをterraformを使って管理してるのでまとめたかったのですが、aws_elasticsearch_domainリソースでは提供されてないようです。

頻繁に辞書を更新する場合はスクリプトで管理するか、7.4以降からはuser_dictionary_rulesという、synonymと同様に直接辞書を追加できる設定があるのでそちらを使うと良いかもしれません。

2. 一部のAPIが利用できない

OSSで提供されているElasticsearchとは異なり、許可されていないAPI(rerouteなど)が存在します。
自前で立てた場合と同じ想定で運用すると思いもよらない落とし穴にハマるかもしれません。
利用用途に合うかリファレンスを読んでから利用することをおすすめします。

3. ElasticCloud独自の機能やサポートが利用できなくなる

これは当たり前なのですが、管理画面からボタン一つでローリングアップグレードやマイナーバージョンアップグレード、スケールアップが容易にできたのはありがたかったですね。

まとめ

移行してよかったと思う一方で、やはりサービスで提供されてるって良いなぁと思うときもあります。
通常運用する分には申し分ないかと思うので、自前で運用を考えてるならこちらも検討材料に入れてはいかがでしょうか。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ancestryはawsにデプロイしただけでは使えない

 1.どんな状態だったか

ancestryを利用して、カテゴリー機能を実装、ローカルでは動くのに本番環境で反映されないという状態

2原因

ancestryを使うためには、本番環境でもローカルと同じ様に
db migrateし、seedを読み込まなくてはならない

3解決方法

まずdb migrateします

$ cd var/www/app名/current
$ rake db:migrate RAILS_ENV=production

上手くいかない時はdbをドロップしもう一度クリエイトし直す

$ RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:drop

$ rake db:create RAILS_ENV=production

もう一度migrateします。

次にseedを反映させます。

$ rake db:seed RAILS_ENV=production

以上になります。

4最後に

自動デプロイをしている場合はcurrentディレクトリで操作を行う必要があるそうです
そうでない場合は~ディレクトリで大丈夫みたいです

参考にした記事
[aws,rails]ancestryをawsにデプロイした時に反映されない状況の解決方法
本番環境でrake db:seedを実行する際の注意点

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Athenaからクエリ出来てCSVダウンロードやS3から直接ダウンロード禁止する

ただのメモです。

AthenaとGlueのリストと読み取り権限ポリシー作ってアタッチ

S3の読み取り権限ポリシーを、calledviaを使いAthenaからだけ許可する形で作成してアタッチ

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucketMultipartUploads",
                "s3:AbortMultipartUpload",
                "s3:CreateBucket",
                "s3:ListBucket",
                "s3:GetBucketLocation",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
                "arn:aws:s3:::aws-athena-query-results-xxxxxxxxxxxx-ap-northeast-1/*",
                "arn:aws:s3:::aws-athena-query-results-xxxxxxxxxxxx-ap-northeast-1"
            ],
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "aws:CalledVia": "athena.amazonaws.com"
                }
            }
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::test",
                "arn:aws:s3:::test/*"
            ],
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "aws:CalledVia": "athena.amazonaws.com"
                }
            }
        }
    ]
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

サルでもできる!? Rails6アプリをAWS EC2にデプロイするまでの全手順【後半】(独自ドメイン, HTTPS化, S3, CloudFront)

この記事では,画像投稿機能の付いた Rails 6 のアプリを AWS EC2 にデプロイするまでの全過程を解説します。

【前半】 でRailsアプリのデプロイはひとまず完了しましたが,まだまだすべきことがたくさんあります。続きも気を抜かずに頑張りましょう!

タイトル
【前半】
1章 はじめに
2章 VPC
3章 RDS
4章 EC2
5章 サーバー構築
6章 デプロイ(Capistrano)
【後半】 <-- こちら
7章 独自ドメイン
8章 HTTPS化(ACM, ALB)
9章 デプロイ関連事項
10章 S3
11章 CloudFront
12章 削除方法

7. 独自ドメイン

Railsアプリを公開することができましたが,現状では2つ大きな問題を抱えています。

  • サイトの URL が不自然
    • google.com のような 独自ドメイン ではない
  • HTTPSではない
    • Google Chrome で「このサイトへの接続は保護されていません」という警告が出る

まずは前者から解決していきましょう。

aws-sample-app.com のような URL でアクセスできるようにするには, ドメイン を取得する必要があります。

ドメイン は有料ですが,こだわらなければ初年度は数百円程度で取得できます。

この記事では昔から代表的な レジストラ である「お名前.com」で取得する前提で解説します。

7.1 ドメインの購入

  • 「お名前.com」にアクセス

  • 検索窓に取得したいドメイン名を入力し,「検索」ボタンをクリック

    • ドメインに使用できる文字は「半角英数字」と「ハイフン -」です
    • 「アンダースコア _」 は使用できません

7_1a.png

  • .com などのドメインを選択し,「料金確認へ進む」ボタンをクリック

    • 自動選択されているチェックを外し忘れないように注意しましょう
    • こだわりがなければ初年度の安いドメインを取得してもよいでしょう
  • 購入処理を行って下さい。「Whois情報公開代行」は必須ですが,その他のオプションは全て不要です

    • 「サーバー」は「利用しない」をチェック
    • 「Whois情報公開代行メール転送オプション」などは全てチェック不要
  • 「お申し込みを受け付けました。」と表示されたら「ドメインの設定はこちら」のリンクをクリック

【備考】後に続きの操作をおこないますので,他のタブで続きの作業を進めて下さい

自動更新の解除

初期設定では,ドメインの更新期限日を過ぎますと自動更新・自動課金されます。

2年目以降は料金が高くなるドメインが多いですので,自動更新を解除したい場合は以下の操作を行ってください。

  • 「お名前.com」のページ上側にあるタブの「ドメイン」を選択

  • 「更新画面から移動する」をクリック

  • アプリで使用するドメインを選択

7_1b.png

  • 「自動更新」ボタンをクリック

7_1c.png

  • 「確認画面へ進む」をクリック

  • 「自動更新設定申込内容」の項目が「解除する」になっていることを確認の上,「規約に同意し、上記内容を申し込む」ボタンをクリック

7_1d.png

  • 「解除する」ボタンをクリック

  • 「ドメイン一覧」のタブをクリック

【備考】後に続きの操作をおこないますので,続きの作業は他のタブで進めて下さい

7.2 IPアドレスとドメインの関連付け

Route 53 を利用することで,先ほど購入した ドメインIPアドレス に変換することができます。

通常の使用範囲内ならば月100円もかかりません。

  • AWS の画面左上の「サービス」を開き、検索欄に「route」と入力し、「Route 53」を選択

  • 「ホストゾーンの作成」ボタンをクリック

キー
ドメイン名 取得したドメインを記載
説明 - オプション アプリ名_domain
タイプ パブリックホストゾーン

7_2a.png

  • 「ホストゾーンの作成」ボタンをクリック

  • タイプが「NS」の方の「値/トラフィックのルーティング先」に表示されている4つを ネームサーバー としてメモしておいて下さい

    • 【要注意】メモする際に,それぞれの最後についている「ドット .」は削除して下さい!

7_2b.png

7.3 ネームサーバーの変更

先ほど残しておいた「お名前.com」に移動して下さい

(タブを閉じてしまった場合は,再度「お名前.com」にアクセスし,ログインして下さい)

  • 「ドメイン一覧」の中から取得した「ドメイン名」を選択

  • 「ネームサーバー情報」の項目の「ネームサーバーの変更」をクリック

7_3a.png

  • 「2.ネームサーバーの選択」をクリック

  • 「その他」タブをクリックし,「その他のネームサーバーを使う」の方にチェックを入れ,先ほどメモした4つの ネームサーバー をコピペして下さい

    • 先ほど注意しました通り,最後についている「ドット .」は入力しないで下さい

7_3b.png

7.4 ネームサーバーの確認

ローカル環境のターミナルから以下を実行して下さい。

ローカル環境のターミナル
dig ドメイン名 NS +short

登録した4つのドメインが入っていればOKです。(順番が入れ替わっていてもOK)

デフォルトの2つしか入っていない場合は,しばらく待ってから再度先ほどのコマンドを実行しましょう。

7.5 ドメインの適用

  • AWSRoute 53 の先ほどの続きの画面から,「レコードを作成」をクリック

  • 「シンプルルーティング」にチェックを入れた状態で「次へ」ボタンをクリック

  • 「シンプルなレコードを定義」ボタンをクリック

キー
レコード名 ※入力しない
値/トラフィックのルーティング先 「レコードタイプに応じた IP アドレス または別の値」をクリックし, Elastic IP を入力
レコードタイプ A

7_5.png

これで準備が完了です。まずは,ローカル環境のターミナルから以下を実行して下さい。

ローカル環境のターミナル
curl -I ドメイン名

最初に HTTP/1.1 200 OK もしくは HTTP/1.1 302 が出れば正常です。

前回は Elastic IP でなければアクセスできませんでしたが,今度は ドメイン名 でアクセスできる状態になっています。

ブラウザから ドメイン名 でアクセスし, スーパーリロード して下さい。(ショートカットキーは command + shift + r

8. HTTPS化(ACM, ALB)

次はこちらの問題に対処していきましょう。

  • HTTPSではない
    • Google Chrome で「このサイトへの接続は保護されていません」という警告が出る

【備考】 ELBApplication Load Balancer(ALB) を利用しますので,月2000円程度の費用がかかります。

8_0.png

8.1 ACM

HTTPS化 には,まず, SSL/TLS サーバー証明書 を取得する必要があります。

Let's Encrypt で取得する方法が有名ですが,AWSを利用する場合は SSL/TLS サーバー証明書ACM で取得し, ALB に関連付けるのが一般的な手法です。作業が楽で,更新の手間も不要になります。

ALB と関連付けますので, ACM 自体は無料で利用できます。

  • AWS の画面左上の「サービス」を開き、検索欄に「acm」と入力し、「Certificate Manager」を選択

  • 「証明書のプロビジョニング」の「今すぐ始める」ボタンをクリック

  • 「パブリック証明書のリクエスト」を選択した状態で「証明書のリクエスト」ボタンをクリック

  • 「この証明書に別の名前を追加」をクリック

  • 取得した「ドメイン名」と「*.ドメイン名」を入力

  • 「次へ」ボタンをクリック

8_1.png

  • 「DNS の検証」を選択した状態で「次へ」ボタンをクリック
タグ名
Name アプリ名_alb
  • 「確認」ボタンをクリック

  • 「確定とリクエスト」ボタンをクリック

  • 「続行」ボタンをクリック

8.2 DNS検証用の CNAME レコード追加

  • ドメインの欄のプルダウンを開き,「Route 53 でのレコードの作成」ボタンをクリック
    • 2つ表示されていますが,どちらか片方のみでOKです
    • プルダウンが表示されない場合は,一度リロードして下さい

8_2.png

  • 「作成」ボタンをクリック

【注意】 8.3 は先に行っても問題ありませんが, 8.4 以降の作業は,状況が「検証保留中」から「発行済み」に変わってから行って下さい

8.3 ALB 用のセキュリティグループの作成

【構成内容】 クライアント --(HTTP or HTTPS)--> ALB --(HTTP)--> EC2

ELB の内の ALB (Application Load Balancer) を使用し,先ほど取得した SSL/TLS サーバー証明書 を使用できるように設定していきましょう。

ALBEC2 の前にリクエストを受け,(一般には複数の) EC2 に分散します。このことを踏まえたセキュリティグループを作成しましょう。

  • 画面左上の「サービス」を開き、検索欄に「ec2」と入力し、「EC2」を選択

  • EC2 画面左のメニューバーの「セキュリティグループ」を選択し,「セキュリティグループを作成」ボタンをクリック

キー
セキュリティグループ名 アプリ名_alb_security_group
説明 アプリ名_alb_security_group
VPC アプリ名_vpc

「インバウンドルール」の「ルールを追加」を2回クリック

キー
タイプ HTTP
プロトコル TCP ※自動選択
ポート範囲 80 ※自動選択
ソース 任意の場所 (0.0.0.0/0 と ::/0 が表示)
説明 ※空白でOK
キー
タイプ HTTPS
プロトコル TCP ※自動選択
ポート範囲 443 ※自動選択
ソース 任意の場所 (0.0.0.0/0 と ::/0 が表示)
説明 ※空白でOK

8_3a.png

「アウトバウンドルール」は デフォルトの設定を削除した後 「ルールを追加」をクリックし,以下を追加

8_3b.png

キー
タイプ HTTP
プロトコル TCP ※自動選択
ポート範囲 80 ※自動選択
ソース カスタム: アプリ名_ec2_security_group
説明 ※空白でOK

8_3c.png

作成後に次の図のようにルールが定まっているかどうかを確認して下さい。

8_3d.png
8_3e.png

8.4 ロードバランサーの設定

  • 画面左のメニューバーの「ロードバランサー」を選択

  • 「ロードバランサーの作成」ボタンをクリック

  • 「HTTP, HTTPS」の方の「作成」ボタンをクリック

■ 手順 1: ロードバランサーの設定

  • 【基本的な設定】
キー
名前 アプリ名-alb ※ ハイフンに変更

他はデフォルト

  • 【リスナー】

「リスナーの追加」ボタンをクリックし,「HTTPS」を選択

  • 【アベイラビリティゾーン】
キー
VPC アプリ名_vpc
アベイラビリティーゾーン 「ap-northeast-1a」を選択し「アプリ名_public_1a_subnet」を選択
アベイラビリティーゾーン 「ap-northeast-1c」を選択し「アプリ名_public_1c_subnet」を選択

「次の手順: セキュリティ設定の構成」ボタンをクリック

8_4a.png

■ 手順 2: セキュリティ設定の構成

  • 「証明書の名前」がアプリ用のドメインであることを確認し,「セキュリティグループの設定」をクリック

8_4b.png

■ 手順 3: セキュリティグループの設定

  • 「アプリ名_alb_security_group」を選択し,「次の手順: ルーティングの設定」ボタンをクリック

8_4c.png

■ 手順 4: ルーティングの設定

  • ターゲットグループ
キー
ターゲットグループ 新しいターゲットグループ
名前 アプリ名-target-group ※ ハイフンに変更
ターゲットの種類 インスタンス ※デフォルト
プロトコル HTTP ※自動設定
ポート 80 ※自動設定
  • ヘルスチェック

デフォルト設定でOK

「次の手順: ターゲットの登録」ボタンをクリック

8_4d.png

■ 手順 5: ターゲットの登録

  • 「インスタンス」欄から、「アプリ名_instance」にチェックを入れた状態で「登録済みに追加」ボタンをクリック

8_4e.png

  • 「次の手順: 確認」をクリック

  • 「作成」ボタンをクリック

8.5 Route 53の設定を修正

ドメインを EC2 から先ほど作成した ALB に割り当てるように設定を変更しましょう。

  • AWS の画面左上の「サービス」を開き、検索欄に「route」と入力し、「Route 53」を選択

  • 「ホストゾーン」をクリック

  • アプリで使用するドメインをクリック

8_5a.png

  • 「タイプA」の「ドメイン名」のレコードをクリックし,「編集」ボタンをクリック

8_5b.png

  • 「値/トラフィックのルーティング先」の箇所を変更して下さい
    • 「Application Load Balancer と Classic Load Balancer へのエイリアス」を選択
    • 「アジアパシフィック (東京) [ap-northeast-1]」を選択
    • 「アプリ名-alb」を含むロードバランサーを選択

8_5c.png

  • 「変更を保存」ボタンをクリック

8.6 セキュリティグループの修正

ALB 経由でアクセスされるように変更したため, EC2ALB からのアクセスに限定すべきです。そのため, EC2 用のセキュリティグループを修正します。

  • AWS の画面左上の「サービス」を開き、検索欄に「ec2」と入力し、「EC2」を選択

  • 画面左のメニューバーの「セキュリティグループ」を選択

  • 「アプリ名_ec2_security_group」にチェックを入れ,「アクション」ボタンをクリックし,「インバウンドルールを編集」ボタンをクリック

8_6a.png

  • タイプが HTTP のものを全て削除し,「ルールを追加」をクリックし,以下を設定
    • SSH は削除しないこと

8_6b.png

キー
タイプ HTTP
ソース カスタム: アプリ名_alb_security_group
説明 ※空白でOK

8_6c.png

  • 「ルールを保存」ボタンをクリック

8.7 Nginx の設定ファイルを修正

ALB への接続に使用するプロトコルが HTTPS であることを識別できるよう,Nginx の設定ファイルを修正し,再起動しておきましょう。

(こちらを実行しないと,例えば POST リクエスト時にエラーが発生します)

サーバー環境のターミナル
sudo sed -i s/X-Forwarded-Proto\ http/X-Forwarded-Proto\ https/g /etc/nginx/conf.d/$APP_NAME.conf
sudo service nginx restart

それでは, HTTPS でアクセスできるかを確認しましょう。まずはターミナルから以下を実行して下さい。

ターミナル(ローカル側でもサーバー側でもOK)
curl -I https://ドメイン名

最初に HTTP/2 200 もしくは HTTP/2 302 が表示されれば正常です。次にブラウザから https://ドメイン名 にアクセスし, スーパーリロード して下さい。(ショートカットキーは command + shift + r

ブラウザのURLの左隣に「鍵マーク」が表示され,アプリが問題なく開けばOKです!

8_7.png

8.8 HTTPS にリダイレクト

【参考】 https://aws.amazon.com/jp/premiumsupport/knowledge-center/elb-redirect-http-to-https-using-alb/

最後に, HTTP でのアクセスを HTTPS にリダイレクトするように設定しましょう。

  • EC2の画面左のメニューバーの「ロードバランサー」をクリック

  • (「アプリ名-alb」を選択した状態で)「リスナー」タブをクリック

  • HTTP : 80 の方の 「ルールの表示/編集」をクリック

8_8a.png

  • 上の「鉛筆」マークをクリックし,下に出現した「鉛筆」マークをクリック

8_8b.png

  • 「THEN」の項目の転送先にある「ゴミ箱」マークをクリックして削除

8_8c.png

  • 「アクションの追加」を選択し,「リダイレクト先」をクリック

  • 「HTTPS」になっていることを確認し,ポートに 443 を入力

  • 「チェックマーク」をクリック

  • 右上の「更新」ボタンをクリック

8_8d.png

これで http でアクセスした場合も https に自動変換されるようになりました。ターミナルから以下を実行してみましょう。

ターミナル(ローカル側でもサーバー側でもOK)
curl -I http://ドメイン名

最初に HTTP/1.1 301 Moved Permanently が表示され,最後に Location: https://アプリ名:443/ が表示されていればOKです。

ブラウザでも http://ドメイン名 でアクセスしてみましょう。URLの左隣に鍵マークが付いていればOKです!

お疲れ様でした!

8.9 最後に

グローバル変数の削除

作業が終わりましたので,ローカル環境で定義したグローバル変数 $APP_NAME は消しておくこととしましょう。

ローカル環境のターミナル
# zsh の場合
vi ~/.zshrc

# bash の場合
vi ~/.bash_profile

一番最後の行にある export APP_NAME=アプリ名 を削除して下さい。

EC2のパスワード設定

次に,EC2のユーザーにパスワードを設定し, sudo コマンド実行時にパスワードを求められるように変更しましょう。

(作業を楽にするため,EC2のユーザーはパスワード無しで sudo コマンドを使用できる状態にしていました)

サーバー環境のターミナル
sudo passwd `whoami`
設定したいEC2のパスワードを入力
EC2のパスワードを再入力

【注意】「EC2のパスワード」は必ずメモしておいて下さい。

サーバー環境のターミナル
sudo visudo

Vim で開かれたら,一番最後の行の NOPASSWD: の箇所のみ削り,次の状態にして下さい。

sudoers
ユーザー名 ALL=(ALL) ALL

【注意】ユーザー名 ALL=(ALL) NOPASSWD: ALL を「全て」削ってはいけません!編集を間違えると,二度と sudo コマンドを実行できなくなる恐れがありますので,慎重に行ってください。

これで sudo コマンドを実行した際に今後はパスワードを尋ねられるようになります。

以下を実行し,パスワードを求められるかどうか,パスワードを入力してコマンドを実行できるかどうかを確かめて下さい。

サーバー環境のターミナル
sudo ls

9. デプロイ関連事項

この章は必要な場合のみご覧ください。

9.1 アプリ修正時の反映方法

以下のコマンドで「GitHub」の master ブランチをAWS側に反映させることができます。

ローカル環境のターミナル
# Railsアプリのルートディレクトリに移動してから
bundle exec cap production deploy

【注意】 Heroku のデプロイで使用する git push heroku master は「ローカル」の master ブランチを反映させるコマンドです。 bundle exec cap production deploy コマンドは「ローカル」ではなく「GitHub」である点に注意しましょう。

9.2 master以外のブランチを反映させたい

config/deploy.rb
set :branch, ENV['BRANCH'] || "master"

を追加すれば,例えば以下のコマンドで「GitHub」の hoge ブランチを反映できます。

ローカル環境のターミナル
bundle exec cap production deploy BRANCH=hoge

例えば,現在のブランチをAWS側で動作確認したい場合は次の手順になります。

ローカル環境のターミナル
# add, commit の実行後
git push origin HEAD
bundle exec cap production deploy BRANCH=HEAD

9.3 AWS側で Rails コマンドや rake タスクを実行する方法

サーバー側のアプリは /var/www/$APP_NAME/current に入っています。

まずはここまで移動し,必要に応じて yarn install --check-files を実行して下さい。

サーバー環境のターミナル
cd /var/www/$APP_NAME/current
yarn install --check-files

その上で,必要なコマンドを実行しましょう。コマンド例を紹介します。

  • サーバー側で rails db:seed を実行したい場合
サーバー環境のターミナル(/var/www/$APP_NAME/current)
bin/rails db:seed RAILS_ENV=production

bin/railsbundle exec rails でも問題ありませんが, rails ではダメです。また, RAILS_ENV=production が必要である点に注意して下さい。

  • サーバー側で rails db:migrate:reset を実行したい場合
サーバー環境のターミナル(/var/www/$APP_NAME/current)
bin/rails db:migrate:reset RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1

本番環境のデータベースを削除(リセットを含む)したい場合は, DISABLE_DATABASE_ENVIRONMENT_CHECK=1 が必要です。

  • サーバー側で rails console を実行したい場合
サーバー環境のターミナル(/var/www/$APP_NAME/current)
bin/rails c -e production

オプションが RAILS_ENV=production ではなく -e production の書き方になります。

  • サーバー側で rake タスクを実行したい場合
サーバー環境のターミナル(/var/www/$APP_NAME/current)
bundle exec rake タスク名 RAILS_ENV=production

タスク名は bundle exec rake -T で確認できます。bundle exec rakebin/rails でもOKですが rake ではダメです。

9.4 サーバー側で ログ を確認する方法

サーバー側の ログ/var/www/$APP_NAME/shared/log に入っています。

サーバー環境のターミナル
cd /var/www/$APP_NAME/shared/log
ls

でログファイルの一覧を確認できます。

エラーが出た場合は,nginx.error.logpuma_error.log を確認しましょう。

サーバー環境のターミナル(/var/www/$APP_NAME/shared/log)
# ログを全て表示したい場合
cat nginx.error.log
# 最後の30行を表示したい場合
tail -n 30 nginx.error.log
# ログの追加分のみを自動表示したい場合(control + c で終了)
tail -f nginx.error.log

10. S3

【注意】10章, 11章は, CarrierWaveActiveStorage などで画像の投稿機能を実装している場合のみ,実行して下さい。

現状でも画像の投稿は可能ですが, AWS S3 を使用することで,Webサーバー(EC2)のストレージが画像で圧迫されるのを防いだり,負荷分散ができるなど複数のメリットがあります。

さらに, CloudFront を用いることで画像転送を高速化するところまでを解説します。

10.1 S3バケットの作成

S3 は,クラウド型のオブジェクトストレージサービスです。画像に限らずいろいろなデータを保存することができ,簡単なWebサイトの公開にも使用できます。

セキュリティ・耐久性共に優れ,価格も安いのが特徴です。ポートフォリオの画像投稿機能に使用する程度であれば,大抵の場合は無料利用枠内でおさまるでしょう。

S3 を利用するには,まず, バケット を作成する必要があります。

  • 画面左上の「サービス」を開き、検索欄に「s3」と入力し、「S3」を選択

  • 「バケットの作成」を選択

  • 一般的な設定

タイトル 内容
バケット名 任意 ※世界ですでに存在する名前は付けられません
リージョン アジアパシフィック (東京) ap-northeast-1

【注】 バケット名とリージョンap-northeast-1を忘れないようにメモしておいて下さい。

  • ブロックパブリックアクセスのバケット設定

下の2つ(ACL以外)のみをチェックし,注意喚起にもチェック

10_1a.png
10_1b.png

「バケットを作成」をクリック

10.2 アプリ用のIAMユーザーを作成

次に,アプリ側から S3 にアクセスするための アクセスキー などを入手しましょう。

  • 画面左上の「サービス」を開き、検索欄に「iam」と入力し、「IAM」を選択

  • 左のメニューから「ユーザー」を選択

  • 青いボタン「ユーザーを追加」をクリック

タイトル 内容
ユーザ名 アプリ名_user
アクセスの種類 「プログラムによるアクセス」にチェック

10_2a.png

  • 「次のステップ:アクセス権限」をクリック

  • 「既存のポリシーを直接アタッチ」ボタンをクリック

  • AmazonS3FullAccess をチェックして,「次のステップ: タグ」ボタンをクリック

    • 「参考」のようにより権限を厳しくしたポリシーをアタッチするとより安全です

10_2b.png

  • 「次のステップ: 確認」ボタンをクリック

  • 「ユーザーの作成」をクリック

  • 「.csvのダウンロード」ボタンをクリック

「ユーザー名」「アクセスキーID」「シークレットアクセスキー」をメモしておいて下さい。

  • 「閉じる」ボタンをクリック

参考: 権限の少ないポリシーを作成

AmazonS3FullAccessS3 の全ての操作ができる権限ですので,アプリに持たせる権限としては過剰すぎます。

最低限必要な権限をもつポリシーを作成し,AmazonS3FullAccess の代わりにこちらをIAMユーザーにアタッチしておくと,万一の場合の被害を軽減することができます。

参考: CarrierWave

IAMポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:PutObjectAcl",
                "s3:ListAllMyBuckets"
            ],
            "Resource": "*"
        }
    ]
}

10_2c.png
10_2d.png

さらに安全を求めるならば,バケットまで制限することも可能ですが,ここでは省略します。

10.3 CarrierWaveの設定

※ 以下,画像投稿機能に CarrierWave を使用していることを前提とします

まず,Railsアプリに fog-awsGemfile に追加し,インストールしておきましょう。

ローカル環境のターミナル
bundle add fog-aws

本番環境のみで AWS S3 を使用する場合は次のように修正しましょう。

(開発環境でも使用したい場合は,条件分岐せず storage :fog のみにして下さい)

app/uploaders/image_uploader.rb
# 「storage :file」を以下に置き換える
  if Rails.env.production?
    storage :fog
  else
    storage :file
  end

次に, S3 の「アクセスキーID」などを読み込む設定を追加しましょう。

特に「シークレットアクセスキー」は,GitHubに公開してはならないので, credentials.yml.enc から読み込む形式とします。

「リージョン」と「バケット名」は公開しても問題ありませんので,直接記載することとします。

ローカル環境のターミナル
touch config/initializers/carrier_wave.rb

(開発環境でもS3を使用したい場合は,最初の行 if Rails.env.production? と最後の行 end を削りましょう)

config/initializers/carrier_wave.rb
if Rails.env.production?
  CarrierWave.configure do |config|
    config.fog_credentials = {
      provider: "AWS",
      aws_access_key_id: Rails.application.credentials.dig(:aws, :access_key_id),
      aws_secret_access_key: Rails.application.credentials.dig(:aws, :secret_access_key),
      region: "ap-northeast-1"
    }
    config.fog_directory = "S3のバケット名"
  end
end
  • credentials.yml.encを開くため,次のコマンドを実行
ターミナル
EDITOR=vi rails credentials:edit
  • アプリが S3 にアクセスするために必要な情報を credentials.yml.enc に記載しましょう
    • yaml形式なので,インデント幅にはくれぐれも注意して下さい
    • 例えば,access_key_id:の後に「半角スペース1個」がないだけでエラーになります
config/credentials.yml.enc
db:
  password: RDSのパスワード
  hostname: RDSのエンドポイント
# 以下を追加
aws:
  access_key_id: IAMユーザーのアクセスキーID
  secret_access_key: IAMユーザーのシークレットアクセスキー

10.4. 動作確認

念のため以下を実行し,「アクセスキーID」などが取得できることを確認しておいた方がよいでしょう。

ローカル環境のターミナル
rails c
# コンソール起動後
Rails.application.credentials.dig(:aws, :access_key_id)
Rails.application.credentials.dig(:aws, :secret_access_key)
# IAMユーザーのアクセスキーID, シークレットアクセスキーが表示されることを確認後
exit

コミット・プッシュ(必要があればプルリク・マージ)などを行い,GitHub の master ブランチに変更を反映した上で,AWS にデプロイを行いましょう。

ローカル環境のターミナル
bundle exec cap production deploy

【補足】 9.2 に記載した方法で,masterブランチにマージする前に確認するのが理想的です

これで本番環境では S3 に画像を投稿し,読み込みができるようになりました。

ブラウザから https://ドメイン名 にアクセスし,画像を投稿してみましょう。問題なく画像が投稿・表示できていればOKです。

念のため,AWSにログインし S3 のバケットに画像が保存されているかどうかも確認しておくとよいでしょう。

バケットを選択し,ディレクトリを選択していき,「オブジェクト URL」をクリックして投稿した画像が表示されていればOKです。

11. CloudFront

最後に CloudFront を用いて画像の表示を高速化できるようにし,さらに画像のURLを独自ドメインに変更しましょう。

CloudFront も1年間は無料利用枠があり,料金も安いのであまり気にしなくてよいでしょう。

11.1 ACM

CloudFront で ACM 証明書を使用するには、「米国東部」リージョンで証明書をリクエストする必要があります。

  • AWS の画面左上の「サービス」を開き、検索欄に「acm」と入力し、「Certificate Manager」を選択

  • 【重要!】右上の「東京」を「米国東部 (バージニア北部)us-east-1」に変更

11_1a.png

  • 「証明書のプロビジョニング」の「今すぐ始める」ボタンをクリック

  • 「パブリック証明書のリクエスト」を選択した状態で「証明書のリクエスト」ボタンをクリック

  • static.ドメイン名 を入力

    • static の箇所は任意ですが,変更する場合は以降も合わせて変更して下さい

11_1b.png

  • 「次へ」ボタンをクリック

  • 「DNS の検証」を選択した状態で「次へ」ボタンをクリック

タグ名
Name アプリ名_cloudfront

11_1c.png

  • 「確認」ボタンをクリック

  • 「確定とリクエスト」ボタンをクリック

  • 「続行」ボタンをクリック

  • DNS検証用の CNAME レコードを追加(8.2参照)

11.3 の作業は,状況が「検証保留中」から「発行済み」に変わってから行う必要があるため,ブラウザのタブは残しておきましょう

11.2 CarrierWaveの設定

次に,Railsアプリ側のCarrierWaveの設定に追記しましょう。

config/initializers/carrier_wave.rb
if Rails.env.production?
  CarrierWave.configure do |config|
    config.fog_credentials = {
      provider: "AWS",
      aws_access_key_id: Rails.application.credentials.dig(:aws, :access_key_id),
      aws_secret_access_key: Rails.application.credentials.dig(:aws, :secret_access_key),
      region: "ap-northeast-1"
    }
    config.fog_directory = "S3のバケット名"
    # ***** 以下を追加 *****
    config.asset_host = "https://static.ドメイン名"
    # ***** 以上を追加 *****
  end
end

コミット・プッシュ(必要があればプルリク・マージ)などを行い,GitHub の master ブランチに変更を反映した上で,AWS にデプロイを行いましょう。

ローカル環境のターミナル
bundle exec cap production deploy

11.3 CloudFront

【注意】 ACM の状況が「検証保留中」から「発行済み」に変わってから行って下さい

  • 画面左上の「サービス」を開き、検索欄に「cloudfront」と入力し、「CloudFront」を選択

  • 「Create Distribution」ボタンをクリック

  • 「Web」の方の「Get Started」を選択

【Origin Settings】

キー
Origin Domain Name S3のバケット名を選択
Restrict Bucket Access Yes

11_3a.png

【Default Cache Behavior Settings】

キー
Viewer Protocol Policy Redirect HTTP to HTTPS

11_3b.png

【Distribution Settings】

キー
Alternate Domain Names static.ドメイン名
SSL Certificate Custom SSL Certificate をチェックし,自分のドメインを選択

11_3c.png

他はデフォルト設定のまま,右下の「Create Distribution」ボタンをクリック

【注意】 続きの作業は「Status」が「Deployed」になってから行ってください。

11.4 Route 53

最後に CloudFront 用のAレコードを作成しましょう。

  • AWS の画面左上の「サービス」を開き、検索欄に「route」と入力し、「Route 53」を選択

  • 「ホストゾーン」をクリック

  • アプリで使用するドメインをクリック

  • 「レコードを作成」ボタンをクリック

  • 「シンプルルーティング」にチェックを入れた状態で「次へ」ボタンをクリック

  • 「シンプルなレコードを定義」ボタンをクリック

キー
レコード名 static
値/トラフィックのルーティング先 CloudFront ディストリビューションへのエイリアス
米国東部 (バージニア北部)
CloudFrontのドメイン名を選択
レコードタイプ A

11_4.png

  • 「シンプルなレコードを定義」ボタンをクリック

これで全ての設定が完了です。

ブラウザから https://ドメイン名 にアクセスし,再度画像を投稿してみましょう。問題なく画像が投稿・表示できていればOKです。

念のため,AWSにログインし S3 のバケットに画像が保存されているかどうかも確認しておくとよいでしょう。

「無事全てが完了した!!」という方は是非 LGTM もお願いいたします!

12. 削除方法

AWS は有料ですので,アプリの公開が不要となったタイミングで削除することをお勧めします。

以下,削除の手順を解説しますが,特に有料となっている以下の削除を忘れないようにしましょう。

  • RDSインスタンス【高額!】
  • ALB(ロードバランサ)【高額!】
  • EC2インスタンス【高額!】
  • Elastic IP(EC2を削除すると課金対象)
  • Route 53
  • ACM
  • S3(画像投稿機能を付けた場合)
  • CloudFront(画像投稿機能を付けた場合)

12.1 Route 53 の削除

  • Route 53 ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「route」と入力し、「Route 53」を選択)
  • 画面左のメニューバーの「ホストゾーン」をクリック

  • アプリで使用したドメインをクリック

  • タイプが ACNAME のものにチェックを入れ,「削除」ボタンをクリックし,さらに「削除」ボタンをクリック

  • 右上の「削除」ボタンをクリック

  • 「削除」と入力し,「削除」ボタンをクリック

12.2 ALB の削除

  • EC2 ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「ec2」と入力し、「EC2」を選択)
  • 画面左のメニューバーの「ロードバランサー」をクリック

  • 「アクション」ボタンをクリックし,「削除」をクリック

    • 使用しているロードバランサーが表示されない場合は,右上のリージョンが「東京」になっているか確認
  • 「削除」をクリック

12.3 CloudFront の削除

【備考】画像投稿機能を付けていない場合は,次に進んで下さい。

  • CloudFront ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「cloudfr」と入力し、「CloudFront」を選択)
  • 使用している Distribution にチェックを入れて,「Disable」ボタンをクリック

  • 「Yes, Disabled」ボタンをクリック

「Status」が「Disabled」になるまで待ちましょう

  • 使用している Distribution にチェックを入れて,「Delete」ボタンをクリック

  • 「Yes, delete」ボタンをクリック

  • 「Close」ボタンをクリック

12.4 SSL証明書 の削除

  • Certificate Manager ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「acm」と入力し、「Certificate Manager」を選択)
  • アプリで使用したドメインを選択し,「アクション」ボタンをクリックし,「削除」をクリック

  • 「削除」ボタンをクリック

【備考】画像投稿機能を付けている場合は,「東京」リージョンだけでなく「バージニア北部」リージョンのACMも削除して下さい。

12.5 EC2 の削除

  • EC2 ダッシュボードに移動
    • (画面左上の「サービス」を開き、検索欄に「ec2」と入力し、「EC2」を選択)

ターゲットグループの削除

  • 画面左のメニューバーの「ターゲットグループ」をクリック

  • アプリで使用していたものを選択した状態で「Action」のプルダウンの「Delete」をクリック

  • 「Yes, delete」ボタンをクリック

EC2 インスタンスの削除

  • 画面左のメニューバーの 「インスタンス」をクリック
  • 削除したいインスタンスを選択した状態で「アクション」ボタンをクリックし,「インスタンスの状態」「インスタンスを終了」をクリック(「停止」ではない)
  • 「終了」ボタンをクリック

Elastic IP の解放

  • 画面左のメニューバーの Elastic IP をクリック
  • 削除したい Elastic IP を選択した状態で「アクション」ボタンをクリックし,「Elastic IPアドレスの解放」をクリック
    • EC2終了後少し待たないと解放できません
  • 削除したい Elastic IP が消えたことを確認

その他

  • 「キーペア」も削除しましょう
  • 「セキュリティグループ」は VPC 削除時に自動的に削除されます

12.6 RDS の削除

  • RDS ダッシュボードに移動
    • (画面左上の「サービス」を開き、検索欄に「rds」と入力し、「RDS」を選択)

s RDS インスタンスの削除

  • 画面左のメニューバーの「データベース」をクリック
  • 削除したい DB を選択し,「アクション」ボタンをクリックし,「削除」をクリック
  • 「最終スナップショットを作成しますか?」のチェックを外し,「インスタンスの削除後、システムスナップショットとポイントインタイムの復元を含む自動バックアップが利用不可となることを了承しました。」にチェックを入れ,フィールドに「delete me」を入力して「削除」ボタンをクリック

その他

  • 「サブネットグループ」を削除
    • RDSが削除されるまで削除できません
  • 「パラメータグループ」は残してよいでしょう。

12.7 VPC の削除

  • VPC ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「vpc」と入力し、「VPC」を選択)
  • 削除したい VPC を選択し,「アクション」ボタンをクリックし,「VPC を削除」をクリック

  • フィールドに「削除」と記入して「削除」ボタンをクリック

サブネット,インターネットゲートウェイ,ルートテーブルも同時に削除されます。

12.8 S3/IAM の削除

【備考】画像投稿機能を付けていない場合は,次に進んで下さい。

S3 の削除

  • S3 ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「s3」と入力し、「S3」を選択)
  • アプリで使用したバケットを選択し,「空にする」ボタンをクリック

  • 「完全に削除」と入力し「空にする」ボタンをクリック

  • 「終了」ボタンをクリック

  • 「削除」ボタンをクリック

  • 「バケット名」を入力し,「バケットを削除」ボタンをクリック

IAM の削除

  • IAM ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「iam」と入力し、「IAM」を選択)
  • 画面左のメニューバーの「ユーザー」をクリック

  • 「アプリ名_user」にチェックを入れ,「ユーザーの削除」ボタンをクリック

    • アプリと関係ないものを削除しないように注意!
  • 「はい,削除します」ボタンをクリック

12.9 キーペアの削除

GitHub の公開鍵を削除

  • ブラウザでGitHubにアクセス
  • 右上のサムネイル画像をクリック
  • 「Settings」をクリック
  • 左メニューバーから「SSH and GPG keys」をクリック
  • 「アプリ名_git_rsa/pub」の箇所で「Delete」ボタンをクリック
  • 「I understand, please delete this SSH key」ボタンをクリック

ローカル環境のキーペアの削除

最後に,ローカル環境の秘密鍵と設定を削除しておきましょう。

ローカル環境のターミナル
cd ~/.ssh
rm -f アプリ名.pem
vi config
# Host アプリ名 の設定を削除
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

サルでもできる!? Rails6アプリをAWS EC2にデプロイするまでの全手順【前半】(VPC, RDS, EC2, Capistrano)

この記事では,画像投稿機能の付いた Rails 6 のアプリを AWS EC2 にデプロイするまでの全過程を解説します。

Railsアプリのデプロイに関する記事はたくさん見かけますが,初学者にとっては

「具体的に何をすればよいかが分からない:sweat:

記事がほとんどで,ましてや「独自ドメインの設定方法」や「投稿画像を独自ドメインでCloudFrontから配信する方法」まで網羅的に解説を行っている記事は見当たらない状態です。

そこで,「Rails初学者が初めてAWSにデプロイする際に本当に参考となる記事」を目指して書かせていただきました。

Heroku にデプロイしたことはあるけれど,AWS にデプロイしたことがない」という方を対象としますので,AWS の操作は,直感的に操作できる AWS マネジメントコンソール で行います。

AWS CLITerraform などのツールは使用しませんので,あらかじめご了承下さい。

タイトル
【前半】 <-- こちら
1章 はじめに
2章 VPC
3章 RDS
4章 EC2
5章 サーバー構築
6章 デプロイ(Capistrano)
【後半】
7章 独自ドメイン
8章 HTTPS化(ACM, ALB)
9章 デプロイ関連事項
10章 S3
11章 CloudFront
12章 削除方法

1. はじめに

1.1 注意事項

この記事における注意事項を列記します。

料金

AWS は有料のサービスで,いわゆる従量課金制です(サービスの使用量に応じて料金が決まります)。

この記事の構成で AWS を利用した場合,ポートフォリオのようにあまりアクセスが来ないアプリであっても,(無料利用枠を使用する前提で)月におよそ3000円前後かかります。

RDS, ALB などを使用せず, EC2 にデータベースシステムをインストールする構成にすればもっと安く済ませることができますが,ポートフォリオのアピール材料としては弱くなるでしょう。

なお,エラーが発生した際に原因を特定しやすくするため,AWS へのデプロイはアプリの 完成後ではなく開発初期の段階 から行うことをお勧めします。

ただ,料金の問題がありますので,アプリの開発初期は Heroku にデプロイし,仕上げの段階で AWS にデプロイするという手法もありでしょう。

Railsアプリの条件

AWSにデプロイ予定のアプリが,以下の条件を満たすことを前提とします。

  • アプリの Rails のバージョンが 6 であること(5でも多分OK)

  • データベースは MySQL 5.7 もしくは PostgreSQL を使用

  • 画像投稿機能がある場合は CarrierWave を使用

6.1 に画像投稿機能の付いたサンプルアプリを作成する方法を紹介しておりますので,必要がございましたらご利用下さい。

構成図

以下のような一般的な構成を目指します。(料金の都合上,冗長化は行いません)

1_1.png

サーバー環境

  • 【Web サーバー】 Nginx
  • 【アプリケーションサーバー】 Puma

使用する AWS のサービス

  • VPC(Amazon Virtual Private Cloud)
  • RDS(Amazon Relational Database Service)
  • EC2(Amazon Elastic Compute Cloud)
  • Route 53
  • ACM(Certificate Manager)
  • ALB(Application Load Balancer)
  • S3(Amazon Simple Storage Service)
  • IAM(AWS Identity and Access Management)
  • CloudFront

基礎知識の解説

この記事は,「画像投稿機能の付いた Rails アプリを AWS EC2 にデプロイし,独自ドメインでアクセスできるようにする」ことを主目的としております。

最低限度知っておくべき内容は触れますが,インフラの基礎知識は解説しません。

AWS に必要な基礎知識を学べる本はたくさんありますし,Udemyにも丁寧な解説動画が存在します。デプロイの完了後でもよいですので,是非学習されることをお勧めします。

注意点

理解が不十分な状態で進められる場合は, 絶対にミスをしない ように気を付けて下さい。1つのミスで最初からやり直すことになり,数時間の作業が無駄になる可能性があります。

コメントについて

記事内の改善点・間違いなどございましたら,遠慮なくご指摘下さい。可能な限りで記事にも反映させていただきます。

Qiita上の質問には原則お答えする時間が取れませんので,あらかじめ了解いただいた上でご質問下さい。

メモ

作業中にパスワードなど各自設定が異なる部分が複数存在します。メモ帳に以下を貼り付け,決まり次第埋めていくようにされるとよいでしょう。

メモ
【アプリ名】



【RDS】

●マスターユーザー名



●マスターパスワード


●エンドポイント


【EC2】

●Elastic IP


●sshでサインインするときのコマンド

ssh アプリ名

●ユーザー名



●パスワード

【ドメイン】

●ドメイン名


●ネームサーバー情報

【S3】

●バケット名


●リージョン


【IAM】

●ユーザー名


●アクセスキーID


●シークレットアクセスキー


【CloudFront】

static.ドメイン名

まずは,AWSで使用する アプリ名 を決め,上記にメモして下さい。ただし,「aws_sample_app」のように スネークケース 表記であることを前提とします。(アルファベット大文字は使わないで下さい)

「(AWSで使用する)アプリ名」は,「Railsのアプリ名」「GitHubのリポジトリ名」と合わせる方が混乱しづらいと思いますが,同じでなくても問題ありません。

以下, アプリ名 と記載している箇所は,全てこのメモ通りにして下さい。

1.2 AWSアカウントの作成・初期設定

要点のみ記載します。

  • AWSアカウントの作成

    • https://portal.aws.amazon.com/billing/signup
    • メールアドレス・パスワードは超重要です。絶対に忘れないようにし,また他人に知られないように注意しましょう。不正利用されると高額の料金を請求される可能性があります。
    • パスワードは,大文字・小文字・数字・記号を含む16文字以上の強固なものを設定しましょう。
    • サポートプランは特に用事がなければ「ベーシックプラン」でOK
  • 「セキュリティステータス」に全てチェックが入るように設定を進めましょう。

【お勧め参考記事】 https://qiita.com/tmknom/items/303db2d1d928db720888

  • ルートアカウントの MFA を有効化
    • セキュリティ向上のため2段階認証を導入
  • 個々の IAM ユーザーの作成
    • 最初に発行される「ルートアカウント」は,セキュリティの都合上,今後サインインに使用しないようにします
    • 普段のサインインに使用する IAM ユーザーを作成
    • 「パスワードのリセットが必要」は不要なのでチェックを外しましょう
    • 今後のサインインに必要となる「アカウントID」「ユーザー名」「パスワード」を忘れないようにしましょう
  • グループを使用してアクセス許可を割り当て
    • ほぼ全ての権限を持つ「AdministratorAccess」のポリシーを持つグループを作成し,作成した IAM ユーザーを追加
  • IAMパスワードポリシーの適用

最後に「請求アラーム」を作成し,課金状況を確認できるようにしておくことをお勧めします。

【お勧め参考記事】 https://www.kakiyoro.com/archives/2198

2. VPC

Amazon VPC とは Amazon Virtual Private Cloud の略称で,ユーザー専用のプライベートなネットワーク空間を構築できるサービスです。

RailsアプリをAWSで動作させるために,Webサーバーを配置する EC2 とデータベースシステムを動かす RDS を使用しますが,これらを配置するには先に VPC を設定する必要があります。

Amazon VPC は追加料金なしで使用できます。(参考:https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html

2.1 VPC の作成

2章では以下の部分を作成していきます。

2_0.png

【注意】 メニューバー右側の真ん中に「米国」などと表示されている場合は,「東京(アジアパシフィック(東京) ap-northeast-1)」に変更して下さい

2_1a.png

  • 画面左上の「サービス」を開き、検索欄に「VPC」と入力し、「VPC」を選択

2_1b.png

【注意】 以下,左上の「New VPC Experience」をONにしていることを前提とします。

  • 画面左のメニューバー(もしくは,ダッシュボード内の)の「VPC」をクリック

2_1c.png

  • 「VPCを作成」ボタンをクリック
キー
名前タグ アプリ名_vpc
IPv4 CIDR ブロック 10.0.0.0/16

【注意】1章で注意しましたとおり,「アプリ名」の箇所はあらかじめ メモ しておいた「アプリ名」を使用して下さい

  • 他はデフォルトのままで「VPCを作成」ボタンをクリック

2_1d.png

2.2 サブネット の作成

VPCの中に,「インターネットから直接通信できる EC2用 のサブネット」と「インターネットから直接通信できない RDS用 のサブネット」を2つずつ作成していきましょう。(許可する接続方法は後に設定します)

  • 画面左のメニューバーから「サブネット」を選択

EC2 用のサブネット

HTTPS化 する際に ALB を使用するため,異なる アベイラビリティーゾーン に属するサブネットを 2つ 用意する必要があります。

  • 「サブネットの作成」ボタンをクリック
キー
VPC アプリ名_vpc ※リストから選択

2_2a.png

キー
名前タグ アプリ名_public_1a_subnet
アベイラビリティーゾーン ap-northeast-1a ※リストから選択
IPv4 CIDR ブロック 10.0.0.0/24

2_2b.png

  • 「新しいサブネットを追加」ボタンをクリック
キー
名前タグ アプリ名_public_1c_subnet
アベイラビリティーゾーン ap-northeast-1c ※リストから選択
IPv4 CIDR ブロック 10.0.1.0/24

※ まだ作成しますので,「サブネットを作成」ボタンをクリックしないこと!

RDS 用のサブネット

RDS を利用するには異なる アベイラビリティーゾーン に属するサブネットを 2つ 用意する必要があります。

  • 「新しいサブネットを追加」ボタンをクリック
キー
名前タグ アプリ名_private_1a_subnet
アベイラビリティーゾーン ap-northeast-1a
IPv4 CIDR ブロック 10.0.10.0/24
  • 「新しいサブネットを追加」ボタンをクリック
キー
名前タグ アプリ名_private_1c_subnet
アベイラビリティーゾーン ap-northeast-1c
IPv4 CIDR ブロック 10.0.11.0/24
  • 「サブネットを作成」ボタンをクリック

  • 下図の状態になっていることを確認しておきましょう

2_2c.png

2.3 インターネットゲートウェイ の作成

VPC 内から インターネット に接続するための「出入口」に相当する インターネットゲートウェイ を作成しましょう。

  • 画面左のメニューバーから「インターネットゲートウェイ」を選択
  • 「インターネットゲートウェイの作成」ボタンをクリック
キー
名前タグ アプリ名_gateway

2_3a.png

  • 他はデフォルトのままで「インターネットゲートウェイの作成」ボタンをクリック
  • フラッシュで表示されている「VPCへアタッチ」をクリック
    • (「アクション」を選択し、「VPCにアタッチ」を選択してもOK)
キー
使用可能なVPC アプリ名_vpc
  • 「インターネットゲートウェイのアタッチ」ボタンをクリック

2_3b.png

2.4 ルートテーブル の作成

インターネットゲートウェイ をアタッチしただけでは,サブネットからインターネットにアクセスすることはできません。
インターネットゲートウェイ へ転送する経路である ルートテーブル を設定する必要があります。

  • 画面左のメニューバーから「ルートテーブル」を選択
  • 「ルートテーブルの作成」ボタンをクリック
キー
名前タグ アプリ名_table
VPC アプリ名_vpc

2_4a.png

  • 「作成」ボタンをクリック
  • 「閉じる」ボタンをクリック

  • 作成したルートテーブルを選択し,「アクション」ボタンをクリックし,「ルートの編集」を選択

2_4b.png

  • 「ルートの追加」ボタンをクリック
    • local を消さないこと!
キー
送信先 0.0.0.0/0
ターゲット 「Internet Gateway」を選択し,先ほど作成した「アプリ名_gateway」を選択

2_4c.png

2_4d.png

  • 「ルートの保存」をクリック
  • 「閉じる」ボタンをクリック

  • (作成したルートテーブルを選択したまま)「アクション」ボタンをクリックし,「サブネットの関連付けの編集」を選択

  • 「アプリ名_public_1a_subnet」「アプリ名_public_1c_subnet」のみを選択し,「保存」ボタンをクリック

2_4e.png

2.5 セキュリティグループ の作成

インスタンスごとに許可する通信を設定するため, セキュリティグループ を作成しておきましょう。

EC2RDS に適用する作業は,後で行います)

EC2 用のセキュリティグループ

【構成内容】 クライアント --(HTTP or SSH)--> EC2

  • 画面左のメニューバーの「セキュリティグループ」を選択

2_5a.png

  • 「セキュリティグループを作成」ボタンをクリック
キー
セキュリティグループ名 アプリ名_ec2_security_group
説明 アプリ名_ec2_security_group
VPC アプリ名_vpc

「インバウンドルール」の「ルールを追加」を2回クリック

キー
タイプ HTTP ※「HTTPS」ではありません!
プロトコル TCP ※自動選択
ポート範囲 80 ※自動選択
ソース 任意の場所 (0.0.0.0/0 と ::/0 が表示)
説明 ※空白でOK
キー
タイプ SSH
プロトコル TCP ※自動選択
ポート範囲 22 ※自動選択
ソース マイIP (自分のグローバルIPが表示)
説明 ※空白でOK

2_5b.png

【注意】ソースを マイIP とすることで,SSH接続できるIPアドレスを制限できます。ただし,自宅以外で EC2 にアクセスする可能性がある場合は,他のIPアドレスも登録が必要です。(意味が分からない場合は, SSH のソースも 任意の場所 に設定して下さい)

RDS 用のセキュリティグループ

【構成内容】 EC2 --(TCP)--> RDS

データベースは EC2 からのリクエストのみを受け付けるように設定しておきます。

画面左のメニューバーの「セキュリティグループ」を選択し,「セキュリティグループを作成」ボタンをクリック

キー
セキュリティグループ名 アプリ名_db_security_group
説明 アプリ名_db_security_group
VPC アプリ名_vpc

「インバウンドルール」の「ルールを追加」をクリック

【注意】アプリで使用するデータベースシステムを確認し,「いずれか一方」のルールを追加して下さい

  • MySQL の場合
キー
タイプ MySQL/Aurora
プロトコル TCP ※自動選択
ポート範囲 3306 ※自動選択
ソース カスタム : アプリ名_ec2_security_group
説明 ※空白でOK

2_5c.png

「セキュリティグループを作成」をクリック

  • PostgreSQL の場合
キー
タイプ PostgreSQL
プロトコル TCP ※自動選択
ポート範囲 5432 ※自動選択
ソース カスタム : アプリ名_ec2_security_group
説明 ※空白でOK

2_5d.png

「セキュリティグループを作成」をクリック

3. RDS

Amazon RDS とは Amazon Relational Database Service の略称で,MySQLPostgreSQL のようなデータベース管理システム(DBMS)を最適な動作条件で利用できるサービスです。

RDS は運用負荷が低く非常に便利なのですが,コストが高い ため注意が必要です。

AWSアカウント作成後,1年間は一定の条件で無料となりますが,不要になった時点で削除することをお勧めします。

3.1. サブネットグループの作成

2.2 で作成した RDS 用のサブネット2つをグループ化しましょう。

  • 画面左上の「サービス」を開き、検索欄に「RDS」と入力し、「RDS」を選択

  • 画面左のメニューバーの「サブネットグループ」を選択し,右上の「DB サブネットグループを作成」ボタンをクリック

  • サブネットグループの詳細

キー
名前 アプリ名_subnet_group_db
説明 アプリ名_subnet_group_db
VPC アプリ名_vpc
  • サブネットの追加
    • 異なる アベイラビリティーゾーン に属するサブネットを2つ以上選択する必要があります
    • マルチ AZ 構成時に必要となるため,今回のように マルチ AZ を使用しない場合にも必須となります
キー
アベイラビリティーゾーン ap-northeast-1a, ap-northeast-1c
サブネット 10.0.10.0/24, 10.0.11.0/24 の2つを選択

3_1.png

「作成」ボタンをチェック

3.2 パラメータグループの作成(MySQL限定)

【注意】PostgreSQL の場合はスキップして下さい

RDSMySQL のデフォルト文字コードは latin1 であり,日本語に対応していません。

文字コードを変更するためのパラメータグループを先に作成しておきましょう。

(1度作成すれば使い回しが可能です)

  • 画面左のメニューバーの「パラメータグループ」を選択

「パラメータグループの作成」ボタンをクリック

  • パラメータグループの詳細
キー
パラメータグループファミリー mysql5.7
グループ名 mysql57-supported-in-ja
説明 parameter group for mysql5.7 supported in ja
  • 作成した「mysql57-supported-in-ja」をクリック

  • 「パラメータの編集」ボタンをクリック

  • 検索窓にキーをコピペして値を変更

キー
character_set_client utf8
character_set_connection utf8
character_set_database utf8mb4
character_set_results utf8
character_set_server utf8mb4
skip-character-set-client-handshake 1
  • 「変更の保存」ボタンをクリック

3.3 DBインスタンスの作成

画面左のメニューバーの「データベース」を選択

「データベースを作成」ボタンをクリック

「MySQL」の場合と「PostgreSQL」の場合で設定が異なりますので,いずれか片方を実行して下さい。

3.3.1 MySQLの場合

  • データベース作成方法を選択

「標準作成」を選択

  • エンジンのオプション
キー
エンジンのタイプ MySQL
バージョン MySQL 5.7.* (*の箇所は最新のものを推奨)
  • テンプレート

「無料利用枠」を選択

3_3ma.png

  • 設定

【注意】ここの「アプリ名」の _ は ハイフン - とすること
【注意】マスターユーザー名・パスワードをメモしておくこと

キー
DB インスタンス識別子 アプリ名-db
マスターユーザー名 root
マスターパスワード 任意
  • DB インスタンスサイズ

db.t2.micro(デフォルト)

3_3mb.png

  • ストレージ

※デフォルト設定で

  • 可用性と耐久性

※デフォルト設定で

3_3mc.png

  • 接続

「アプリ名_vpc」を選択

  • 「追加の接続設定」のドロップダウンをクリック
キー
サブネットグループ アプリ名_subnet_group_db ※2.1で作成
セキュリティグループ アプリ名_db_security_group ※1.5で作成, default は外す
アベイラビリティーゾーン ap-northeast-1a

3_3md.png

  • データベース認証

※デフォルト設定で

  • 「追加設定」をクリック

  • データベースの選択肢

キー
最初のデータベース名 アプリ名_production
DB パラメータグループ mysql57-supported-in-ja
オプショングループ ※デフォルト設定
  • バッグアップ以降

※デフォルト設定で

3_3me.png

3_3f.png

  • 「データベースの作成」ボタンをクリック

3.3.2 PostgreSQLの場合

まず,ターミナルでローカルで使用している PostgreSQL のバージョンを確認しておきましょう。

psql -V
  • データベース作成方法を選択

「標準作成」を選択

  • エンジンのオプション

PostgreSQL のバージョンは,上記で確認したローカルのバージョンに合わせた方が無難です。

メジャーバージョンを合わせれば十分なので,例えばローカルが 12.3 ならば,12.* (*の箇所は最新のもの) をお勧めします。

2020年11月時点ではバージョンが 13 に対応していないので,ローカルのバージョン 13 の場合は最新のバージョンでよいでしょう。

キー
エンジンのタイプ PostgreSQL
バージョン ※上記を参考に設定
  • テンプレート

「無料利用枠」を選択

3_3pa.png

  • 設定

【注意】ここの「アプリ名」の _ は ハイフン - とすること
【注意】マスターユーザー名・パスワードをメモしておくこと

キー
DB インスタンス識別子 アプリ名-db
マスターユーザー名 postgres
マスターパスワード 任意
  • DB インスタンスサイズ

db.t2.micro(デフォルト)

3_3pb.png

  • ストレージ

※デフォルト設定で

  • 可用性と耐久性

※デフォルト設定で

3_3pc.png

  • 接続

「アプリ名_vpc」を選択

  • 「追加の接続設定」のドロップダウンをクリック
キー
サブネットグループ アプリ名_subnet_group_db ※2.1で作成
セキュリティグループ アプリ名_db_security_group ※1.5で作成, default は外す
アベイラビリティーゾーン ap-northeast-1a

3_3pd.png

  • データベース認証

※デフォルト設定で

  • 「追加設定」をクリック

  • データベースの選択肢

キー
最初のデータベース名 アプリ名_production
DB パラメータグループ ※デフォルト設定
オプショングループ ※デフォルト設定
  • バッグアップ以降

※デフォルト設定で

3_3pe.png

3_3pf.png

  • 「データベースの作成」ボタンをクリック

3.4 エンドポイントの確認

  • アプリ名を選択

  • 「接続とセキュリティ」の「エンドポイント」をメモ

    • データベースが作成されるまで待つ必要がありますので,別タブで次の EC2 の設定に進めるとよいでしょう

3_4.png

4. EC2

Amazon EC2 とは Amazon Elastic Compute Cloud の略称で,コンピューティング性能をクラウド内で提供するサービスです。サーバーに必要なものをクラウド内で借りることができます。

Railsのアプリをこの EC2 にデプロイし,ブラウザからアクセスできるように準備を行います。

EC2 も運用に料金がかかりますので,不要になったインスタンスなどは削除するようにしましょう。

4.1 インスタンスの作成

  • 画面左上の「サービス」を開き、検索欄に「EC2」と入力し、「EC2」を選択

  • 画面左のメニューバーの「インスタンス」を選択し,「インスタンスを起動」ボタンをクリック

ステップ 1: Amazon マシンイメージ (AMI)

「無料利用枠の対象」タグの付いた「Amazon Linux 2 AMI (HVM), SSD Volume Type」「64ビット (x86)」の「選択」ボタンをクリック

4_1a.png

ステップ 2: インスタンスタイプの選択

  • 「無料利用枠の対象」タグの付いた「t2.micro」が選択されていることを確認した上で,「次のステップ」ボタンをクリック
    • 「確認と作成」ボタンをクリックしないこと。クリックした場合は,「戻る」ボタンをクリックしてステップ3まで移動しましょう

4_1b.png

ステップ 3: インスタンスの詳細の設定

キー
ネットワーク アプリ名_vpc
サブネット アプリ名_public_1a_subnet

他はデフォルト設定のまま「次のステップ」ボタンをクリック

4_1c.png

ステップ 4: ストレージの追加

「次のステップ」ボタンをクリック

ステップ 5: タグの追加

「タグの追加」ボタンをクリック

キー
Name 「アプリ名_instance」を選択

4_1d.png

「次のステップ」ボタンをクリック

ステップ 6: セキュリティグループの設定

「既存のセキュリティグループを選択する」にチェック

「アプリ名_ec2_security_group」にチェック

4_1e.png

「確認と作成」ボタンをクリック

ステップ 7: インスタンス作成の確認

  • セキュリティグループの「名前」が「アプリ名_ec2_security_group」になっていることを確認した上で,「起動」ボタンをクリック

既存のキーペアを選択するか、新しいキーペアを作成します。

  • 「新しいキーペアの作成」を選択

  • 「キーペア名」は「アプリ名」を入力

    • メモ しているアプリ名と全く同じにして下さい(ハイフン - を使用せず,アンダースコア _ を使用)
  • 「キーペアのダウンロード」を選択

    • アプリ名.pem をダウンロードできます。後に EC2 のログインで利用します

4_1f.png

「インスタンスの作成」ボタンをクリック

作成ステータス

「インスタンスの表示」ボタンをクリック

4.2 Elastic IPの作成、紐付け

インターネットに接続するには グローバルIPアドレス が必須です。

現状ではこの グローバルIPアドレス は固定化されておらず EC2インスタンス を再起動した際に変更されてしまいます。(URLが変化してしまう!)

Elastic IP 設定することで,グローバルIPアドレス を固定化することができます。

Elastic IP はこれから行う EC2インスタンス との関連付けを行っている状態では無料ですが,関連付けた EC2インスタンス を削除したり停止させると料金が発生するようになります。

EC2インスタンス を削除する際は Elastic IP の開放を忘れないように注意しましょう。

Elastic IPの作成

  • 画面左のメニューバーの「Elastic IP」を選択

  • 「Elastic IP アドレスの割り当て」ボタンをクリック

  • 「割り当て」ボタンをクリック

Elastic IPの紐付け

  • 先ほど割り当てた Elastic IP を選択した状態で、「アクション」ドロップダウンを選択し、「Elastic IP アドレスの関連付け」をクリック

4_2a.png

ここで,表示されている Elastic IP は必ずメモしておいて下さい。

キー
インスタンス アプリ名_instance
プライベート IP アドレス ※クリックして表示されるIPを選択
再関連付け チェックを入れる

4_2b.png

  • 「関連付ける」ボタンをクリック

4.3 EC2へのログイン

アプリ名を定義(ローカル環境)

作業ミスを減らすため,ターミナルで頻出する アプリ名 を一時的にグローバル変数として定義しておきましょう。

アプリ名 の箇所は,各自がメモしているものに置き換えて実行して下さい。

ターミナル
APP_NAME=アプリ名
echo $APP_NAME
(例)
APP_NAME=aws_sample_app
echo $APP_NAME

最後のコマンドで,「アプリ名」が正しく表示されていることを確認した上で,以下を実行して下さい。

【補足】間違った場合は再度上記を実行し直してから進めて下さい。また,コマンドは原則コピペして下さい。1文字間違っただけで大きく時間をロスする可能性があります。

ターミナル
# zsh の場合
echo "export APP_NAME=$APP_NAME" >> ~/.zshrc
source ~/.zshrc

# bash の場合
echo "export APP_NAME=$APP_NAME" >> ~/.bash_profile
source ~/.bash_profile

【備考】 使用しているシェルスクリプトが zshbash か分からない場合は echo $SHELL を実行して確認して下さい

4_3a.png

キーペアの移動・アクセス権の付与

【参考】 https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-key-pairs.html

4.1 でダウンロードしたキーペア アプリ名.pem.ssh ディレクトリに移動し,利用できる状態にしておきましょう。

ターミナル
cd
mkdir .ssh
mv Downloads/$APP_NAME.pem .ssh
chmod 400 .ssh/$APP_NAME.pem
ls -l .ssh/$APP_NAME.pem

最後のコマンドで -r-------- (略) .ssh/アプリ名.pem が表示されていればOKです。

【補足】mv コマンド実行時に No such file or directory が表示された場合は,Google Chrome の下に現れている アプリ名.pem のドロップダウンメニューから,キーペアの場所を確認して,直接,ホームディレクトリの .ssh ディレクトリに移動させて下さい。キーペアのファイル名が アプリ名.pem になっているかどうかも確認しましょう。

EC2 インスタンスの状態を確認

  • EC2 の画面左のメニューバーの「インスタンス」をクリックし,作成した EC2インスタンスの「インスタンスの状態」が 実行中 となっているか確認して下さい
    • 実行中 になっていない場合はしばらく待ってからブラウザをリロードして下さい

【補足】4.2で Elastic IP をメモし忘れた人は,作成した EC2インスタンス を選択し, Elastic IP をメモして下さい

4_3b.png

ssh接続の設定ファイルを作成

EC2インタスタンス にログインするには,「ホスト名」「ユーザー名」「AWSからダウンロードしたキーペア(秘密鍵)」が必要になります。

これらをログインの度に毎回記述するのは面倒なので,設定ファイルに記載し,使える状態にしましょう。

ローカル環境のターミナル
vi ~/.ssh/config

Vim エディタでファイルが開かれますので,以下を記述して下さい。(デフォルトで ec2-user という名前のユーザーが用意されています)

ローカル環境のターミナル(~/.ssh/config)
Host アプリ名
  Hostname ElasticIPを記入
  User ec2-user
  IdentityFile ~/.ssh/アプリ名.pem

【参考】 「アプリ名」が aws_sample_app, 「Elastic IP」が 172.217.161.46 の場合は,次の形式となります。

(例)
Host aws_sample_app
  Hostname 172.217.161.46
  User ec2-user
  IdentityFile ~/.ssh/aws_sample_app.pem

【補足】 Vimの基本

一般のテキストエディタは,ファイルを開いてすぐに文字が入力できます。 Vimインサートモード に変更しなければキー入力ができません。

ここは初学者が非常に混乱しやすいところですので,くれぐれもご注意下さい。

以下は最低限覚えておきましょう。

  • Vim の起動時は「ノーマルモード」
  • 文字をキー入力したいときは i を入力し,「インサートモード」に変更する必要がある
    • 「かな」入力モードでは i を入力しても効果が出ないので,「英数」入力モードに切り替えてから行うこと
  • 「ノーマルモード」への移行は,esc
  • 保存終了は「ノーマルモード」にしてから :wq
  • (保存せずに)強制終了は「ノーマルモード」にしてから :q!

EC2にログイン

それでは, EC2インタスタンス にログインしてみましょう。

ターミナル
ssh アプリ名

Are you sure you want to continue connecting (yes/no/[fingerprint]) と表示されたら,yes と入力してEnterキーを押しましょう。

これで, EC2インタスタンス にログインできます。


【備考】ここでSSH接続できない場合は,以下の可能性があります。

  • 先ほど作成した ~/.ssh/config にミスがある

  • 4.3で,キーペアが指定箇所に移動できていない or パーミッションを適切に変更できていない(ls -l ~/.ssh/$APP_NAME.pem で確認)

  • Elastic IP をメモし間違えている

  • 2.5で作成した「EC2 用のセキュリティグループ(アプリ名_ec2_security_group)」の設定を間違えている

    • SSHのソースが マイIP の場合は,IPアドレスが変わっていないかも確認しましょう(不明な場合は 任意の場所 に変更)
  • 4.1で設定したEC2 用のセキュリティグループが「アプリ名_ec2_security_group」になっていない

  • 2.4で作成したルートテーブルの「サブネットの関連付け」を間違えている


4.4 EC2の初期設定

(参考)Amazon Linux インスタンスでユーザーアカウントを管理する


要注意

今後,EC2にログインした状態の サーバー環境のターミナル と,通常の ローカル環境のターミナル のどちらで操作するかを「必ず」確認して下さい。1度でも間違えると,エラー解決に大きく時間を取られる可能性があります。

なお,一定時間が経過しますと,EC2からログアウトしますので,その点にも注意しましょう。


新規ユーザーアカウントの作成

今後 EC2 での作業や Capistrano で利用するユーザーを作成しましょう。作業を楽にするため,しばらくパスワード無しで sudo コマンドを使える状態にしておきます。

EC2にログインした状態の サーバー環境のターミナル で以下を実行しましょう。

「ユーザー名」の箇所は自由に決め, メモ しておいて下さい。

サーバー環境のターミナル
APP_USER=ユーザー名
echo $APP_USER

最後のコマンドで,「ユーザー名」が正しく表示されていることを確認した上で,以下を実行して下さい。

サーバー環境のターミナル
sudo adduser $APP_USER
echo "$APP_USER ALL=(ALL) NOPASSWD: ALL" | sudo EDITOR='tee -a' visudo > /dev/null
sudo su - $APP_USER
sudo ls

最初の表示が ec2-user から「自分の決めたユーザー名」に変更され,最後のコマンドでパスワードを求められなければOKです。

【補足】2番目の操作は sudo visudo 実行後,一番最後の行に ユーザー名 ALL=(ALL) NOPASSWD: ALL を追加する操作です

アプリ名を定義(サーバー環境)

作業ミスを減らすため,サーバー環境でも「アプリ名」をグローバル変数として定義しておきましょう。

サーバー環境のターミナル
APP_NAME=アプリ名
echo $APP_NAME

最後のコマンドで,「アプリ名」が正しく表示されていることを確認した上で,以下を実行して下さい。

(間違っている場合は再度上記を実行し直してから進めて下さい)

サーバー環境のターミナル
echo "export APP_NAME=$APP_NAME" >> ~/.bash_profile
source ~/.bash_profile

新規ユーザーでssh接続するための設定

新規ユーザーでssh接続できるようにするには,アプリ名.pem (秘密鍵)に対応する 公開鍵EC2~/.ssh/authorized_keys に配置し,適切な権限を与えておく必要があります。

サーバー環境のターミナル
mkdir .ssh -m 700
vi .ssh/authorized_keys

サーバー側でVimエディタが開かれます。

ここで,新しく ローカル 環境のターミナルを用意して下さい。( command + n もしくは command + t

そして, ローカル 環境のターミナルで 秘密鍵(アプリ名.pem) から 公開鍵 をコピーして下さい。

ローカル環境のターミナル
ssh-keygen -y -f ~/.ssh/$APP_NAME.pem | pbcopy

(コマンドを実行するだけでコピーされますので,command + c は不要です。もし pbcopy: command not found が表示される場合は | pbcopy を削って実行し,直接コピーして下さい)

その後,サーバー環境のターミナルに戻って以下の操作を行ってください。

サーバー環境のターミナル
# 公開鍵を貼り付け,保存終了
chmod 600 .ssh/authorized_keys
exit
exit

これで,新しく作成したユーザーでもログインができるようになりました。

ログイン時のユーザー名を変更しましょう。

ローカル環境のターミナル
vi ~/.ssh/config
  • 「ユーザー名」を ec2-user から メモしたユーザー名 に変更しましょう。
ローカル環境のターミナル(~/.ssh/config)
Host アプリ名
  Hostname ElasticIP
  User ユーザー名 ★ここを変更★
  IdentityFile ~/.ssh/アプリ名.pem

yml:(ユーザー名が take の場合)
Host aws_sample_app
Hostname 172.217.161.46
User take
IdentityFile ~/.ssh/aws_sample_app.pem

4.5 今後のEC2のログイン方法

再度,以下のコマンドで EC2インスタンス にログインしてみましょう。

ローカル環境のターミナル
ssh アプリ名

ec2-user ではなく各自が決めたユーザー名でログインできるはずです。

デフォルトユーザーは必要なくなりましたので,削除しておきましょう。

サーバー環境のターミナル
sudo userdel -r ec2-user

5. サーバー構築

Railsアプリを実行できるようにするための環境構築を行っていきます。

EC2インスタンス にログインしていない場合は,次でログインして下さい。

ローカル環境のターミナル
ssh アプリ名

5.1 Nginx の設定

以下の順序で実行していきます。

  • サーバーをアップデート
  • Nginx のインストール
  • Nginx の起動とインスタンス起動時自動起動の設定
サーバー環境のターミナル
sudo yum -y update
sudo amazon-linux-extras install -y nginx1
sudo systemctl start nginx
sudo systemctl enable nginx

ブラウザに Elastic IP を入力してアクセスしましょう。

Welcome to nginx on Amazon Linux! が表示されればOKです。

【補足】ここでアクセスできない場合は,以下の可能性があります

  • 2.5で作成した「EC2 用のセキュリティグループ(アプリ名_ec2_security_group)」の設定を間違えている
    • 「タイプが HTTP, ソースが 0.0.0.0/0::/0」のものが含まれているかを確認。「HTTP」を「HTTPS」にしているミスを見かけます
  • 4.1で設定したEC2 用のセキュリティグループが「アプリ名_ec2_security_group」になっていない

5.2 必要なプラグインのインストール

  • 各種プラグインのインストール
    • 1行のコマンドです
サーバー環境のターミナル
sudo yum -y install git make gcc-c++ patch openssl-devel libyaml-devel libffi-devel libicu-devel libxml2 libxslt libxml2-devel libxslt-devel zlib-devel readline-devel ImageMagick ImageMagick-devel

【注意】上記はあくまで「画像投稿可能なアプリ」のデプロイを想定したものです。アプリに導入されている gem や ライブラリ次第では,依存関係にある他のプラグインもインストールしておく必要があります。

5.3 データベースにログイン

まず,EC2 にプリインストールされている MariaDB を削除しておきましょう。

サーバー環境のターミナル
sudo yum -y remove mariadb-libs

MySQLの場合

以下の順序で実行していきます。

  • MySQL のリポジトリを追加
  • MySQL の5.7がインストールされるように変更
  • MySQL をインストール
サーバー環境のターミナル
sudo yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
sudo yum-config-manager --disable mysql80-community
sudo yum-config-manager --enable mysql57-community
sudo yum -y install mysql-community-client mysql-server mysql-devel

次のコマンドでRDSの MySQL にログインできます。

サーバー環境のターミナル
mysql -h エンドポイント -u root -p
# RDS の パスワード を入力

mysql> という表示が出た後に次を実行して下さい。

サーバー環境のターミナル(mysql)
show databases;
# 表示されたデータベース一覧に,「アプリ名_production」が存在していればOK
exit

【参考】「エンドポイント」は 2.4 で確認したものです。確認できていない場合は RDS の「データベース」をクリックし,アプリを選択して出てくる「エンドポイント」を確認しましょう。


【補足】もし,データベース一覧に,「アプリ名_production」が存在しない場合は,exit; で終了する前に以下を実行してデータベースを作成して下さい。

サーバー環境のターミナル(mysql)
# 「アプリ名_production」が存在しない場合のみ,次を実行して下さい
CREATE DATABASE アプリ名_production;

【参考】 Sequel Proで MySQL に接続する方法

Sequel Pro (nightly バージョン) をインストールしていない場合は,次を実行してインストールしましょう。

ローカル環境のターミナル
brew cask install homebrew/cask-versions/sequel-pro-nightly

これで,アプリケーションディレクトリに Sequel Pro.app が入ります。

  • SSHのタブを選択
キー
MySQL Host RDSのエンドポイントを記載
Username root
Password RDSのパスワードを記載
Database アプリ名_production
Port 3306
SSH Host Elastic IPを記載
SSH User EC2のユーザー名を記載
SSH Password 右側の鍵マークボタンをクリックし「~/.ssh/アプリ名.pem」を選択

【参考】 .ssh は隠しファイルです。隠しファイルを表示するショートカットキーは command + shift + . です。

5_3.png

PostgreSQLの場合

単純にインストールするとバージョンが低すぎるので,amazon-linux-extras リポジトリから PostgreSQL のバージョン11を入れることにしましょう。

サーバー環境のターミナル
sudo amazon-linux-extras install -y postgresql11
yum list | grep postgresql
sudo yum -y install postgresql-devel

【補足】PostgreSQLのバージョン12以上を強引に入れることも可能ですが,postgresql-devel のインストールが難しいのでお勧めしません。なお,インストール可能な最新バージョンは, amazon-linux-extras | grep postgresql で確認できます。


次のコマンドでRDSの PostgreSQL にログインできます。

サーバー環境のターミナル
psql -h エンドポイント -U postgres
# RDS の パスワード を入力

postgres=> という表示が出た後に次を実行して下さい。

サーバー環境のターミナル(PostgreSQL)
\l
# 表示されたデータベース一覧に,「アプリ名_production」が存在していればOK
exit;

【補足】もし,データベース一覧に,「アプリ名_production」が存在しない場合は,exit; で終了する前に以下を実行してデータベースを作成して下さい。

サーバー環境のターミナル(PostgreSQL)
# 「アプリ名_production」が存在しない場合のみ,次を実行
CREATE DATABASE アプリ名_production;

【参考】 Postico で PostgreSQL に接続する方法

https://eggerapps.at/postico

インストールしていない場合は,上記サイトの Download ボタンをクリックし,zipファイルを解凍して出てくる Postico をアプリケーションに移動した上で,実行して下さい。

  • Postico を起動し,左下の「New Favorite」をクリック

  • Options のドロップダウンを開き, Connect via SSH をクリック

キー
Nickname ※任意 (アプリ名_production など)
Host RDS のエンドポイントを記載
Port ※不要
User postgres
Password RDSのパスワードを記載
Database アプリ名_production
SSH Host Elastic IPを記載
User EC2のユーザー名を記載
Password ※不要
Private Key 「Choose」をクリックし,「~/.ssh/アプリ名.pem」を選択

「Connect」を選択し,再度「Connect」を選択

5_3b.png

5.4 Node, Yarn のインストール

サーバー環境のターミナル
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
. ~/.nvm/nvm.sh
nvm install node
node -e "console.log('Running Node.js ' + process.version)"

最後のコマンドで Running Node.js バージョン が表示されればOKです。

  • Yarn のインストール
サーバー環境のターミナル
curl -o- -L https://yarnpkg.com/install.sh | bash

5.5 Rubyのインストール

  • rbenv のインストール
サーバー環境のターミナル
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
source ~/.bash_profile
  • ruby-build のインストール
サーバー環境のターミナル
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
  • Ruby のインストール

まず,デプロイするアプリの Ruby のバージョンを確認して下さい。

ローカル環境のターミナル でアプリのディレクトリまで移動し ruby -v で確認できます)

以下は,バージョンが 2.6.6 の場合の例です。バージョンはアプリに「必ず」合わせて下さい。

サーバー環境のターミナル
rbenv install 2.6.6
rbenv global 2.6.6
rbenv rehash

Ruby のインストールには時間がかかります。

  • Bundler のインストール
サーバー環境のターミナル
gem install bundler

完了後に以下を実行し,全てバージョンが表示されればOKです。

サーバー環境のターミナル
rbenv -v
ruby -v
yarn -v
bundler -v

5.6 デプロイ先ディレクトリの設定

(デフォルト設定の場合) Capistrano によるアプリのデプロイ先は /var/www/アプリ名 ディレクトリになります。

そこで,このディレクトリをあらかじめ作成しておき,必要な権限を与えておきましょう。

サーバー環境のターミナル
sudo mkdir -p /var/www/$APP_NAME
sudo chown `whoami`:`whoami` /var/www/$APP_NAME
ls -l /var/www

最後のコマンドで drwxr-xr-x 2 ユーザー名 ユーザー名 日付 アプリ名 が表示されればOKです。

5.7 Git の初期設定

次に,サーバー環境で GitHub の操作ができるようにしていきましょう。

まずは,サーバー環境の Git の初期設定を行いましょう。ここでは,ローカル環境と同じ「ユーザー名」「メールアドレス」を登録することとしておきます。

まず, Git に登録した名前とメールアドレスを確認しましょう。

ローカル環境のターミナル
cat ~/.gitconfig

次の箇所をコピーして下さい。

出力内容の一部
[user]
    name = ~~~~~
  email = ~~~~~@~~~.~~~
  • .gitconfig ファイルの生成
サーバー環境のターミナル
cd
vi .gitconfig
  • Vimが開いたら先ほどコピーしたものをペーストしましょう。

5.8 GitHub連携

サーバー環境に GitHub へのアクセス権限を持たせるため,必要な公開鍵・秘密鍵を生成しましょう。

サーバー環境のターミナル
cd .ssh
ssh-keygen -t rsa -f "${APP_NAME}_git_rsa" -N ""
  • これで,以下のファイルが作成されます

    • 公開鍵(GitHubに配置する鍵) アプリ名_git_rsa.pub
    • 秘密鍵(EC2に残しておく鍵) アプリ名_git_rsa
  • config ファイルの生成

サーバー環境のターミナル
vi config
  • Vimでファイルが開かれたら次を追加
    • 「アプリ名」の箇所は各自の設定に合わせること
~/.ssh/config
Host github github.com
  Hostname github.com
  User git
  IdentityFile ~/.ssh/アプリ名_git_rsa
  • GitHubに公開鍵を登録

以下を実行し,値をコピーしておきましょう。

サーバー環境のターミナル(~/.ssh)
cat "${APP_NAME}_git_rsa.pub"

5_8a.png

  1. ブラウザでGitHubにアクセス
  2. 右上のサムネイル画像をクリック
  3. 「Settings」をクリック
  4. 左メニューバーから「SSH and GPG keys」をクリック
  5. 「SSH Keys」の「New SSH key」をクリック

5_8b.png
5_8c.png

キー
Title アプリ名_git_rsa.pub
Key サーバー環境のターミナルからコピーした値をペースト

5_8d.png

「Add SSH key」ボタンをクリック

  • サーバーから GitHub に接続できるか確認
サーバー環境のターミナル(~/.ssh)
chmod 600 config
ssh github

yes を入力し,次の赤枠の内容が出力されればOKです。

5_8e.png

6. デプロイ(Capistrano)

Capistrano を使い,1コマンドで Rails アプリを AWS EC2 にデプロイできる状態にしていきましょう。

サンプルのアプリをデプロイされたい場合は 6.1 から進めて下さい。オリジナルのアプリをデプロイされる場合は 6.2 から進めて下さい。

なお,オリジナルアプリのデプロイについては,以下の条件を改めて確認しておいて下さい。

  • Rails 6 であること
  • アプリで使用するデータベースシステムの指定が RDS と一致していること
    • 他のデータベースを指定している場合は config/database.yml を修正して下さい。
    • rails db:system:change --to=mysql もしくは rails db:system:change --to=postgresql コマンドが便利です
  • アプリで使用する gem やライブラリ次第では EC2 に他にもあらかじめインストールしておく必要がある可能性があります

6.1 Railsのサンプルアプリを作成

【注】 「サンプルのアプリ」で AWS のデプロイに挑戦されたい方以外はスキップして下さい。

CarrierWave を用いた画像投稿機能を持つアプリを簡単に実装しましょう。

アプリの作成(MySQLの場合)

ターミナル
rails new aws_sample_app -d mysql -C -M -T --skip-active-storage

アプリの作成(PostgreSQLの場合)

ターミナル
rails new aws_sample_app -d postgresql -C -M -T --skip-active-storage

※ 以下は MySQL, PostgreSQL 共通です

ターミナル
cd aws_sample_app
git add .
git commit -m "init"
bundle remove jbuilder
bundle add carrierwave
rails g scaffold Post title:string image:string --skip-assets --skip-helper
rails db:migrate:reset
rails g uploader Image
echo "/public/uploads/" >> .gitignore
  • トップページを設定
config/routes.rb
Rails.application.routes.draw do
  # ********** 以下を追加 **********
  root to: 'posts#index'
  # ********** 以上を追加 **********
  resources :posts
end
  • 画像投稿機能を付けるための準備
app/models/post.rb
class Post < ApplicationRecord
  # ********** 以下を追加 **********
  mount_uploader :image, ImageUploader
  # ********** 以上を追加 **********
end
  • 投稿する画像の選択ボタンを作成
app/views/posts/_form.html.erb
<!-- 略 -->
  <div class="field">
    <%= form.label :image %>
  <!-- ********** 「<%= form.text_field :image %>」を変更 ********** -->
    <%= form.file_field :image, accept: "image/png,image/jpeg,image/gif" %>
  <!-- ********** 以上を変更 ********** -->
  </div>
<!-- 略 -->
  • 投稿詳細ページで,投稿した画像が表示されるように設定
app/views/posts/show.html.erb
<p id="notice"><%= notice %></p>

<p>
  <strong>Title:</strong>
  <%= @post.title %>
</p>

<!-- ********** 以下を編集 ********** -->
<% if @post.image? %>
  <p>
    <%= image_tag @post.image.url %>
  </p>
<% end %>
<!-- ********** 以上を編集 ********** -->

<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %>

動作確認を行った上で,GitHubにリポジトリを作成し,add, commit を行い, GitHub に push しましょう。

さらに,画像を AWS S3 に保存できるようにすべきですが,ひとまず画像投稿は可能ですのでデプロイ完了後の10章・11章で設定を行うこととしましょう。

6.2. データベースの設定

※以下は自作アプリの場合の場合も実行して下さい。必要があれば作業前にブランチを切るようにしましょう。

ファイル名 ファイルのイメージ
config/master.key
config/credentials.yml.enc 錠付きファイル

まず,本番環境用の config/database.yml を修正しておきましょう。

RDS のパスワードとエンドポイントは GitHub から見られないようにするため, credentials.yml.enc に記載し,これを読み込むように設定することとします。

dotenv-rails を導入し .env にパスワードなどを記載する方法もあります)

MySQLの場合

config/database.yml
production:
  <<: *default
  # ***** 以下を修正 *****
  database: アプリ名_production
  password: <%= Rails.application.credentials.db[:password] %>
  host: <%= Rails.application.credentials.db[:hostname] %>

PostgreSQLの場合

config/database.yml
production:
  <<: *default
  # ***** 以下を修正 *****
  database: アプリ名_production
  username: postgres
  password: <%= Rails.application.credentials.db[:password] %>
  host: <%= Rails.application.credentials.db[:hostname] %>

※ 以下は MySQL, PostgreSQL 共通です

  • database.yml で読み込むパスワードとエンドポイントを credentials.yml.enc に記載しましょう
    • yaml 形式ですので,インデント幅にはくれぐれも注意して下さい
    • 例えば,password:の後に「半角スペース1個」がないだけでエラーになります
ローカル環境のターミナル
EDITOR=vi rails credentials:edit
config/credentials.yml.enc
db:
  password: RDSのパスワード
  hostname: RDSのエンドポイント

さらに,本番環境で master.key が存在しない場合はエラーが出るように設定しておきます。

config/environments/production.rb
# 次のコメントアウトを解除
config.require_master_key = true

念のため以下を実行し,パスワードとエンドポイントが取得できることを確認しておいた方がよいでしょう。

ローカル環境のターミナル
rails c
# コンソール起動後
Rails.application.credentials.db[:password]
Rails.application.credentials.db[:hostname]
# RDSのパスワード, エンドポイントが表示されることを確認後
exit

確認ができれば,add, commit を行い, GitHub に push しましょう。

master(main) ブランチ以外で作業をされている場合は,プルリクを出し,GitHubの master(main) ブランチにマージするところまでは行ってください。

6.3. Capistrano

1コマンドで Rails アプリをデプロイできるよう Capistrano を導入しましょう。

Gemfile
group :development do
  # 略
  # ***** 以下を追加 *****
  gem "capistrano", "~> 3.10", require: false
  gem "capistrano-rails", "~> 1.6", require: false
  gem 'capistrano-rbenv', '~> 2.2'
  gem 'capistrano-rbenv-vars', '~> 0.1'
  gem 'capistrano3-puma'
  # ***** 以上を追加 *****
end
ローカル環境のターミナル
bundle install
bundle exec cap install STAGES=production

Capfile# require "capistrano/passenger" の下に以下を追加

Capfile
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/puma'
install_plugin Capistrano::Puma
install_plugin Capistrano::Puma::Nginx
  • デプロイの設定ファイルを修正・追記しましょう
    • 「アプリ名」「GitHubリポジトリURL」は各自のものに置き換えて下さい
    • 「GitHubリポジトリURL」は HTTPS でなく SSH のURLをコピペして下さい
config/deploy.rb
# config valid for current version and patch releases of Capistrano
lock "~> 3.14.1"

# ***** 以下を修正 *****
set :application, "アプリ名"
set :repo_url, "GitHubのリポジトリURL"
set :rbenv_ruby, File.read('.ruby-version').strip

# Nginxの設定ファイル名と置き場所を修正
set :nginx_config_name, "#{fetch(:application)}.conf"
set :nginx_sites_enabled_path, "/etc/nginx/conf.d"

append :linked_files, "config/master.key"
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "node_modules"
# ***** 以上を追加 *****
  • production.rb の一番上に,EC2サーバーにログインするユーザー名、サーバーのロールを記述
    • 「ElatsticIP」「アプリ名」「ユーザー名」は各自のものに置き換えること
config/deploy/production.rb
server "ElatsticIP", user: "ユーザー名", roles: %w{app db web}

set :ssh_options, {
  keys: %w(~/.ssh/アプリ名.pem),
  forward_agent: true,
  auth_methods: %w(publickey),
}

master.key の配置と Rails アプリのデプロイ

準備が整いましたので,Railsアプリのデプロイを行いましょう。

初回の実行では master.key がないためデプロイに失敗しますが, master.key を配置するために必要なディレクトリが生成されます。

デプロイ失敗後に scp コマンドで master.key をサーバー側に追加し,再度実行すればデプロイに成功するでしょう。

ローカル環境のターミナル
# Railsアプリのルートディレクトリに移動してから
bundle exec cap production deploy

# 「ERROR linked file /var/www/アプリ名/shared/config/master.key does not exist on ElasticIP」が出ればOK

scp config/master.key $APP_NAME:/var/www/$APP_NAME/shared/config
bundle exec cap production deploy

最後から2行目に Command restart sent success が表示されていればOKです。

【備考】ここでデプロイに失敗した場合は,まずエラー文を確認しましょう。いろいろなケースがありますが,アプリで使用されている gem 次第では,先に依存関係にあるプラグインを EC2 にインストールしておく必要があります。

Nginx の設定

Nginx 用の設定ファイルを追加するため,先に必要なディレクトリをサーバー側で作成しておきましょう。

サーバー環境のターミナル
cd /etc/nginx
sudo mkdir sites-available

ローカル環境 のターミナルで,Railsアプリのルートディレクトリまで移動した後,以下を実行しましょう。
これで Nginx 用の設定が生成されます。

ローカル環境のターミナル
# Railsアプリのルートディレクトリに移動してから
bundle exec cap production puma:nginx_config

これで,サーバー側の /etc/nginx/conf.d に設定ファイル アプリ名.conf が入ります。

Nginx を再起動しましょう。

サーバー環境のターミナル(/etc/nginx)
sudo service nginx restart

ブラウザのアドレスバーに Elastic IP を入力してアクセスし, スーパーリロード して下さい。(ショートカットキーは command + shift + r

アプリが表示されればOKです!

【補足】アプリが表示されない場合は,以下を試して下さい

  • ローカル環境のターミナルから curl -I ElasticIP を実行したとき,最初に HTTP/1.1 301 Moved Permanently が出力される場合
    • config/environments/production.rbconfig.force_ssl = true をコメントアウトして下さい
  • 9.4 にログの確認方法を記載していますので,確かめてみましょう!!

これでひとまずデプロイは完了です!……が,他にもすべきことがありますので, 【後半】 に進みましょう。

「無事デプロイに成功した!!」という方は是非 LGTM もお願いいたします!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ECRリポジトリから最新のタグを取得する

目的

  • ECRリポジトリに保存されたDockerイメージの最新のタグを取得する

使うもの

  • AWS CLI

手法

--query を利用してAWS CLIの結果をフィルタ、抽出できます。

aws ecr describe-images --repository-name 【リポジトリ名】 \
  --query "reverse(sort_by(imageDetails[*], &imagePushedAt))[0].imageTags[0]" \
  | sed -e 's/"//g'

--queryJMESPath の文法が使えます。

上記の例では、リポジトリのイメージ一覧を取得して、imagePushedAt(日付)で降順ソートを行い、1つ目の imageTagsを取得します。

配列になっているので、そのままでは以下のように扱いづらいため、imagePushedAt[0] で値だけ取り出します。

# imageTags で取得
[
    "005d6f6"
]

# imageTags[0] で取得
"005d6f6"

最後に sed でダブルクォートを取り除き、再利用可能にします。

参考

AWS CLI からのコマンド出力の制御 - AWS Command Line Interface

--query オプションを使用して出力をフィルタリングする方法
AWS CLI は、--query オプションによって、組み込みの JSON ベースの出力フィルタリング機能を提供します。--query パラメータは、JMESPath の仕様に準拠している文字列を受け入れます。

JMESPath — JMESPath

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS初心者向け】AWS学習方法まとめ【15時間で達成できる】

AWS学習を始めようと考えている人

「AWSとは、概要や全体像、メリットデメリットが知りたい」
「AWSの学習方法が知りたい」
こういった疑問に答えます。

本記事のテーマ

【AWS初心者向け】AWS学習方法まとめ【15時間で達成できる】

AWS学習の始め方

AWSやクラウド初心者の方がAWSを学ぶための方法を纏めました。

①クラウドを学ぶ
②AWSの概要を学ぶ
③知識の定着(AWS公式ハンズオン実施)
④AWS運用の現場に参画

残念ながらIT基礎知識(基本情報技術者レベル)がある前提になってしまいました。
(ない場合はもっと時間かかると思います)
知識定着のため、インプット、アウトプットのバランスを考えてまとめています。

記事の信頼性

筆者はAWS経験5年程度です。AWS資格は5冠達成しました。
現在は大規模ECサイトのAWS運用を任されるようになっています。

今回紹介している記事は全てAWS公式ページにあったもので、その中から初心者向けのものをピックアップしています。(公式ページがこれだけ分かりやすいことにAWSの本気度を感じました)

読者さんへの前置きメッセージ

本記事では「IT経験あるけどクラウド経験ない、クラウド勉強したいけど、どのように勉強していけば良いか分からない」方向けに書いています。
この記事を読むことで、「AWS学習の具体的なやり方、その後のキャリア」までをイメージできるようになると思います。
15時間で終わるので仕事しながらでも1か月もあれば完了できると思います。

①クラウドを学ぶ

クラウド (クラウドサービス) とは?(30分程度)

https://aws.amazon.com/jp/cloud/

まずはクラウドについて知るために上記の記事を読みます。
クラウドの専門用語たくさん出てきますが、調べながら読むと良い勉強になる。
量は多くないので30分程度を目標に読み切りましょう。

読んだ後に下記が説明できればOKです。

クラウドのメリット
クラウドの種類
クラウドネイティブとは
クラウド活用の場面

②AWSの概要を学ぶ

はじめてのアマゾン ウェブ サービス(動画40分程度)

https://pages.awscloud.com/hajimete-ondemand-jp.html?trk=aws_introduction_page

下記についてIT初心者でもわかりやすく解説してくれています。

AWSの企業理念
マネージドサービス(価値を生みずらい重労働の話)
クラウドの利点(早く、安く、楽に)
セキュリティ
クラウドジャーニー(オンプレからの移行)

理解が深まるように画像も合わせて貼っておきます。

AWSの企業理念
image.png

マネージドサービス(価値を生みずらい重労働の話)
image.png
image.png

クラウドの利点(早く、安く、楽に)
image.png

セキュリティ
image.png

クラウドジャーニー(オンプレからの移行)
image.png

『AWS ご利用開始時に最低限おさえておきたい10のこと』資料と解説動画(動画60分程度)

https://pages.awscloud.com/event_JAPAN_at-least-10-ondemand.html?trk=aws_introduction_page
初心者には難しいかもしれません。
初回はざっくりで良いので目を通す程度でも大丈夫です。何度も見返すべき資料かなと思います。
AWS Well-Architected Frameworkがどんなものなのか理解できていればOKです。
image.png

『AWS 設計のベストプラクティスで最低限知っておくべき 10 のこと』資料と解説動画(動画60分程度)

https://pages.awscloud.com/JAPAN-event-OE-At-least-10-Architecting-2020-reg-event-LP.html?aws_introduction_page

読むのには高いインフラ知識が必要です。
これも初回は目を通す程度で構いません。超重要なので何度も見返すべき資料です。
(AWS経験者でも理解していないことが多いと感じています。)

目次を見て何を言っていたかぼんやり思い返せれば良い感じです。
image.png

AWS 初心者向け Webinar 〜料金編〜(動画30分程度×2本)

https://pages.awscloud.com/event_JAPAN_cost-ondemand.html?trk=event_webinar_page

ハンズオンを行う上で利用料金が気になる場合は読んでおく程度です。
今回紹介するハンズオン程度であればほぼ料金はかからないので、気にならなければ読まなくても構いません。
気になる方は上記URLにある7つの動画のうち『AWS 支払いと請求』と『AWS 無料利用枠のご案内』を見ておけば良いです。

上記の動画を見ることで下記が理解できます。

コスト確認方法(請求ダッシュボード)
無料利用枠の種類(ずっと無料、1年無料、トライアル期間だけ無料)

※無料利用枠については「AWS 無料利用枠」でググると一覧で見れます。

③知識の定着(AWS公式ハンズオン実施)

正直なところ、何もわかってなくても動画の通りにやるだけで、ハンズオンのシステムは完成します。
クラウドのメリットやAWSの設計原則みたいな大枠を理解して実施することが
知識の定着や応用を効かせる意味で重要なことだと考えています。

ここではアカウント作成と代表的な2つのアーキテクチャパターンを学ぶハンズオンの
合わせて3つを紹介します。

ハンズオンはじめの一歩: AWS アカウントの作り方 & IAM 基本のキ(動画40分(5分程度×8本))

https://pages.awscloud.com/event_JAPAN_Ondemand_Hands-on-for-Beginners-1st-Step_LP.html?trk=aws_introduction_page

まずはアカウントの作成です。
理解ポイントとしては下記の2点です。
ルートユーザーと IAM ユーザー
IAM (ポリシー、グループ、ロール)について
image.png

スケーラブルウェブサイト構築編(動画2時間程度(10分程度×10本)))

https://pages.awscloud.com/event_JAPAN_Hands-on-for-Beginners-Scalable_LP.html?trk=aws_introduction_page

AWSで利用される基礎的で一般的な構成です。
ハンズオン後に下図の各種サービスの役割や機能を理解していればOKです。

image.png

サーバーレスアーキテクチャで翻訳 Web API を構築する(動画2時間程度(10分程度×10本)))

https://pages.awscloud.com/event_JAPAN_Hands-on-for-Beginners-Serverless-2019_LP.html?trk=aws_introduction_page

スケーラブルウェブサイト構築編に比べ設定項目が少ないことがわかります。(楽に構築できます)
新規サービスを作る際はなるべくサーバーレスで作れないかを考えるようになるのが目的です。
ハンズオン後に下図の各種サービスの役割や機能を理解していればOKです。
image.png

④AWS運用の現場に参画

本記事で書いた程度の知識があれば運用案件に潜り込める可能性が高いです。
(それだけ手が足りていない。自分の現場なら来てほしい)
AWS運用ができれば月額70~80万は稼ぐことが可能です。
運用経験を積んだ後は、より単価の高い設計や提案案件、専門性の高い案件を目指せます。

複数の現場でAWS運用していて思うことですが、ベストプラクティスに沿った運用ができている現場はほとんどありません。
なので、運用しながら下記の資料をダウンロードして、繰り返し見て原則を忘れないようにしましょう。
『AWS 設計のベストプラクティスで最低限知っておくべき 10 のこと』資料と解説動画
https://pages.awscloud.com/JAPAN-event-OE-At-least-10-Architecting-2020-reg-event-LP.html?aws_introduction_page

さいごに

資格の勉強だけだと知識定着しないのは、アウトプット(ハンズオンの部分)が足りないからだという結論に行き着いたのが、本記事を執筆しようと思った経緯です。
ベストプラクティスは時代で変わるので、5年前のベストプラクティスが今はバッドプラクティスだったりします。
AWSベテラン経験者になっても改めて本ページに戻ってきてもらえるような使い方をしてもらえると嬉しいです。
(本記事も最新化していかないといけないですが。。)

出展

下記ページから最低限必要な知識をピックアップして紹介しています。
興味ある分野引き続きアウトプットしながら学んでみてください。

AWS 初心者向け資料

https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-level-100/

AWS で最低限知っておきたい 10 のことシリーズ
それぞれの分野別に9つの資料がまとめられている
10種類の概要資料がある。本記事では2つの資料を紹介。

AWS 初心者向けハンズオン

https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-hands-on/

13種類のハンズオンがある。本記事では3つのハンズオンを紹介。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2で自動デプロイが反映されなくなったときの対処法

はじめに

現象

いつもどおり自動デプロイしたはずがまったく反映されない

やってみて

EC2インスタンスがおかしいのかなと思って再起動してみたら無事解決。
再起動に必要なコマンドを備忘します。

手順

EC2インスタンスを再起動

AWSコンソールからEC2インスタンスを再起動します。

DBを起動させる

EC2を再起動するとDBが停止状態になるので起動させます。
(私はMariaDBを使用しています)

確認コマンド

ターミナル(EC2)
$ sudo systemctl status mariadb

結果

ターミナル(EC2)
● mariadb.service - MariaDB database server
   Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled; vendor preset: disabled)
   Active: inactive (dead)

死んじゃってるのが確認できます。


DB起動コマンド

ターミナル(EC2)
$ sudo systemctl start mariadb

これで確認するとActiveになっているはずです。

Nginxを起動させる

同じようにNginxも起動させます。

Nginx起動コマンド

ターミナル(EC2)
$ sudo systemctl start nginx

改めて自動デプロイを行う

これが本当に正解なのかわからないところがありますが(1度目の自動デプロイの内容をEC2が読み込めているなら、Unicornの起動だけでいいような気がします)

とりあえず自動デプロイを行えばEC2に反映されますし、Unicornも起動されるのでもう一度コマンドを打ちます。

ターミナル(ローカル)
% bundle exec cap production deploy

これにて一件落着です。

おわりに

スクリーンショット 2020-11-26 12.34.44.png

本当にこの画面が嫌いです。

✔︎

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

boto3 の DEBUG ログを表示しない

Python コードのデバッグのために以下のようにログレベルを DEBUG に設定していると、boto3 関連のログがたくさん流れてきて邪魔なときがある。

import logging

logging.basicConfig(level=logging.DEBUG)

logger = logging.getLogger(__name__)

boto3 関連の DEBUG ログを表示しないようにしたいときは、いくつかのロガーのログレベルを INFO 以上に引き上げればよい。

import logging

for name in ["boto3", "botocore", "s3transfer", "urllib3"]:
    logging.getLogger(name).setLevel(logging.WARNING)

ただし、boto3 以外のモジュールが urllib3 に依存していた場合はそのログも見えなくなってしまうので注意。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSとオンプレミスの疎通確認に使えるコマンド

前提

  • EC2 Amazon Linux 2

ポート指定でping疎通

$ sudo yum -y install nc
$ nc -zv {ipaddress} {port}

ping疎通の確認

# pingの受け手で実行
$ tcpdump -nn icmp

# pingの送り手で実行
$ ping {ipaddress}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[AWS] AWSだけで完結する定期処理の作り方 [Lambda・CloudWatch]

概要

アプリ開発などでサーバレスな環境構築をすることがあると思います。
そう言った場合にAWSでだけで実装することができるバッチ処理の簡単な作り方をご紹介します。
色々やり方はありますが、今回はLambdaとCloudWatchに焦点を当ててご紹介します。

また解説する内容は必要最低限のプログラムなどになりますので全体的には15分程で試すことが出来るかと思います。

1. Lambdaで処理を作ろう

まず定期処理が行われた際の実際の処理が行われるプログラムを作成していきます。

Screen Shot 2020-11-26 at 10.41.32.png

AWSのLambdaのトップページより"Create function"ボタンを押下しファンクション作成のページに遷移します。

Screen Shot 2020-11-26 at 10.44.36.png

今回は"Author from scratch"を選択し、Function name(関数名)、Runtime(言語)をそれぞれ入力・選択し"Create function"ボタンを押下します。(筆者は関数名"qiitaBatchFunction"、Runtime"Python3.7"をそれぞれ入力・選択)

Screen Shot 2020-11-26 at 10.48.31.png

上記のページに遷移すればLambda関数の作成は完了です。

実際に行いたい処理を"lambda_function.py"を記述します。
またnpmなどでライブラリを導入したい場合や別途ソースコードの管理をしたい場合は、"Actions ▼"を押下し、"Upload zip file."を選択することで外部のソースコードを利用することができます。

実際に作成したソースコードが動くのか確認する場合はページ上部の"Test"ボタンを押下することで確認することが可能です。

では次に定期実行させる仕組みを作っていきましょう!

2. CloudWatchで定期実行させよう

次にCloudWatchで先ほど作成したLambda関数を定期実行させてみましょう。

CloudWatchのサイドバーより"Rules"をクリックします。

Screen Shot 2020-11-26 at 10.58.14.png

そして"Create rule"のボタンを押下します。

Screen Shot 2020-11-26 at 11.00.34.png

まず今回は"Event Source"より"Schedule"を選択します。

そして"Fixed rate of -"を選択し定期実行させたい間隔を設定します。(筆者は5分間隔で起動させる予定なので5を入力し"Minutes"を選択)

もし細かい設定を行いたい場合は、"Cron expression"を選択しスケジュールを設定して下さい。
こちらに関しては検索エンジンで"Cron 書き方"などと調べて頂くと筆者が説明するよりも分かりやすい内容が出てくると思います。

次に"Targets"より"Add target"を押下します。
すると何を実行させるか選択できるので"Lambda function"を選択し先ほど作成したLambda関数を選択します。(ここでは筆者が作成した"qiitaBatchFunction"を選択)

"Configure details"を押下します。

Screen Shot 2020-11-26 at 11.08.23.png

最後に"Rules"の一覧ページに表示される際のName(表示名)とDescription(説明)を記載して"Create rule"ボタンを押下するだけです。
もし作成と同時に定期実行を行いたくない方は"Stete"のチェックを外して下さい。

以上で定期実行の実装は完了です。
あとはサイドバーのLog groupsなどで定期実行されているかログを確認するなどして動作確認を行なって下さい。

3. 最後に

今回は必要最低限の動作ということでご紹介致しましたが基本的にはLambdaの処理部分を変えるだけでお好みの動作を行うことが出来るかと思います。

もしzipファイルを作りたい場合は検索エンジンで"lambda zip 外部"と検索して頂くと丁寧に紹介されているサイトが出てくると思います。
筆者自身もまた別の機会にLambdaで使用する外部ソースコードのzipファイル作成方法を投稿する予定です。

最後まで見ていただきありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ECSタスクへの機密情報の環境変数の設定

概要

Twelve-Factor Appでも述べられているように、アプリケーションの設定は環境変数にしておいた方が色々と取り回しが効きやすいです。
問題は、パスワードなどの機密情報をどう管理してどうデプロイするかにあります。
AWSとECSには機密情報を環境変数として管理する問題を解決するサービスと機能が存在します。
その利用方法を解説します。

アーキテクチャ

環境変数を AWS Systems Managerパラメータストア で管理します。
ECSタスク定義は docker-compose を利用します。
ECSとパラメータストアを連携させて環境変数を埋め込みます。

環境変数管理

環境変数はGithubやGitlabで設定できる機能もありますが、AWSを使っているのであれば Systems Managerパラメータストア を使うのが便利です。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html

理由としては以下が挙げられます。

  • 機密情報管理とECSへの展開が容易でセキュア
  • S3のようなパスで値を管理できる
  • IAMポリシーを使ってアクセス制限をかけられる

機密情報以外の環境変数設定方法

AWS Systems Manager > パラメータストア 画面を開くと パラメータの作成 ボタンがあるのでそれを実行します。

スクリーンショット 2020-11-25 17.54.37.png

作成画面が開くので、各項目を埋めていきます。

スクリーンショット 2020-11-25 17.55.42.png

項目 説明
名前 パス形式で環境変数名を設定します
パスの先頭とかどこかに環境名(dev/stg/prdなど)を入れておくと良いです
説明 説明を記入します。入力なしでも問題ないです
利用枠 通常は 標準 で問題ありません。詳細を使う場合はよく説明を読んで下さい
タイプ 通常の利用の場合は 文字列 を選択します。機密情報を利用する場合は 安全な文字列 を選択します
データ型 通常の利用の場合は text で十分だと思います。詳細はAWSドキュメントを参照してください
環境変数に設定する値を入力します

各項目を入力して パラメータを作成 を実行するとパラメータが作成されます。

機密情報の環境変数

パラメータを作成画面で項目 タイプ安全な文字列 を指定します。

スクリーンショット 2020-11-25 18.07.53.png

項目 説明
KMSキーソース 暗号化復号化のためのKMSキーのソースを指定
KMSキーID 使用するKMSキーIDを指定

通常は 現在のアカウント のデフォルトのKMSキーIDで問題ないと思います。
各項目を入力して パラメータを作成 を実行するとパラメータが作成されます。

機密情報をECSタスク定義に設定する

docker-compose形式でタスク定義する場合、

  • docker-compose.yml
  • ecs_params.yml

の2つのファイルを用意します。
docker-compose形式を使ったタスク定義などに関しては以前書いた記事などを参照してください。
docker-compose.ymlには機密情報の環境変数は設定しません。
機密情報の環境変数は ecs_params.yml に設定します。

docker-compose.yml
version: '3'
services:
  app:
    image: nginx
    ports:
      - "80:80"
:
#機密情報の環境変数は設定しない
ecs_params.yml
version: 1
task_definition:
  services:
    app:
:
      # ここで機密情報の環境変数を設定
      secrets:
        # value_fromにパラメータストアで設定した環境変数名を設定
        - value_from: /dev/DB_USER
          # nameにアプリケーションで参照する環境変数名を設定
          name: DB_USER
        - value_from: /dev/DB_PASSWORD
          name: DB_PASSWORD
:

secrets に機密情報の環境変数を設定します。
value_from にパラメータストアで設定した環境変数名を設定します。
name にアプリケーションで参照する環境変数名を設定します。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/cmd-ecs-cli-compose-ecsparams.html

まとめ

パスワードなどの環境変数として埋め込む機密情報の管理は厄介な問題でしたが、AWSを利用している場合は簡単に解決できます。
また、PEMファイルなどの認証鍵もbase64エンコードしてパラメータストアに登録しておくことで、ファイルとしてサーバやコンテナに置いておく必要がなくなります。
こういうときにクラウドサービスはすごい便利だと感じます。
パラメータストアを是非活用してみてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Oracle DBのマネージメントサービスを使用したくなった時にOCIとAWSのどちらにするか

ちょっと使ってみた上での感想。

Oracle DBのエンジニアが余ってて稼働を確保したい→OCI
Oracle DBが大得意なエンジニアがいてOracle DBの機能を活用したい→OCI
EEの機能を使いたい→OCI
Oracle DBを使わないといけないけど、Oracleの機能をあまり知らないので運用面としては他DBと同じように扱いたい→AWS
Oracle DBを酷使しないといけないけど、Oracleの機能をあまり知らないのでチューニングとかは自動でやってほしい、あとお金はたくさんある→OCI
なんとなくOracle DBをユーザー目線で使ってみたい→AWS
Oracle DBをどうしても運用したい→OCI
規模がでかい→OCI
それ以外、もしくは初心者→AWS

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Mysql2::Error: Table '○○_production.users' doesn't existを解消した話

表題が発生し、解消するまでの顛末をまとめました。原因は2つありました。

開発環境

ruby 2.6.5
Rails 6.0.3.2
capistrano 3.14.1
AWS EC2
webサーバーNginx
アプリケーションサーバーUnicorn

事の発端

データベース関連の修正を行ったため、本番環境(EC2)で一度テーブルを落としてから再作成しました。
そしてマイグレーションを行った際、表題のエラーが発生しました。結論、原因は2つありました。

原因その1 userを参照するreferencesメソッドが、userテーブルが作成される前に読み込まれていた

こちらの方がわかりやすくまとめられてます。
https://obel.hatenablog.jp/entry/20170719/1500456452

rails db:migrate:statusで確認すると、確かにテーブルのステータスがdownになっていました。
タイトルの通り、エラーメッセージの指摘は何ら矛盾がありませんでしたね。
ただ、開発環境ではエラーにはならず?アプリも正常に動いていたので、気づくのにかなり時間を費やしました。

こちらの記事の通り、マイグレーションファイルの日付を修正して、読み込まれる順序を変更しました。
そして、statusはupになりましたが、それでもエラー自体は解消されませんでした。

原因その2 本番環境でgit pull origin masterをしていなかった

結論、これによって上の作業がEC2上に反映され、ようやく解消に至りました。

いやもう思い違いをしていたというか、今なお十分な理解に至っていないのですが、githubへpush(作業ブランチで開発していた場合はmergeしてmasterへpullまで)したら、このコマンドは必要ないと思っていました。
実際、それで自動デプロイのコマンドを打てば、本番環境に機能を実装させることはできていました。

git pull origin masterは毎回必要なのだろうか?この辺りは宿題になっています。
git,githubは大分慣れたように思っていましたが、まだまだ知識が不足しているようです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS 上でマルチアカウントで複数サービスをホストする場合のアーキテクチャパターン (2)

はじめに

AWS 上でマルチアカウントで複数サービスをホストする場合のアーキテクチャパターンを紹介します。
この記事は2つ目で、最初の記事ではシングルアカウントでのパターンについて紹介しています。

マルチアカウントの場合

シングルアカウントパターンで紹介した構成がマルチアカウントでも可能なのかまず見てみましょう。

ALBがフロントパターン

まずはこちらです。
現時点では、ALBのアカウント間共有の機能はないので、ALBをアカウントAが持つ、App1をアカウントBが持つ、App2をアカウントCが持つ...といったことはできないです
image.png

HTTP APIがフロントパターン

次にこちらです。
HTTP API と 内部ALBの連携機能は、同一アカウント内のリソースである必要があるので、API GatewayをアカウントAが持つ、内部ALBをアカウントBが持つ...といったことはできなさそうです。
image.png

REST APIがフロントパターン

次にこちらです。
REST API と 内部NLBの連携機能も同様に、同一アカウント内のリソースである必要があるので、API GatewayをアカウントAが持つ、内部NLBをアカウントBが持つ...といったことはできなさそうです。
image.png

分が悪くなって来ました。

次を見てみましょう。

REST APIがフロントで 外部ALBをバックエンドに持つパターン

お、これはマルチアカウントできそうですね。
API GatewayをアカウントAで作成し、ALBはアカウントBで作成する。
API GatewayとALBとの接続は Publicにすると、API Gatewayだけを管理するアカウントと、ALBとそれに紐付くリソースを管理するアカウントに分けることができそうです。(ALBのアクセス制限は最初の記事を参照してください)
image.png

ただし、冒頭で述べたように、ALBのアカウント共有機能はないため、この構成図だと App1とApp2は必ず同一アカウントになってしまいます。
それをどうにかする方法を少し考えてみたいと思います。

パスごとにALBを持つパターン

こちらだと、API Gateway、App1用のALB、App2用のALBをそれぞれ別アカウントで持つということができそうです。
(参考までにLambda(App3)も別アカウントに持ちたい場合は、フロントのAPI Gatewayの後ろに「ALB - Lambda」か「API Gateway - Lambda」になるかなと思います。あまりイケている気がしないですが、、)

image.png

これを増やしていく、つまり、path3用のALB、path4用のALB...と増やしていけば、フロントをAPI Gatewayに統一し、バックエンドをそれぞれ別アカウントで作成するといったことはできそうです。

どうしても API Gateaway - ALB間の public接続が許容できない場合

REST APIの機能は必須だけど、ALBを使いたい。でも、public接続が許容できないというのも少なからずあると思います。
その場合のマルチアカウントパターンについて考えてみたいと思います。

Appごとにアカウントを分けたい場合

構成図のうち、API gateway、内部NLBとリバースプロキシ(nginxなど)を作成するフロントアカウントと、ELBとAppを持つアプリケーションアカウントに別れます。そして、アプリケーションの数だけアプリケーションアカウントが存在することになります。
複数のVPC間は、VPC peeringもしくは Transit Gatewayで互いに接続します。

こうすることで、API Gatwayから実際のアプリケーションまでの経路は、VPCから外に出ないprivateな通信になります。
考慮が点としては、アプリケーションが増えるごとに、nginxの設定を追加変更する必要がある点です。

image.png

Appごとにアカウントを分けない場合

Appごとにアカウントを分けなくてもいい、つまり、フロント用アカウントとアプリ用アカウントさえ別れていればOKな場合は、
前述の「アプリケーションが増えるごとに、nginxの設定を追加変更する必要がある」という手間はなくなります。

具体的には構成図のように、nginxをシンプルなリバースプロキシ(来たリクエストは全て単一のALBに流す)として設定し、実際のルーティングはALBに任せることで、アプリケーションが増えても、基本的にはNginxの設定を変更する必要はなく、アプリケーション用アカウントのALB周りだけイジればいいことになります。

アプリごとにアカウントを分けなくてもいい場合は、意外とシンプルになるのではないでしょうか。

image.png

(余談) API Gatewayではなく、ELBをフロントに置くパターン

考え方は全く同じですが、アプリ用のアカウントをどうするかで、同様に以下の2パターンがあるかなーと思います。

image.png

image.png

まとめ

フロントとアプリケーションでAWSアカウントを分けたい場合は、現時点でのAWS側の制約などもあり、なかなか一筋縄ではいかなそうです。
個人的には、API Gatewayが必須かどうか、アプリケーション用のAWSアカウントの分け方をどうするかで取りうる選択が変わってきそうです。

API Gatewayの機能は魅力的なので、使いたい人は多いのではないかと個人的には思っています。
なので、アプリケーション用のアカウントを分けたい場合はこのパターン(再掲)。ただし、アプリケーション追加時のNginxの設定変更をどうにかして頑張ることを許容する。
image.png

アプリケーション用のアカウントを分けなくてもいい場合はこのパターン(再掲)、というのがいいのではないかと思っています
image.png

次の話

今回は、/path1 や /path2 でアプリケーションを分けたい。つまり、ルーティングが主目的だったため、ALBやAPI Gatewayでルーティングさせるアーキテクチャをメインで紹介しましたが、通常のルーティング以外に、リトライや接続数制限、サーキットブレーカーといった機能も求めたくなってしまうこともあるかもしれません。
その場合は、ALBでは対応できないため、AWSのサービスであれば、App Meshを使うことになるかと思います。
次回は、App Meshを使ったマルチアカウントパターンについて紹介したいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

開発環境で更新したGithubのコードを本番環境でpull

git fetch origin master

git reset --hard origin/master(強制的にpullする)

EC2インスタンス再起動(これをしないとunicornの起動時にエラー)

unicorn_rails -c /var/www/rails/mumu(アプリの名前)/config/unicorn.conf.rb -D -E production(unicornの起動)

sudo nginx -s reload(Nginxの再起動)

sudo service mysqld start(mysqlを起動していなかったら)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む