OpenFaaSを使ってGo言語でFunctionを書いて、AWSに展開したDocker環境にデプロイするまで

OpenFaaSは聞いたことがあるでしょうか。
まだ生まれて半年ほどしか経っていませんが、GithubStar数は6000を超える勢いで成長している有望なフレームワークです。

2017年10月18日に行われたServerless Meetup Osaka #4でOpenFaaSのことを聞いたので早速試してみました。

どこまでやるかというと、
OpenFaaSのAuthorであるAlex Ellisのブログで紹介されている、OpenFaaSでGo言語の関数を動かして、さらにクラウドに展開するところまでやってみたいと思います。

今回やってみて、日本語の情報がほぼ皆無で、英語でも情報がかなり少なかったので、丁寧に手順を載せておきます。

OpenFaaSいいところ

まとめとして先に良かったことを書いておきます。

  • Dockerイメージになるなら何でも動かせる
  • とはいえ、メジャーな言語のテンプレートを用意している
  • 手軽さは既存のFunction as a Serviceと変わらない

スケール・コストなどの観点はチュートリアルでは評価しきれないので、言及しません。

Faas CLIのインストール

Docker CE 17.05以上がインストールされていることが必要です。

コマンドでさくっとインストールできます。

curl -sSL https://cli.openfaas.com | sudo sh

brewコマンドが使えるなら、

brew install faas-cli

Selection_002.png

OpenFaaSデプロイ環境をローカルに追加

Kubernetesに比べると簡単に扱えると感じたDocker Swarmにデプロイします。

まずはDocker Swarm自体の初期化して、managerとworkerを動作させます。

docker swarm init

以下のコマンドでFaaSスタックをデプロイします。

git clone https://github.com/openfaas/faas && \
  cd faas && \
  git checkout 0.6.5 && \
  ./deploy_stack.sh

このデプロイした環境はどこにいるかというと、Docker Service (Swarm Mode) として動いているので、docker service lsのコマンドで確認できます。

image.png

ローカルのデプロイ環境にはhttp://localhost:8080でアクセスできるので開くと、次のようなFunction管理ポータルが表示されます。
Linuxの場合はhttp://127.0.0.1:8080で開く必要があるかもしれません。

Selection_006.png

Go言語のインストール

こちらの公式インストールガイドを参考にインストールしてください。

v1.8.3かそれ以降が必要です。
gvmでインストールしても問題ありません。

Selection_003.png

$GOPATHが設定されているか確認しておきます。
Selection_004.png

OpenFaaSプロジェクトの生成

まずはプロジェクトフォルダーを作成します。

mkdir -p $GOPATH/src/functions
cd $GOPATH/src/functions

続いてFaaS CLIを使ってプロジェクトテンプレートを生成します。
名前は参考記事通りgohashです。

faas-cli new --lang go gohash

Selection_005.png

プロジェクトの中身を確認する

gohash.ymlファイルにはテンプレートで作成されたFunctionとローカルの実行環境についての設定が書き込まれています。

gohash.yml
provider:
  name: faas
  gateway: http://localhost:8080

functions:
  gohash:
    lang: go
    handler: ./gohash
    image: gohash

gohash/handler.goにはHello Worldなコードが書かれています。

gohash/handler.go
package function

import (
    "fmt"
)

// Handle a serverless request
func Handle(req []byte) string {
    return fmt.Sprintf("Hello, Go. You said: %s", string(req))
}

そしてtemplate内には、各言語のテンプレートもありますが、Go言語のものがちゃんとあります。
main.goではOpenFaaSの仕様通り、 STDIN を受け取って、対応するFunctionを呼び出した結果を STDOUT に送るというシンプルな作りとなっています。

template/go/main.go
package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "os"

    "handler/function"
)

func main() {
    input, err := ioutil.ReadAll(os.Stdin)
    if err != nil {
        log.Fatalf("Unable to read standard input: %s", err.Error())
    }

    fmt.Println(function.Handle(input))
}

Dockerfileが各言語の環境ごとに用意されていて、ミニマルな実行環境を作成し、開発者が用意したFunctionコードをコンテナ内に格納してから最後にWatchdogを起動するという動きになっているようです。

