はてなのサービス

なぜアマゾン独走か? 解説 → 《 クラウド界の絶対王者「AWS」独走の秘密 》 http://business.nikkeibp.co.jp/atcl/report/15/278209/030200103/ クラウドが成長する理由はわかるが、アマゾンである必然性は書いてない。先行者利益? blueboyのコメント2018/02/06 12:40. スターを付ける; ブログを書く; ページに埋め込む. 続きを読む

カテゴリー 未分類 | タグ

AWS上にHackMDを構築する

https://github.com/hackmdio/docker-hackmd
GitHub
hackmdio/docker-hackmd
docker-hackmd – docker hackmd image

これをしたい

そのためにはdockerの他にdocker-composeも必要なので (edited)

https://docs.docker.com/compose/install/
↑でdocker-composeをインストールする
Docker Documentation
Install Docker Compose
You can run Compose on macOS, Windows, and 64-bit Linux. Prerequisites Docker Compose relies on Docker Engine for any meaningful work, so make sure you have Docker Engine installed either…

すると、

ERROR: Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running?
If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.

というエラーで怒られた

ので
https://qiita.com/DQNEO/items/da5df074c48b012152ee
を参考に、今操作しているユーザをdockerユーザグループに追加

続きを読む

ローカルでLambdaのテストをする環境を作ったメモ

何?

Lambdaをテストする際、いちいちUPしてCloudWatchを確認して・・・とテストするのは辛いのでローカルでテストする環境を作る。
作ったメモ

検証環境

Mac: macOS Sierra
awscli: aws-cli/1.14.32 Python/2.7.13 Darwin/16.7.0 botocore/1.8.36
nodejs: v9.4.0
npm: 5.6.0
docker: Version 17.06.2-ce-mac27

ディレクトリ構成

.
├── docker-compose.yml
├── event.json
├── index.js
├── package.json
└── template.yml

aws-sam-localのインストール

npm i aws-sam-local -g

私はこいつはグローバルインストールしている

手順

作業ディレクトリの作成と移動

コマンド
mkdir test
cd test

npm install

npm init -y
npm i aws-sam-local aws-sdk --save-dev

sam-localが使用するYAMLの作成

template.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  lambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs6.10

localstack用のYAMLファイル作成

docker-compose.yml
version: '2.1'
services:
  localstack:
    image: localstack/localstack
    ports:
      - 4567-4583:4567-4583
      - 8080:8080

スクリプトの用意

index.js
'use strict';

const AWS = require('aws-sdk');
const S3 = new AWS.S3({endpoint: 'http://<ローカル端末のIP>:4572', s3ForcePathStyle: true});


exports.handler = (event, context, callback) => {
    console.log(`EVENT is ${event}`);
    uploads3().then(() => {
        callback()
    });
};

const uploads3 = () => {
    return new Promise((resolve, reject) => {
        let param = {
            Bucket: "xxxxxxxxxxxxxbbb",
            Key: "test2.txt",
            Body: "fugafuga"
        };
        console.log(param);

        S3.putObject(param, (err, data) => {
            if (err) {
                console.log(err, err.stack);
            } else {
                console.log(data);
            }
            resolve();
        });
    });
};

ダミーイベント作成

コマンド
sam local generate-event dynamodb > event.json

local-stackの起動(バックグラウンド起動)

コマンド
docker-compose up -d

lambdaのローカル実行

コマンド
sam local invoke lambdaFunction -e event.json 
  • アップロード用のS3バケットのダミーは最初に作っておくこと。
  • samが呼んでくるlambda動かすdockerからlocalstackへのネットワーク疎通が通らなかったからEndpointは端末のIP指定している。

ローカルでCLI使ってlocalstackは疎通出来るのに、docker上で動いてるLambdaスクリプトから接続ができなくてすっごいハマった。

参考

[新ツール]AWS SAMをローカル環境で実行できるSAM Localがベータリリース

AWS SAM Local と LocalStack を使って ローカルでAWS Lambdaのコードを動かす

続きを読む

「おや…ELBのようすが…?」という時に確認すること

私の経験上、「ELBがおかしいぞ!AWSしっかりしろや!」と思ったら、よくよく調べると実装がダメなだけだったというパターンがよくあるのでまとめたい。