WatchdogはGo言語で書かれた小さなHttpサーバーです。

template/go/Dockerfile
FROM golang:1.8.3-alpine3.6
# ---------- 略 -----------
WORKDIR /go/src/handler
COPY . .
# ---------- 略 -----------
CMD ["./fwatchdog"]

まずはデプロイしてみる

テンプレートを導入した時点で、環境構築が無事に完了しているか確認するために、HelloWorldのままデプロイしてみます。

faas-cli build -f gohash.yml
faas-cli deploy -f gohash.yml

BuildはDockerのイメージをダウンロードするところから始まるので、最初の実行は1分ほど待つかもしれません。

とくにエラーが表示されずに、
Selection_009.png
という風な表示がされたら成功です。

http://localhost:8080にアクセスしてgohashが追加されているか確認します。
左のFunction一覧からgohashを見つけたら適当なRequest bodyを打ち込んで INVOKE します。

Selection_007.png

これで無事にデプロイできることが確認できました。

Functionを実装していく

今回はgo1.9を使ったので、コンテナ内のgoも同じバージョンにしておきます。
今回のコードでは変更しなくても特に問題にはならないと思います。
コンテナ生成Dockerfileを書き換えてしまいます。

template/go/Dockerfile変更前
FROM golang:1.8.3-alpine3.6
template/go/Dockerfile変更後
FROM golang:1.9-alpine3.6

go言語のパッケージ管理ツールとしてdepをインストールします。

go get -u github.com/golang/dep/cmd/dep

そして、Goのデータ(Struct)からハッシュを生成するstructhashdepを使ってインストールします。
ただし、faas-cliがDockerコンテナをビルドするときに、template/go/をワーキングディレクトリとしてビルドを行うため、depの実行はこのディレクトリに移動して行う必要があります。

cd template/go/
dep init
dep ensure -add github.com/cnf/structhash

こうすると、Gopkg.lockGopkg.tomlvernder/template/go/以下に生成されます。
ちなみに、gvm環境だとdep ensureでライブラリがうまくインストールされないことがありますが、goのコードがビルドされるのはコンテナ内なので、一応そのまま進めても大丈夫です。

きちんと開発を進める場合はgvm linkthisdepがしっかりと使えるようにします。

それでは、受け取った文字列データからハッシュを生成するコードに変更しましょう。

gohash/handler.go
package function

import (
    "fmt"

    "github.com/cnf/structhash"
)

// S is sample struct
type S struct {
    Str string
    Num int
}

// Handle a serverless request
func Handle(req []byte) string {
    s := S{string(req), len(req)}

    hash, err := structhash.Hash(s, 1)
    if err != nil {
        panic(err)
    }
    return fmt.Sprintf("%s", hash)
}

プロジェクトのデプロイ

では、作成したコードをデプロイしてみましょう。

faas-cli build -f gohash.yml
faas-cli deploy -f gohash.yml

ポータルの実行結果はFunctionのデプロイで新しいものに置き換えたので結果が変わっています。

Selection_010.png

また、もちろんAPI URLも用意されているので、直接呼び出すこともできます。

curl -X POST -d "てすとめっせーじ" http://localhost:8080/function/gohash

Selection_011.png

テストを追加する

テンプレートのDockerfileにはgo testでテストを実施しているのですが、今のところテスト用のgoファイルは生成されないようです。

今は自分で作りましょう。

touch gohash/handler_test.go
gohash/handler_test.go
package function

import "testing"

func TestHandleReturnsCorrectResponse(t *testing.T) {  
    expected := "v1_b8dfcbb21f81a35afde754b30e3228cf"
    resp := Handle([]byte("Hello World"))

    if resp != expected {
        t.Fatalf("Expected: %v, Got: %v", expected, resp)
    }
}

テストを作ったところで、わざとgohash Functionを間違えて修正してしまいましょう。

handler.go修正前
hash, err := structhash.Hash(s, 1)
handler.go修正ミス
hash, err := structhash.Hash(s, 2)

この状態で再びビルドを実行します。

faas-cli build -f gohash.yml

ちゃんとビルド中にテストで失敗してくれます。
Selection_012.png

コードを元に戻してビルドが成功することを確認します。

DockerHubにビルドしたイメージをPUSH

リモート環境でOpenFaaSを動作させるためには、FunctionのDockerイメージをDockerHubまたは別のレジストリに登録しておく必要があります。

まずは、[DockerHubのユーザ名]/gohashとなるように、gohash.ymlを書き換えます。

gohash.yml書換前
    image: gohash
gohash.yml書換後
    image: gcoka/gohash

Docker Hubの登録が済んでいれば、

docker login

でログインし、

faas-cli push -f gohash.yml

でビルドしたイメージをPUSHします。

AWSにデプロイしてみる

AWS EC2コンソールで SSH KeyPairsを作成しておいてください。
ssh-addもお忘れなく。

ssh-add ~/.ssh/yourkey.pem

AWSにDockerをデプロイするためのテンプレートが用意されているので、ここにアクセスして、
Deploy Docker Community Edition (CE) for AWS (stable)をクリックします。
use your existing VPCを選択すると、Docker用ネットワークの設定をいろいろやらないといけなくなり、VPC内のネットワーク構築の知識が必要となるようです。

https://docs.docker.com/docker-for-aws/#docker-community-edition-ce-for-aws

以下の設定は環境に合わせて変更が必要です。

  • SSHキーにKeyPairsで作成したものを指定。

また、このテンプレートでのCloudFormation実行には、以下のCreateRoleが必要です。
正確な一覧はこちら

  • EC2 instances + Auto Scaling groups
  • IAM profiles
  • DynamoDB Tables
  • SQS Queue
  • VPC + subnets and security groups
  • ELB
  • CloudWatch Log Group

特に設定は変更していません。
デプロイを試すだけなので、Swarm ManagerとWorkerの数は1ずつにしました。

Selection_029.png

CloudFormationのStackデプロイが完了したら、デプロイ結果のOutputsタブから、Swarm Managerのインスタンスへのリンクが参照できるので、開きます。
Selection_030.png

Selection_031.png

このインスタンスにSSH接続を行います。
ユーザーはdockerを指定します。

ssh docker@54.159.253.49

OpenFaaSのスタックを導入するために、Gitが必要なので、インストールします。

中身はAlpine Linuxなので、apkコマンドでパッケージをインストールします。

sshコンソール
sudo apk --update add git

ローカルでにインストールしたときと同じコマンドですが再掲。

sshコンソール
git clone https://github.com/openfaas/faas && \
  cd faas && \
  git checkout 0.6.5 && \
  ./deploy_stack.sh

ではOpenFaaSスタックが無事デプロイされているか確認します。

AWSに構築したテンプレートはインターネットからはLoadBalancerを通してアクセスできるので、LoadBalancerのURLを調べます。DNS name: に表示されているものがそれです。

Selection_034.png

URLがわかったら、ポート8080を指定してアクセスします。

Selection_035.png

うまくいっていることを確認したらAWSにデプロイします。
--gatewayオプションを使えばgohash.ymlファイルを書き換える必要がありません。

faas-cli build -f gohash.yml --gateway http://your.amazon.aws.loadbalancer.url:8080

Selection_038.png

Selection_039.png

無事にAWSで動きました。

トラブルシューティング(詰まったところ)

faas-cli buildしてもコード変更が反映されない

--no-cacheをつけることで、すべてのビルドをやり直してくれます。

faas-cli build -f gohash.yml --no-cache

structhashパッケージがvenderディレクトリにコピーされない

$GOPATHが正しく設定されているか確認してください。

gvmを使ってgoをインストールしている場合は、$GOPATH/src/functionsgvm linkthisを実行すると解決するかもしれません。

AWS CloudFormationのデプロイに失敗する

use your existing VPCのテンプレートを使っている場合は、使わないでVPCの作成もDockerテンプレートに任せてください。

AWSにデプロイしたFunctionを実行しても500: Internal Server Errorになる