あ、ELBと言いながら厳密にはALBの話をメインにします。

CASE 1. 「バックエンドは生きてるはずなのにヘルスチェックが失敗する!」

つまり以下のような症状が出る状況

  1. ヘルスチェックが失敗する
  2. バックエンドに直接アクセスしたら普通にうまくいく
  3. バックエンドのアクセスログ見たら、ヘルスチェックに200を返している

というパターン。
「バックエンドは生きてるしヘルスチェックにも200を返してる!それなのに失敗扱いなんてELBの不具合だ!」と思いたくなる気持ちはわかるが、まずは落ち着いてヘルスチエックの成否の基準を見直そう。

ターゲットグループのヘルスチェック – Elastic Load Balancing

ターゲットが応答タイムアウト期間内に応答するのを待ちます。

つまりバックエンドが200を返していようが、タイムアウトしていたらヘルスチェック的には失敗なのだ。
とりあえずバックエンドのアクセスログから処理時間を確認してみよう。まさか処理時間を出力するようにログフォーマットを設定してないなんて言わないよな?

ちなみにステータスコード200というのも注意が必要で、みんな大好きApacheのドキュメントにこんな記載がある

mod_log_config – Apache HTTP サーバ バージョン 2.4

%s ステータス。内部でリダイレクトされたリクエストは、元々の リクエストのステータス — 最後のステータスは %>s

すこぶる分かりにくい文章だが、要するに
・ %s -> リダイレクトが発生した際に3XXのコードを出力する
・ %>s -> リダイレクトが発生した際に3XXのコードを出力せず、リダイレクト後の処理の結果のコードを出力する

というわけだ。そのため、「200を返してるし、CPU使用率も上がってないから大丈夫なはず」と思ってたら実はリダイレクトしまくってタイムアウトしてた、というパターンもある。
そして、筆者の記憶が確かならApacheではデフォルトで%>sが設定されている。

というわけでこの症状の場合は、ELBの不具合とヘルスチェックのタイムアウト、どちらの方がありえそうか考えて調査をはじめてみよう。

CASE 2. 「HTTPCode_ELB_5XX_Countメトリクスが出てる!」

「5XXはサーバサイドのエラー…ELBが5XXエラーを出しているということは…ELBの不具合や!」と思いたくなる気持ちはわかるが、まあ落ち着いてほしい。
私も過去に502 Bad Gatewayに悩まされ、AWSにも問い合わせたりしたが、結局のところバックエンドの実装がクソだったのが原因だった。
だから落ち着いてまずはこれを見てほしい。

Application Load Balancer のトラブルシューティング – Elastic Load Balancing

うん、分かりにくいな。
5XX系のエラーに絞って、頑張って解説してみよう。

HTTP 502: Bad Gateway

そもそも502 Bad Gatewayというもの自体が分かりにくい。
Wikipediaによると

不正なゲートウェイ。ゲートウェイ・プロキシサーバは不正な要求を受け取り、これを拒否した。

これで理解できる人間はほぼいないだろう。
502 Bad Gatewayについてはこちらのページの解説が分かりやすい。

502Bad Getewayの原因と意味について | ぷろめし|プログラミングよりも飯が好き

ELBに当てはめて考えるなら、「ELBからバックエンドにリクエストを投げたが、解せないレスポンスが帰ってきた」という状況である。
つまり、ELBがイかれている可能性もあるが、バックエンドがイかれたレスポンスを返したり途中でコネクションをブッチしている可能性もあるのだ。

つまり、502 Bad Gatewayが現れたらバックエンドからのレスポンスがどうなってるかを見直した方がいいだろう。

HTTP 503: Service Unavailable

一時的に使えないというやつ。
上記のドキュメントにはターゲットグループにインスタンスが無いという場合しか書いてないが、実は他にも503が発生する可能性はある。

ELBはトラフィック量に合わせて自動でスケールするが、あまりに急激にトラフィックが増加した場合にはスケールが間に合わなくなることがある。そういう場合にはELBの処理能力が足りなくなって503が発生することになる。
ほっといたらそのうちELBがスケールして解決するが、「一瞬たりとも落とせないんだ!」という時は予めPre-warmingを申し込んでおこう。

Elastic Load Balancing の暖気申請について | Developers.IO