Docker HubにDockerイメージをPUSHしたか確認してください。

ちゃんと動いているかわからない・・・

docker serviceとして動いているのでdockerコマンドからいくつか情報を得ることができます。

指定したFunctionのプロセス動作情報を表示
docker service ps gohash
指定したFunctionのログを表示
docker service logs gohash
gatewayのログを表示
docker service logs func_gateway

最後に

Docker SwarmはMicrosoft Azure Container Serviceもサポートしているのですが、完全なマネージドの場合OpenFaaSが必要とするDockerバージョンが足りていないようです。

今回はDocker Swarmに対してデプロイしましたが、Kubernetesもサポートしているので、そちらも試してみたいと思います。
Kubernetesの場合は、Swarmよりもホスティング対応しているクラウドがいくつかあるようなので、期待が持てますね。

情報がとても少ないので、どんどん試してどんどん情報公開していきましょう!

続きを読む

【Railsチュートリアル】S3に画像をアップロードする設定【13章課題】

S3に画像をアップロードする

13.4.4 本番環境での画像アップロード

13.4.3で実装した画像アップローダーは、開発環境で動かす分には問題ないのですが、本番環境には適していません。これはリスト 13.67のstorage :fileという行によって、ローカルのファイルシステムに画像を保存するようになっているからです23。本番環境では、ファイルシステムではなくクラウドストレージサービスに画像を保存するようにしてみましょう24。


世の中には多くのクラウドストレージサービスがありますが、今回は有名で信頼性も高いアマゾンの「Simple Storage Service (S3)25」を使います。セットアップの手順は次のとおりです。

Amazon Web Servicesアカウントにサインアップする
AWS Identity and Access Management (IAM)でユーザーを作成し、AccessキーとSecretキーをメモする
AWS ConsoleからS3 bucketを作成し (bucketの名前はなんでも大丈夫です)、2.で作成したユーザーに対してRead権限と> Write権限を付与する
(S3のセットアップはやや高度です。コラム 1.1の考え方をうまく活用してみてください。)


特に、Herokuのファイルストレージは一時的なので、デプロイする度にアップロードした画像が削除される仕様になっています。

Railsチュートリアルで、画像を扱うアプリケーションを本番環境でデプロイする項目があります。

S3とIAMの連携で検索しても、画面キャプチャが古いものしか見つからなかったので、自分で記事を書くことにします。

IAMユーザーの作成

IAM_Management_Console.png

AWSの管理コンソールにログインしたら、IAMというサービスのコンソールを開きましょう。

IAM_Management_Console.png

「ユーザー」>「ユーザーを追加」を選択します。

IAM_Management_Console.png

ユーザー名を入力します。
アクセス権限は「プログラムによるアクセス」を選択します。

IAM_Management_Console.png

グループ名を入力します。
ポリシーは「AmazonS3FullAccess」のみを選択します。

IAM_Management_Console.png

設定があってるか確認しましょう。

IAM_Management_Console.png

最後にアクセスキーとシークレットキーのcsvをダウンロードしましょう。
csvの再ダウンロードはできないので、無くさないように

S3の設定

S3_Management_Console.png

IAMの設定が完了したら、次はS3の設定です。
S3に管理コンソール画面を開いたら、「バケットを作成する」を選択します。

S3_Management_Console.png

名前を入力します。既に使われている名前は使用することができません。
リージョンは東京を選択します。

S3_Management_Console.png

ここはデフォルト設定で問題ありません。

S3_Management_Console.png

「オブジェクト」「オブジェクトのアクセス許可」の読み込み、書き込みにチェックを入れましょう。
他はデフォルト設定です。

S3_Management_Console.png

最後に設定があっているか確認しましょう。

Herokuの環境変数を設定

ここまで完了したら、あと一息です。
Herokuの環境変数を設定しましょう。

$ heroku config:set S3_ACCESS_KEY="ココに先ほどダウンロードしたAccessキーを入力"
$ heroku config:set S3_SECRET_KEY="同様に、Secretキーを入力"
$ heroku config:set S3_BUCKET="S3のBucketの名前を入力"
$ heroku config:set S3_REGION="ap-northeast-1"

これでデプロイしたRailsアプリケーションを起動して見ましょう。
画像を投稿して、S3バケットを確認して、新しく画像が保存されていたら、成功です!
お疲れ様でした!!

参考資料

Amazon S3 再入門 – AWS IAMでアクセスしてみよう!(Cyberduck 編)
35歳だけどRailsチュートリアルやってみた。[第4版 13章 13.4 マイクロポストの画像投稿 まとめ&解答例]

続きを読む

kube-awsでaws-ssm-agentとRunCommandを試してみる

kube-awsとは

AWS上にKubernetesクラスタをつくるツールです。GolangやCloudFormation、Container Linux(旧CoreOS)をベースにしています。

RunCommandとは

Amazon EC2 Systems Managerというサービスの一機能で、AWSのAPI経由でEC2インスタンスにざまざまなコマンドを実行させることができます。

aws-ssm-agentとは

RunCommandで送られたコマンドを実際に実行するデーモンです。

概要

kube-awsクラスタでRunCommandが利用できるようにします。

まず、aws-ssm-agentは公式にはrpmなどで配布されているのですが、基本的にContainer Linuxにはパッケージマネージャ的なものが存在しないのでそれが利用できません。そのため、Container Linux向けにビルドしたaws-ssm-agentをなんとかして手に入れる必要があります。

ありがたいことに、DailyHotelという会社さんがContainer Linux向けにaws-ssm-agentをビルド・公開してくださっているので、それを利用します。

https://github.com/DailyHotel/amazon-ssm-agent

また、kube-awsにはaws-ssm-agent対応があるので、ほぼcluster.yamlという設定ファイルの記述を少しいじるだけでセットアップは完了です。ただし、kube-aws 0.9.8の時点ではaws-ssm-agentの動作に必要なIAMポリシーがそのままだと付与されないというバグ?があるので、その点だけ手動でフォローする必要があります。

手順

kube-aws initkube-aws renderを実行して必要なファイルを生成したあと、cluster.yamlに以下を追記します。

amazonSsmAgent:
  enabled: true
  downloadUrl: https://github.com/DailyHotel/amazon-ssm-agent/releases/download/v2.0.805.1/ssm.linux-amd64.tar.gz
  sha1sum: a6fff8f9839d5905934e7e3df3123b54020a1f5e

clusterNamek8s1ということにします。
その場合、クラスタ名でIAMロールを検索すると下記のように3つでてきます。それぞれ、Controllerノード、Etcdノード、Workerノード用です。

image.png

それぞれに、AWSマネージドなIAMポリシー「AmazonEC2RoleforSSM」を追加します。

image.png

この時点でノードが起動完了してしまっている場合、aws-ssm-agentがエラーを吐き続けているかもしれません。(試した時は少なくともそう見えた)

その場合、aws-ssm-agentを再起動します。

sudo systemctl restart aws-ssm-agent

これで、あとはAWSコンソールから普段どおりRunCommandとAWS-RunShellScriptドキュメントを使ってクラスタ内の任意のEC2インスタンスに対して任意のシェルコマンドを実行することができます。

例えば、クラスタ内の全インスタンスを対象にしたい場合は、クラスタ名のタグが使えます。

image.png

コマンドの実行結果(時刻、成否、標準出力など)は以下のように記録されます。

image.png

CloudTrailなども使うと監査ログをとる目的ではかなり良さそうですね。

続きを読む

パロアルトのクラウドセキュリティサービス「Aperture」、AWS対応などの強化を行った最新版を提供開始

Apertureの最新版では、新たにAmazon EC2、AWS IAM(Identity and Access Management)、Amazon S3に対応。AWS上でのマルウェアからの防御と、適切 … 続きを読む

Amazon SESで送信元と宛先の制限をかけてみたメモ

調べたり試したりしてみたので、メモ的な。