見積もりがガバガバだと「ほんまにPre-warming必要か?」と突っ込まれることもあるので、真面目に見積もろう。

HTTP 504: Gateway Timeout

これは分かりやすい。
ELB -> バックエンドの通信がタイムアウトしたということである。
バックエンドの処理を見直すか、タイムアウト時間を伸ばすかの二択だが、基本的にはバックエンドの処理を見直す方が健全である。

色々調べたが、どう考えても実装に問題はない時は…

AWS側の問題という可能性もあるので、問い合わせよう。

続きを読む

Ruby on Rails アプリをAWSにアップするまで

Webアプリ初心者がはじめてrailsアプリをAWSへアップするまでの作成日記
作成中のサイト
https://www.drink-app.club/

  • ID:admin
  • pass:test0108

https://github.com/katsun0921/drink-app-rb

参考サイト

@iwaseasahi さんのページを参照すればだいたいAWSへのアップはいける

はまったところ

ruby2.5.0でやったらDeviseでSyntaxErrorとなった。

バグらしいので修正が必要だった

SyntaxError: /.../devise-3.5.5/app/controllers/devise/sessions_controller.rb:5: syntax error, unexpected '{', expecting keyword_end
...ter only: [:create, :destroy] { request.env["devise.skip_tim...

ここをコードを修正

prepend_before_filter only: [:create, :destroy] { request.env["devise.skip_timeout"] = true }
prepend_before_filter(only: [:create, :destroy]) { request.env["devise.skip_timeout"] = true }

nginxでrestartが反映されない?

修正ファイルをgit hubからpull したら、反映されずというかDNSが切れた
なぜ?
どうやらnginxだとrestartではなくreloadだとうまくいく
http://abyssluke.hatenablog.com/entry/2015/12/11/203707

sudo nginx service reload

でうまくいかなかったらreload

sudo nginx -s reload

develop環境だと画像が表示されるのに、producton環境だと画像が表示されなくなった?

ローカル環境でのvagrantだと画像は、表示されるのにAWSにアップしたら表示されない?
assets/images 配下に画像をおいていた

background: url(/assets/images/hoge.jpg)

この書き方だとパスの書き方が間違っていたっぽい

https://qiita.com/wadako111/items/03bc00d914e62243a511

このページを参考にして画像をpublicへ変更したら解決

/public/images/

に画像をおいて画像パスを変更

background: url(/images/images/hoge.jpg)

assetsにあるcssは変更したらプリコンパイルを忘れず

bundle exec rake assets:precompile RAILS_ENV=production

続きを読む

{AWS(CloudFront+S3)+Node.js} 署名付きURLの使用したプライベートコンテンツの配信

はじめに

短期間のみ有効な署名付き URL を使用してプライベートコンテンツを配信するにあたり、Node.js環境下での情報が公式にはのっていなかったので、その対応方法をメモとして残します。

公式ガイド
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html

環境準備

  1. プライベートコンテンツを格納するS3のバケットを作成する
  2. 上記バケットを非公開とする
  3. CloudFrontのディストリビューションを作成する
    • CloudFront経由に限り上記S3バケットにアクセス出来る用に設定する
  4. 署名付きURL生成のためにCloudFront のキーペアを作成する
    • この処理だけはAWSアカウント(ルートアカウント)が必要

〇参考URL
https://dev.classmethod.jp/cloud/aws/cf-s3-deliveries-use-signurl/
http://blog.mekachan.net/?p=105

コード実装

現在JavaScriptのaws-sdkライブラリではCloudfrontの署名付きURL生成がサポートされていないため、「aws-cloudfront-sign」ライブラリを活用して対応する

aws-cloudfront-sign

https://www.npmjs.com/package/aws-cloudfront-sign

サンプルコード

// 30分だけ有効な署名付きURLを生成するコード
var cf = require('aws-cloudfront-sign')
var options = {
  keypairId: 'XXXXXX',
  privateKeyPath: 'XXXX/XXXXXX-private-pk-XXXXX.pem',
  expireTime: (new Date().getTime() + 30 * 60 * 1000)
}
// CloudFrontの「Domain Name」を指定する
// https://${Domain Name}/${Origin path(S3バケット内のパス)}
var signedUrl = cf.getSignedUrl('https://dXXX.cloudfront.net/example.mp4', options);
console.log('Signed URL: ' + signedUrl);

options(オプション)の説明

項目 内容
expireTime 有効期限(任意設定:省略時は30秒)指定する際はミリ秒で指定する
keypairId 作成したクラウドフロントキーペアのアクセスキー ID
privateKeyString
または
privateKeyPath
作成したクラウドフロントキーペアの秘密鍵ファイルパス

参考 S3上で署名付きURLを利用するの場合

このケースではクラウドフロントを介しません。
S3上で生成した署名付きURL経由で非公開バケット中のリソースへアクセスする方式です。
特別なライブラリは不要でaws-sdkで対応可能です。

const AWS = require('aws-sdk')

AWS.config.update({
  accessKeyId: 'XXXXXX',
  secretAccessKey: 'XXXXXX'
  // ,
  // region: 'ap-northeast-1'
})
const s3 = new AWS.S3()

const url = s3.getSignedUrl('getObject', {
    Bucket: 'private-bucket',
    Key: 'example.mp4',
    Expires: 60 // 単位は秒
})

console.log(url)

参考(AWS-CLI)の場合

aws cloudfront sign
 --url http://dXXX.cloudfront.net/example.mp4
 --key-pair-id XXXXXX
 --private-key file://C:/XXX-private-pk-XXXXX.pem
 --date-less-than YYYY-mm-dd

続きを読む

AWSのEC2とRDS(mysql)を他アカウントへ移行してみるテスト

方針

ちょっとだけサーバを止める
移行前=>VPC1 / AP1 / DB1
移行後=>VPC2 / AP2 / DB2
って名前にする
ロードバランサなどについては特に記述しない

移行手順

  • VPC2を作る
  • VPC2とVPC1をピア接続する
  • AP2を作る
  • AP2からDB1へ接続する
  • DNSサーバをAP1からAP2へ向き先を変える
  • 浸透を待ち、AP1止める
  • DB2を作る
  • DB1からDB2へDBを移行(ダンプとかで)
  • データ移行が終わった段階で、AP2を止める
  • AP2の向き先をDB2へ変更
  • DB2を親にする
  • AP2を起動する
  • (゚∀゚)

作成

vpc2を作る

以降元とprivate-ipが被らないようにする

ピア接続

こちらを参考に作成しました
https://dev.classmethod.jp/cloud/aws/vpc-peering-different-awsaccount/

  • vpc2からvpc1へピア接続を作る
  • vpc1のアカウントIDとvpc-idを設定する
  • vpc1アカウントのvpc=>ピア接続で、リクエストを承認する
  • vpc1とvpc2双方のルートテーブルへ、お互いのip範囲でターゲットなピア接続を追加

EC2の移行

こちらを参考に作成しました
http://keisukeohta.hatenablog.com/entry/2016/03/01/210556

  • AP1のインスタンスからイメージを作る
  • AMIのイメージパーミッションの設定で移行先アカウントIDを追加する
  • 移行先アカウントのAMI=>プライベートイメージに共有されているので、それを使ってEC2を作成
  • ap2からdb1へピア接続出来ることを確認する
    => db1がパブリック接続許可の場合、パブリックIDで接続しに行ってしまうので、ローカルIDで接続する

以上

これで「AP2からDB1へ接続する」から先が作業可能となります

続きを読む

AWS CloudWatchでEC2のCPU使用率を監視してSNSで通知する

サーバ監視ってややこしそうな印象でしたが、AWSを使うと簡単でした。
タイトルの通り、CloudWatchでEC2のCPU使用率を監視してSNSで通知した時のメモです。
ここでいう SNS は、Social Networking Service ではなく、AWSのサービスの一つである Simple Notification Service のことです。

前提

  • EC2インスタンスが稼働中であること(事前に監視対象のインスタンスIDをメモしておく)

SNS(Simple Notification Service)でトピック・サブスクリプション作成

トピックとは

  • 通知のチャンネルのようなもの
  • トピックの中(下?)に通知先を色々設定できる(HTTP、Email、AWS Lambda…)
  • 作成時に トピック名(半角英数字とハイフン、アンダースコアで256文字まで)と、表示名(10文字以内)を入力

サブスクリプションとは

  • トピックの中(下?)に作成する通知先のこと
  • エンドポイントとして、HTTPならURL、Emailならメールアドレスを指定する
  • Emailを指定すると、設定したアドレス宛に承認用URLが届くので、本文内のURLで承認する

SNSの料金設定

  • メール送信であれば、毎月1,000件までは無料
  • それ以降は、100,000件あたり2ドル

※他のサブスクリプションについてはSNS料金ページを参照してください
https://aws.amazon.com/jp/sns/pricing/

作成手順

  1. トピック作成
  2. 作成したトピックに対してサブスクリプション作成
    • プロトコルを Email
    • エンドポイントに 通知先のメールアドレス
  3. 設定したメールアドレス宛に届いた承認メール内のURLにアクセスして、承認
    • 件名は AWS Notification - Subscription Confirmation

CloudWatchでアラーム作成

アラームとは

  • ◯◯が▲▲以上になったら□□する といった設定のこと
  • 以下の3つの状態がある
    • アラーム:設定した条件に合致している状態
    • 不足:データが不足していて設定した条件が判定できない状態
    • OK:設定した条件に合致していない状態

CloudWatchの料金

  • 無料

    • 最大50個のメトリクス、3つのダッシュボード、モニタリングは5分間隔

※詳細はCloudWatch料金ページを参照してください
https://aws.amazon.com/jp/cloudwatch/pricing/

作成手順

※スクショはありません

  1. メトリクスの選択EC2 を選択し、右横のテキストボックスに対象のインスタンスIDを入力して Enter
  2. 下の一覧から CPUUtilization (CPUUtilization) の行にチェックを入れ、次へ
  3. 名前説明 を入力
  4. しきい値、アラームのプレビュー の下にあるテキストボックス、ラジオボタン、セレクトボックスを適宜設定する
    以下、「5分間の使用率平均が70%を超えた場合にトリガー」という条件の場合の設定例
    が:≧ 70
    期間:1 中 1データポイント
    間隔:5分間
    統計:スタンダード 平均
  5. アクション の項目で、アラームが次の時:状態:警告 に、作成したSNSのトピックを指定する
    アラームの状態が、アラーム に変わった時に通知が来る
  6. アラームが次の時:状態:OK も設定すると、アラームの状態が OK に変わったときにも通知が来る

注意点

  • 間隔を 1分 とかに設定することもできますが、無料で使用する場合はモニタリングの最小間隔が 5分 なので、アラームの状態が頻繁に 不足 になります。

続きを読む

AWS EC2作成からTeraterm接続まで

※AWSアカウントを持っていて、ログインできる方が対象です。

VPCの構築

・1つのお城のようなイメージ
・参考URLに沿って作成する

VPCとはAWSアカウント上に複数作成することが出来るプライベートなネットワークの単位です。一軒家を建てる為の土地全体といったところでしょうか。
VPCの配下には、AZがあり、その配下にはサブネットがあります。またAZは1つ以上のサブネットを保持することができます。AWS上で初めてネットワークを構築するときは最低でも1つのVPC、1つのAZ、1つのサブネットを作成する必要がします。
AZは建造物エリア、サブネットは建造物を設置するための基礎といったイメージです。

参考URL:https://engineers.weddingpark.co.jp/?p=523

EC2の作成

・これも下記URLに沿って作成する
参考URL:https://engineers.weddingpark.co.jp/?p=523

・ただし、インスタンスのパブリックIPが勝手に設定されていますが、私の時は設定されていなかった
→Elastic IPを取得して、割り当てる必要あります。下記参照

image.png

image.png

画面を閉じて、取得したElastic IPを選択→アクション→アドレスの関連付け
→インスタンスに先ほど作成したEC2を選択し、関連付け
※Elastic IPはEC2に関連付けしないと課金されるので注意

関連付けるとパブリックDNS、IPが記載されるのでそちらでSSH接続する。

SSH接続(Windows)

Teratermでアクセスしました。
下記参照。ファイルの種類を「すべてのファイル」にしないと秘密鍵を選択できないので注意

参考URL:https://dev.classmethod.jp/cloud/aws/aws-beginner-ec2-ssh/

image.png

ping応答設定

EC2に紐づいているセキュリティグループに「ICMP」を追加する

参考URL:http://a1-style.net/amazon-web-service/ping-icmp-setting/

続きを読む