制限するには

 もともとSESにはサンドボックスモードと言って制限がかかった状態でサービスが利用可能になる。
  参照:http://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/limits.html
 その制限をわざわざ解除申請を出して自由に利用できるようにする。

 けど、自由すぎても困って、という話。

 SESを利用する際には、SES用のIAMユーザーを払い出して利用します。
 そのIAMユーザーのポリシーを利用して幾つかの制限ができるようです。
  参照:http://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/control-user-access.html

設定

送信元制限

 特に問題なくできてしまったので、その時のポリシー例を。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1507889923000",
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Condition": {
                "StringLike": {
                    "ses:FromAddress": [
                        "*@example.com"
                    ]
                }
            },
            "Resource": [
                "*"
            ]
        }
    ]
}

 これで「なんちゃら@example.com」が送信元の場合に限り、IAMはSESの認証をできるようにしてくれます。
 例えば「なんちゃら@jp.xxxx.com」とかが送信元になった場合に、554 Access deniedしちゃいます。
 これが送信元制限の簡単なやり方。

送信先(宛先)制限

 送信元制限のノリで作業したらはまったので、このメモを残すことになった。
 先に参照として出したドキュメントに、「ses:Recipients」使ったらできるで、と書いてあったので、間に受けて設定してたんですが
 それが間違いでした。
 とりあえず、うまくいった例

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "*",
            "Condition": {
                "ForAnyValue:StringLike": {
                    "ses:Recipients": [
                        "*@example.com"
                    ]
                }
            }
        }
    ]
}

 この設定で、「*@example.com」以外にメールが送信できなくなり、先ほどの送信元制限と同様に554エラーが発行されます。
 何にはまったかというと、"ForAnyValue:StringLike" この項目。

 送信元制限の際は、「”StringLike”」でいけるんですが、サポートにお聞きしたところ、ses:Recipientsは複数の項目にまたがり値があるので
 "ForAllValues:StringLike"
 を使ってな、と。
 ドキュメントにも例でのせてるで、ってなことなので、やったんですがダメでした。
 曰く

注記
キーに複数の値が含まれる場合、設定演算子(ForAllValues:StringLike および ForAnyValue:StringLike)を使用して StringLike を修飾できます。

 なので、ダメ元で ForAnyValue:StringLike を使ったらいけたという。
 実はAllとAnyの利用の違いについては調べ切れてないんですが、やりたいことができたということなので、これにて。

両方制限したい欲張りなあなたへ

 以下の設定で実現できてます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "*",
            "Condition": {
                "ForAnyValue:StringLike": {
                    "ses:Recipients": [
                        "宛先アドレス"
                    ],
                    "ses:FromAddress": [
                        "送信元アドレス"
                    ]
                }
            }
        }
    ]
}

 アドレスを指定する場合はLikeじゃなくてEqualesでもいいかもしれませんね。

続きを読む

AWS認定ソリューションアーキテクト-プロフェッショナルに合格するためにやったことまとめ

8月にアソシエイトに合格し、じゃあプロフェッショナルも取るかと思ったものの、日本語のソースだとプロフェッショナルに受かるためにどんなことをしたらいいかの情報が少なかったので、自分がやったことのまとめ。
※2017年10月時点での情報だと思ってください

よく問われるサービス

  • コンピューティング

    • EC2,Elastic Beanstalk
  • ストレージ
    • S3, EFS, Glacier, Storage Gateway
  • データベース
    • RDS, DynamoDB, ElastiCache, Amazon Redshift
  • ネットワーク&コンテンツ配信
    • VPC, CloudFront, Direct Connect, Route53
  • 管理者ツール
    • CloudWatch, CloudFormation, CloudTrail, OpsWorks
  • セキュリティ、アイデンティティ、コンプライアンス
    • IAM, Certificate Manager, Directory Service, CloudHSM
  • 分析
    • EMR, CloudSearch, Kinesis, Data Pipeline
  • モバイルサービス
    • Cognito
  • アプリケーションサービス
    • SWF, Elastic Transcoder
  • メッセージング
    • Simple Queue Service, Simple Notification Service, Simple Email Service

最低限読んでおく資料

まずはここを見て各サービスの概要を把握する。

概要をつかんだらこれを読んで細かいハマりポイントを理解する。

試験ガイドにあるようにホワイトペーパーも出題範囲。英語多め。各種ベストプラクティスくらいは読んでおく。

いわゆるCDP。典型的な設計パターンがまとめられている。

主要なサービスのドキュメントは一通り読む。

気を付けるポイント

  • 各種IDフェデレーション

AssumeRole, AssumeRoleWithWebIdentity, AssumeRoleWithSAML, GetFederationToken, GetSessionTokenがそれぞれどのようなケースで使うのが適当かを押さえる。

  • EC2のインスタンスタイプ
    「T2はバースト可能」「R4はメモリ最適化」といった用途を押さえる。回答の選択肢の中にさらっと出たりする。

  • VPN, DirectConnect, VPC peeringの特徴やユースケース
    オンプレミスとのハイブリッド環境でよく問われる。冗長化する(SPOFをなくす)方法も押さえておく。

  • EBSのIOPS
    最大値および最大値を超えるIOPSが必要な場合の設計方法を押さえる。

  • VPCにおいて予約されているIP

  • 各種サービスがどのレベルで提供されるのか(AZ、リージョン、グローバル)
    単一リージョンから複数リージョンへの移行や、グローバルレベルでの可用性・耐障害性に関する問題がよく出る。

  • CloudFormation, Elastic Beanstalk, OpsWorks
    それぞれの特徴や違い、作成(デプロイ)・変更・削除・中止方法を押さえる。

  • キャッシュエンジンの違い
    ElastiCacheにおけるmemcachedおよびRedisそれぞれの特徴を理解する。

  • 一括請求 (コンソリデーティッドビリング)
    請求を統合する方法および共有されるもの/されないものを押さえる。

有料学習サービス

  • Linux Academy

    • AWS SAプロ用のコースがあって、動画とハンズオンで学習できる。
    • 動画は英語のみで字幕もないが、活用資料集で概要を把握していれば十分理解できるレベル。
    • 登録後7日間は無料。その後は月額料金($29)が発生。無料期間だけで終わることもできる(ただし、ハンズオンは利用不可)。
    • 登録時にクレジットカードかpaypalの登録必須。
    • 独自の模擬試験もついていて、個人的にかなり良かった(無料期間だけで終わったけど…)

他にも海外のブログだとQwikLABSとかa Cloud Guruが評判が良かった(僕は使ってないです)

模擬試験について

公式の模擬試験は一度は受けた方がいい。問題形式や時間配分を体感できるのは重要。
アソシエイトに受かった時に模擬試験を無料で受験できるバウチャーがもらえるので、それを使うのが吉。
ただし、僕が受けた時は日本語がひどくて、日本語として何を言っているか分からない問題が多々あった(本番はまともだった)。もし模擬試験を受けてその日本語に恐怖を覚えても、本番ではそこまで怯える必要はないと思う。

本試験予約時の注意

  • 支払ページの請求先住所は英語で入力。全部入りきらなくても気にしない。

赤字で「英語で入力しろ」と注意書きもあるけど、英語で入力するとフォームの文字数制限で書ききれない。これじゃAWS困るだろと思って日本語で入力するとtemporary errorになる。このtemporary errorが日本語入力のせいだと気付かず、LiveChatで聞いたりして1週間以上待った…。
ちなみに英語で住所を入力して全部入りきらなくても郵便番号欄もあるので、中の人が補完してくれるとのこと。

  • 試験会場の住所が全部表示されない時は英語表示に切り替える

なぜか日本語表示だと郵便番号レベルの住所しか表示されず、とても不安な気持ちになるが、英語表示に切り替えるとちゃんと表示される。謎。

続きを読む

python の関数を AWS Lambda で使用する

次の python の関数を、aws の Lambda にアップロードします。

evening_function.py
# -*- coding: utf-8 -*-
#
#   evening_function.py
#
#                   Oct/18/2017
#
# --------------------------------------------------------------------
import sys
import json

# --------------------------------------------------------------------
def evening_handler(event, context):
    sys.stderr.write("*** evening_handler *** start ***\n")
    print("Received event: " + json.dumps(event, indent=2))
    print("name = " + event['name'])
    print("AAA value1 = " + event['key1'])
    print("BBB value2 = " + event['key2'])
    print("CCC value3 = " + event['key3'])
    print("DDD value4 = " + event['key4'])
    print("EEE value5 = " + event['key5'])
    sys.stderr.write("*** evening_handler *** end ***\n")
#
    return event['name']  # Echo back the first key value
    #raise Exception('Something went wrong')
# --------------------------------------------------------------------

1) zip で、固めます。

zip -r evening.zip evening_function.py

2) aws にアップロードします。
 morning_exec_role というロールが作られているとします。 ロールの作り方は、
aws cli でラムダを使う

function_create.sh
aws lambda create-function \
    --function-name evening_function \
    --runtime python3.6 \
    --role arn:aws:iam::178234159025:role/morning_exec_role \
    --handler evening_function.evening_handler \
    --zip-file fileb://evening.zip \
    --region ap-northeast-1

3) CLIからイベントを発火

cli_exec.sh
aws lambda invoke --invocation-type Event \
    --function-name evening_function \
    --region ap-northeast-1 \
    --payload  '{"name": "島崎藤村","key1":" こんにちは", "key2":"おはよう", "key3":"さようなら","key4": "Hello","key5": "Bonjour"}' \
    outputfile.txt

4) CloudWatchLogsにログが出力されているか確認

続きを読む

CloudFormationでクロスアカウントなVPCPeeringを構築する

概要

別アカウントのVPCとVPCピアリングを行う際のCFnの書き方と、ロールの設定方法について。
なお同一アカウント内でのVPCピアリングだとロール無しでスルッと行ける。

やり方

ざっくり

  1. 前提としてピアリングを行うVPCは各アカウントで用意してあること
  2. VPCPeeringを受け入れる(accepter)アカウントでクロスアカウント許可用ロールを用意
  3. VPCPeeringをリクエストする(requester)アカウントでVPCPeeringリクエストを送信
  4. 完了

ロールの用意

テンプレート

acceptrole.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Accept VPC Peering Role
Parameters:
  AcceptAccountId:
    Type: String

Resources:
  AcceptVpcPeeringRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: 'AcceptVpcPeeringRole'
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Action: 'sts:AssumeRole'
            Principal:
              # ここで複数アカウントを指定することも可能
              AWS: !Join
                - ''
                - - 'arn:aws:iam::'
                  - !Ref AcceptAccountId
                  - ':root'
      Policies:
        - PolicyName: 'AcceptVpcPeering'
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action: 'ec2:AcceptVpcPeeringConnection'
                # 適宜許可を行いたいVPCを設定
                Resource: '*'

実行コマンド

$ aws cloudformation create-stack 
    --stack-name accept-vpcpeering-role 
    --template-body file://acceptvpcpeeringrole.yaml 
    --parameters ParameterKey=AcceptAccountId,ParameterValue=000000 
    --capabilities CAPABILITY_NAMED_IAM 
    --profile=accepter # profileは適宜

VPCPeeringの作成

テンプレート

vpcpeering.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: VPC Peering
Parameters:
  VpcId: 
    Type: String
    Default: 'vpc-xxxxxxxxx'
  PeerOwnerId:
    Type: String
    Default: '000000000000000'
  PeerVpcId:
    Type: String
    Default: 'vpc-xxxxxxxxx'
  PeerRoleArn:
    Type: String
    Default: 'arn:aws:iam::000000000000000:role/AcceptVpcPeeringRole'

Resources:
  VpcPeering:
    Type: "AWS::EC2::VPCPeeringConnection"
    Properties:
      VpcId: !Ref VpcId
      PeerOwnerId: !Ref PeerOwnerId
      PeerVpcId: !Ref PeerVpcId
      PeerRoleArn: !Ref PeerRoleArn
      Tags:
        - Key: Name
          Value: 'TestPeering'

コマンド

$ aws cloudformation create-stack 
    --stack-name vpcpeering 
    --template-body file://vpcpeering.yaml 
    --profile=requester # profileは適宜

続きを読む