AWS Lambdaから実行したEC2上のPythonでモジュールがimportできない

S3に動画ファイルが配置されたことを契機にLambdaでEC2上のPythonをキックし、
ffmpy経由でffmpegを起動し動画を処理するようなプログラムを作っていたのですが、
どうもffmpyが正常にimportできないので、現状と解決した際の情報共有に書き残します。

環境

実行用コードは下記のようにec2-userのホームディレクトリ配下に配置されています。

/home/ec2-user/hoge/
├── MAIN1_KICKED_BY_LAMBDA.py # メインメソッド
├── fuga
│   └── hogefuga.py           # 動画編集用モジュール
...

下記の設定をrootユーザに対して行いました。

  • pyenv -> Anaconda3.4.1 (Python 3.6)
  • pip install ffmpy
  • ffmpegをインストール (下記スクリプト)
ffmpegcpl.sh
#!/bin/sh

sudo yum -y install autoconf automake cmake freetype-devel gcc gcc-c++ git libtool make mercurial nasm pkgconfig zlib-devel

mkdir ~/ffmpeg_sources

#Yasm
cd ~/ffmpeg_sources
git clone --depth 1 git://github.com/yasm/yasm.git
cd yasm
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin"
make
make install
make distclean

#libx264
cd ~/ffmpeg_sources
git clone --depth 1 git://git.videolan.org/x264
cd x264
PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static
make
make install
make distclean

#libx265
cd ~/ffmpeg_sources
hg clone https://bitbucket.org/multicoreware/x265
cd ~/ffmpeg_sources/x265/build/linux
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DENABLE_SHARED:bool=off ../../source
make
make install

#libfdk_aac
cd ~/ffmpeg_sources
git clone --depth 1 git://git.code.sf.net/p/opencore-amr/fdk-aac
cd fdk-aac
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install
make distclean

#libmp3lame
cd ~/ffmpeg_sources
curl -L -O http://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz
tar xzvf lame-3.99.5.tar.gz
cd lame-3.99.5
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --disable-shared --enable-nasm
make
make install
make distclean

#libopus
cd ~/ffmpeg_sources
git clone http://git.opus-codec.org/opus.git
cd opus
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install
make distclean

#libogg
cd ~/ffmpeg_sources
curl -O http://downloads.xiph.org/releases/ogg/libogg-1.3.2.tar.gz
tar xzvf libogg-1.3.2.tar.gz
cd libogg-1.3.2
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install
make distclean

#libvorbis
cd ~/ffmpeg_sources
curl -O http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.4.tar.gz
tar xzvf libvorbis-1.3.4.tar.gz
cd libvorbis-1.3.4
LDFLAGS="-L$HOME/ffmeg_build/lib" CPPFLAGS="-I$HOME/ffmpeg_build/include" ./configure --prefix="$HOME/ffmpeg_build" --with-ogg="$HOME/ffmpeg_build" --disable-shared
make
make install
make distclean

#libvpx
cd ~/ffmpeg_sources
git clone --depth 1 https://chromium.googlesource.com/webm/libvpx.git
cd libvpx
./configure --prefix="$HOME/ffmpeg_build" --disable-examples
make
make install
make clean

#FFmpeg
cd ~/ffmpeg_sources
git clone http://source.ffmpeg.org/git/ffmpeg.git
cd ffmpeg
PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --prefix="$HOME/ffmpeg_build" --extra-cflags="-I$HOME/ffmpeg_build/include" --extra-ldflags="-L$HOME/ffmpeg_build/lib" --bindir="$HOME/bin" --pkg-config-flags="--static" --enable-gpl --enable-nonfree --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265
make
make install
make distclean
hash -r

現状・試したこと

実行するコードについては、公開を控えさせてください。。。
Lambdaから実行したときのログは下記のとおりで、どうやらec2-userのpyenv(存在しない)を見にいって落ちているようです。

Traceback (most recent call last):
  File "/home/ec2-user/hoge/MAIN1_KICKED_BY_LAMBDA.py", line 88, in <module>
    hogefuga.exeExtractWav(TMP_DIRECTORY2 + '/', nameonly)
  File "/home/ec2-user/hoge/fuga/hogefuga.py", line 175, in exeExtractWav
    extractWav(filename)
  File "/home/ec2-user/hoge/fuga/hogefuga.py", line 162, in extractWav
    ff.run()
  File "/home/ec2-user/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/site-packages/ffmpy.py", line 99, in run
    raise FFExecutableNotFoundError("Executable '{0}' not found".format(self.executable))
ffmpy.FFExecutableNotFoundError: Executable 'ffmpeg' not found

SSH接続しrootで直接実行した際はroot側のpyenvを見にいき問題なく実行されるのですが、解決策としては以下の2つでしょうか。

  • ec2-user環境にも同様にpyenv, ffmpeg環境を構築する
  • 実行ファイル類をrootのホーム配下へ移動する

そもそも直接実行とLambda実行でパスが変わる原因を明らかにしないとすっきりしませんが・・・。

(2017.05.23 17:12追記)

  • ec2-user環境にも同様にpyenv, ffmpeg環境を構築する
  • 実行ファイル類をrootのホーム配下へ移動する

両方試したものの、下記のエラーが出て終了。

----------ERROR-------
failed to run commands: exit status 1
Traceback (most recent call last):
  File "MAIN1_KICKED_BY_LAMBDA.py", line 17, in <module>
    import formatchg
  File "/root/fuga/hoge/fugahoge.py", line 10, in <module>
    from ffmpy import FFmpeg
ImportError: No module named ffmpy

続きを読む

awsサービス cloudformationからlambdaをキックさせる

cloudformationでインスタンスなどが立ち上げ終わった後に、マネジメントコンソールで管理しているlambdaを叩きたいなと思って実行したものです。

カスタムリソース

カスタムリソースというのが用意されています。これを使います。

こいつは何か?

AWSのCloudFormationのリソースタイプとして使用できないリソースを含める必要があるときに、それらのリソースは、カスタムリソースを使用して含めることができるらしい。つまりこの方法によりすべての関連リソースを1つのスタックで管理できるという優れものです。
今回だとて使用できないリソースとしてlambdaが当たりますがSQSとかもそうらしいです。以下のような感じで記述できます。Test1、Test2のように任意の文字列も渡せます。

"CustomResource" : {
  "Type" : "AWS::CloudFormation::CustomResource",
    "Properties" : {
        "ServiceToken": "指定のARN",
        "Test1": {"Ref": "InstanceName"},
        "Test2": {"Ref": "TargetGroupName"}
    }
}

使い方

lambdaをcloudformatinで使うにはあるものを呼ばないといけないらしい。それがcfn-responseモジュールと呼ばれるものだ。そしてこれを使うときの注意書きとして以下が記述してあります。

cfn-response モジュールは、ZipFile プロパティを使用してソースコードを作成した場合にのみ使用できます。S3 バケットに保存されたソースコードには使用できません。S3 バケットのコードでは、独自の関数を作成してレスポンスを送信する必要があります。

どういうことかというとcloudformationでlambdaを使うときは以下のようにコードを直書きしないと使えませんよということ。

"ZipFile": { "Fn::Join": ["", [
  "var response = require('cfn-response');",
  "exports.handler = function(event, context) {",
  "  var input = parseInt(event.ResourceProperties.Input);",
  "  var responseData = {Value: input * 5};",
  "  response.send(event, context, response.SUCCESS, responseData);",
  "};"

あれ??マネジメントコンソールですでに記述したやつを使いたかったのに・・・・
github調べてみたら出てきた

https://github.com/LukeMizuhashi/cfn-response/blob/c5bb51ada6110f4e84d7a8bad7799fd90e0b440d/index.js#L11

解決方法

実際に書いた。githubのほぼコピペなので迷うことありません。

cloudformation側

"CustomResource" : {
  "Type" : "AWS::CloudFormation::CustomResource",
    "Properties" : {
        "ServiceToken": "lambdaのARN",
        "Test1": {"Ref": "InstanceName"},
        "Test2": {"Ref": "TargetGroupName"}
    }
}

そうすると”lambdaのARN”で指定したlambdaを叩きに行く。そしてlambda側で以下を入れておく。

lambda側

var SUCCESS = "SUCCESS";
var FAILED = "FAILED";

var cfnResponse = function(event, context, responseStatus, responseData, physicalResourceId) {

    var responseBody = JSON.stringify({
        Status: responseStatus,
        Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName,
        PhysicalResourceId: physicalResourceId || context.logStreamName,
        StackId: event.StackId,
        RequestId: event.RequestId,
        LogicalResourceId: event.LogicalResourceId,
        Data: responseData
    });

    console.log("Response body:n", responseBody);

    var https = require("https");
    var url = require("url");

    var parsedUrl = url.parse(event.ResponseURL);
    var options = {
        hostname: parsedUrl.hostname,
        port: 443,
        path: parsedUrl.path,
        method: "PUT",
        headers: {
            "content-type": "",
            "content-length": responseBody.length
        }
    };

    var request = https.request(options, function(response) {
        console.log("Status code: " + response.statusCode);
        console.log("Status message: " + response.statusMessage);
        context.done();
    });

    request.on("error", function(error) {
        console.log("send(..) failed executing https.request(..): " + error);
        context.done();
    });

    request.write(responseBody);
    request.end();
}

exports.handler = (event, context, callback) => {
    // TODO implement
    if(event['RequestType'] == 'Delete'){
        cfnResponse(event, context, SUCCESS, {});
    }
    console.log(event);
    cfnResponse(event, context, SUCCESS, {});
};

これをlambda側に書いていないとインプログレスのまま一時間くらい止まってしまい、立ち上げ直さないといけない感じになる。

結果

cloudformationで環境を作った後に、lambdaを使うことに成功した。
その時にカスタマーリソールなるものを用いた、ちゃんとS3のcloudformationのタスクのレスポンスとして結果を返さないといけないので注意しましょ!!!

続きを読む

Security-JAWS#5レポート

こんにちは、ひろかずです。

5/22にトレンドマイクロさんで開催されたSecurity-JAWS#5に行ってきましたので、一筆書きます。

月曜に関わらず、盛況な集まりでした。

お品書き

Session1:トレンドマイクロ株式会社 姜 貴日さん「Deep SecurityとAWS WAF、SNS、Lambdaを使ってうまいこと自動防御する」
Session2:三井物産セキュアディレクション株式会社 大橋 和正さん「インシデント別対策から見るセキュリティ運用体制〜Alert Logicのことも少し〜」
Session3:エフセキュア株式会社 河野 真一郎さん「脆弱性について疑似クラッキング(デモ)をやってみる ~脆弱性対策はとても大切。でも多くの人はそれに気づかないんだ〜」
Session4:洲崎さん「AWS使って社内CTFを開催してみた」

Session1:「Deep SecurityとAWS WAF、SNS、Lambdaを使ってうまいこと自動防御する」

トレンドマイクロ株式会社 姜(かん) 貴日さん

DeepSecurityとは

サーバ向け総合セキュリティ対策製品
IPS/IDS, セキュリティログ監視, アンチマルウェア, 変更監視
単一の機能ではなく、多層防御の考え方でセキュリティを確保する製品。
AWSコンソールとDeepSecurityManagerが連携して、インスタンスの増減を自動で反映する機能もある。

自動防御の仕組み

今回の構成は、AWS上にALB(AWS WAF)-EC2(ECS)を配置した構成。
SNSとLambdaを用意
SecurityGroupは、隔離用のもの(Outbound,Inboudなし)を用意しておく

シナリオ1(自動ブロック)

  • Deep Security Agentの侵入防御(IPS/IDS)で検知する。
  • Deep Security ManagerからイベントがSNS送信される。
  • SNSは、Lambdaに通知する。
  • Lambdaは、送信元IPをAWS WAFのIP Condition(Blocked)に登録する。

シナリオ2(自動隔離)

  • DeepSecurityAgentのアンチマルウェアで検知
  • イベントがSNS送信
  • SNSはLambdaに通知
  • Lambdaは、検知したインスタンスIDのSGを隔離用のものに差し替え、Auto Scaling Groupから切り離す。
  • Auto Scaling Groupの設定により、差し替え用インスタンスが起動される

まとめ

より、リアルに近い環境でのPoCを実施したい。
共同PoC大募集中!声かけてください!

QA

IPは、トレンドマイクロのデータベースと突き合わせるのですか?

  • 今は検知ベースです。

テンプレートは公開されていますか?

  • まだです(公開予定)

IPはころころ変わると思いますが、リフレッシュとか考えてますか?

  • そういうフィードバック大歓迎です!

DSaaSは、どこまでの規模感に対応できますか?

  • DSaaSは、中規模向け。大規模ならDSMがいい。(中規模って、どれくらい?100大規模?)
  • 国内で1000超えはない。100大規模は実績ある。

DSaaSのバージョンアップってどうなんだろう?

  • Manager側は自動でバージョンアップされます。

Session2:「インシデント別対策から見るセキュリティ運用体制〜Alert Logicのことも少し〜」

三井物産セキュアディレクション株式会社 大橋 和正さん
もともとオンプレメインのセキュリティエンジニア出身。
三井物産セキュアディレクションは、セキュリティ診断、SOC、セキュリティコンサルティングをやっている。
Alert Logicの拡販はじめました。

セキュリティ脅威の動向

IPA発表の10大脅威では、標的型攻撃、ランサムウェアが多く、公開サーバではインジェクション系が多い。
VerizonでもWebサーバに対する攻撃がダントツ

ランサムによる被害

WannaCryの詳細は三井物産セキュアディレクションのサイトで公開中!

Apache Struts2脆弱性をついた情報流出の事例

Twitterで気づく等、対応の遅れがあった

セキュリティインシデントとは?

コンピュータセキュリティに関係する人為的事象で、意図的および偶発的なもの
意図的脅威

  • パスワードリスト攻撃
  • サービス拒否攻撃
  • 情報の持ち出し(内部犯行)
  • サイト改ざん(ハクティビズム、マルウェア配布)

偶発的脅威

  • 設定ミス
  • プログラムのバグ
  • メール誤送信(情報漏えい)
  • PC紛失(情報漏えい)

なぜ事前準備が必要?

100%攻撃を防ぐことはできない

  • 攻撃技術の進歩(いたちごっこ)
  • 人間が使う以上、100%はない(オペミスはない)

天災には備えるのに、セキュリティインシデントへの備えはしないの?

  • 対応の遅れが、ユーザーからの信頼失墜に結びつく。

どのようなインシデントがあって、どのような対応をするのか準備しておく。

AWSにおけるセキュリティインシデントについて

クラウドvsオンプレ

アジリティと自動化
高可用性

おなじみAWS責任共有モデル

コンピューティング、ネットワーク、ストレージ等、クラウド基盤はAWSの責任範囲
OSレイヤ以上は、利用者側の責任ではあるが、SIerやベンダーと協力して対応して行く必要がある。
インシデントの種類をマッピングして、対応すべきセキュリティインシデントを明確にすることが大事。

Alert Logicについて

セキュリティの専門家がSOCで監視している。
リクエストとレスポンスのペイロードがコンソールで見れる。

Session3:「脆弱性について疑似クラッキング(デモ)をやってみる ~脆弱性対策はとても大切。でも多くの人はそれに気づかないんだ〜」

エフセキュア株式会社 河野 真一郎さん

セキュリティ営業3年目(2月からエフセキュア所属)
本社はフィンランド
衣装はガルパンモチーフ

まずは質問

脆弱性をついたクラッキングデモを実際に見たことある方ー!(会場は半々)

今回のシナリオ

標的型メールの添付ファイル(履歴書)を送りつけて、開いてしまった。

前提条件

アンチウィルス、メールサーバ前段のFirewallでは阻害されない

  • 標的型攻撃なので事前調査している想定

AWS接続が簡単なのは、デモのため。

デモ

開いた時点で、Windows7の一般権限は取れている。
攻撃ツールを使用してコマンドプロンプトを操作できる。
1分に一回だけ使える脆弱性をついてAdministoratorに昇格。
PowerShellでDomain Adminを取るまで約6分

OSのパッチ適用してる?

Linuxでも脆弱性管理をしていなければ、ハッカーにかかれば危ない。
OSのパッチ適用だけでは不十分(脆弱性は全体の約12%)
ミドルウェア、アプリケーションの脆弱性が85%をを占める。

宣伝

エフセキュアでは、Rapid Detection Serviceというサービスがある。
デモのような脆弱性がないかを見て欲しいひとはコンタクトして!

Session4:「AWS使って社内CTFを開催してみたよ」

洲崎さん
謎の勉強会ssmjpの運営やってます。

某社で社内CTFを開催しました

会社のHP
30人規模から70人規模に参加者が増えた
セキュリティエンジニアに楽しんで貰える
集合研修方式
Jeopardy形式
CTF終了後には問題と解説を配布(希望者には環境も)

ガジェット

状況を表示するLED看板
ラズパイでスコアサーバのWebAPIに定期的に投げる
スコアサーバは自作
運用管理ダッシュボードを用意
競技PCはWorkspacesを使いたいなー(NGだった)

得られた知見

AWSでイベントやるには申請が必要。
日本語NG。英語で申請。
EC2のみ。WorkspacesはNG。
申請時にはかなり細かく聞かれる。終わるときにはイベント設計が終わってるレベル。
申請から承認まで7日と言われたが、割とすぐに承認がおりた。

Docker(ECS)を使いたかった

時間の関係でEC2に
使えたらECRでデプロイが超ラクになる

監視サーバ

Zabbix Docker Monitoringを使ってみた。
TCPとWebサービスについて

実際にかかった金額

準備期間を含めて$2555だった。
Workspacesの検証がなければもっと安くあがっただろう

QA

参加者の平均年齢は?

  • 若手が多かったが、ベテランまで

運営は何人?

  • 5人。問題は2人で作った。大変だった。他の人も巻き込んでいきたい。

参加者スキルのピンきり具合

  • 満足度は70%(研修としては悪め)
  • 事前にフルイにかけたけど、ミスマッチした方は残念だった。
  • トップは、CTF運営経験者だった

正答率は?

  • 71.38%。8割の問題が解かれた。
  • 2割の問題が解かれなかった。(作った人は凹んでた。作ったのに解かれないのは悲しい。)

最後に

質疑応答も活発でした!
次回も楽しみですね!

今日はここまでです。
お疲れ様でした。

続きを読む

DynamoDB は空文字を登録できない

DynamoDB は空文字を登録できないため、空文字チェックしてエラー回避する実装にする必要があります。

が、JSONとかの関係でどうしても登録したい場合は、以下のように単純にスペースで登録するとよいかもしれません。

ちなみに Lambda – Node.js 6.10 での例です。

'use strict';

const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient();

exports.handler = (event, context, callback) => {

    // 空文字チェック
    // ※DynamoDBの仕様で空文字を登録できないため、半角スペースで登録
    let resourcesPara = ' ';
    if (event.resources !== undefined && event.resources.length > 0) {
        resourcesPara = event.resources;
    }

    const params = {
        TableName: "tableName",
        Item: {
            "id": "newId",
            "resources": resourcesPara
        }
    };

    docClient.put(params, function(err, data) {
        if (err) {
            console.error('Unable to add item. Error JSON:', JSON.stringify(err, null, 2));
            // エラー
            callback(null, err);
        } else {
            console.log('Added item:', JSON.stringify(data, null, 2));
            callback(null, {"id": "newId"});
        }
    });
};

取得するときも単純に半角スペースを空文字にして返却。

'use strict';

const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient();

exports.handler = (event, context, callback) => {

    const params = {
        TableName: "tableName"
    };

    docClient.scan(params, function(err, data) {
        if (err) {
            console.error('Unable to get item. Error JSON:', JSON.stringify(err, null, 2));
            // エラー
            callback(null, err);
        } else {
            if (data.Count > 0) {
                // データあり
                for (let i = 0; i < data.Count; i++) {
                    // スペースのみの場合空文字にする
                    // ※DynamoDBの仕様で空文字を登録できないため、半角スペースで登録している
                    if (data.Items[i].resources === ' ') {
                        data.Items[i].resources = '';
                    }
                }
                callback(null, data.Items);
            } else {
                // データなし
                callback(null, '404 Not Found. Data is nothing.');
            }
        }
    });
};

続きを読む

【AWS】Amazon Lexのカスタムボットできんにくフレンズを作ろう[Part1]

タダです。

Amazon Lex(以下、Lex)と戯れてみたレポートを何回か書いてみたいと思います。
今回は、定型文の会話を行うカスタムボットを作ってみた時の紹介記事です。
社内のLT大会で話してみたので、その模様は以下からどうぞ。

社内ブログとか動画

[contents]

Lexの概要

さて、改めてLexの概要をまとめてみると、次のような特徴があります

  • Lexはアプリケーションの対話型インタフェースを作るのをサポートするサービス

    • チャットボット開発に最適
  • Lambda,Cognito,Polly,MobileHub 等とも連携可能
  • チャットのプラットフォームとして、Facebook Messanger,Twilio SMS,Slackと連携可能
  • 従量課金制

Lexの専門用語

Lexで扱う専門用語は次のものです

  • Bot : ボットそのもの
  • Intents : ユーザが入力した自然言語に応答する、ボットのアクションの固まり
  • Utterances : Intentsを発動する口頭もしくは入力されるフレーズ
  • Slot : Intentsを満たすための要求される入力データ
  • Prompt : Slotを引き出すためのフレーズ
  • Fulfillment : Intentsを実現するビジネスロジック

公式資料

やってみたこと

  • Slackにきんにくフレンズを召喚

    • 普段から使っているし、馴染みがある
  • きんにくフレンズBot(@musclechang)に話しかけて自分のトレーニングメニューを管理するものを作ってみたい
    • トレーニングしたいと話しかけると、トレーニングメニュー、回数、セット数を聞いてくれて、最後は励ますようなボットです

実現するためにやったこと

AWS側

Utterancesと、Slots、Promptはこんな感じです

Screen Shot 2017-05-21 at 10.25.05 PM.png

Slots typesは3つ作りました

  • Set(トレーニングのセット数)
  • Training Menu(トレーニングメニュー)
  • Count(何回やるかのカウント数)

Fulfillmentは、Lambdaでやらないので、「Return parameters to client」を選択しています
Screen Shot 2017-05-21 at 10.27.11 PM.png

Slack側

Slackの連携部分は、以下のドキュメントを参考にしました

結果

こんな感じの対話ができるフレンズができました!

Screen Shot 2017-05-21 at 10.06.30 PM.png

まとめ

  • ノンプラグラミングでボットを作れました

    • 定型文しか返せないので、AIぽく入力した情報を貯めて、より良いトレーニングメニューを提案するような感じにしていきたい
    • 次回に他のAWSリソースと連携してみたいです(Lambda,Pollyとの連携とか)

続きを読む

aws周りのメモ2

postgresqlを使う

RDSへpostgresqlをいれて立ち上げ

認証と接続

import-key-pair — AWS CLI 1.11.87 Command Reference
http://docs.aws.amazon.com/cli/latest/reference/ec2/import-key-pair.html

cd $HOGE
openssl genrsa -out my-key.pem 2048
openssl rsa -in my-key.pem -pubout > my-key.pub
# IAMのコンパネで*.pubを入力
# 多分、権限があれば以下でもいける
# aws iam upload-ssh-public-key

【AWS 再入門】EC2 + RDS によるミニマム構成なサーバー環境を構築してみよう – NET BIZ DIV. TECH BLOG
https://tech.recruit-mp.co.jp/infrastructure/retry-aws-minimum-vpc-server-environment/

便利

無料枠

無料のクラウドサービス | AWS 無料利用枠
https://aws.amazon.com/jp/free/

AMI

AWS Marketplace: Search Results
https://aws.amazon.com/marketplace/search/results?x=14&y=18&searchTerms=&page=1&ref_=nav_search_box

CFテンプレート

サンプルコード & テンプレート – AWS CloudFormation | AWS
https://aws.amazon.com/jp/cloudformation/aws-cloudformation-templates/

ec2 ami tool & ec2 api tool

Mac で Amazon EC2 API Toolsを設定する – サーバーワークスエンジニアブログ
http://blog.serverworks.co.jp/tech/2013/01/31/mac-amazon-ec2-api-tools-setup/

ec2 api toolは若干心配。

VPCを使う

接続の際に、sshを経由したい。sslでもいいけどなんかsshがいいなと。
パスワードよりkeyのほうがセキュアだからかな。

0から始めるAWS入門①:VPC編 – Qiita
http://qiita.com/hiroshik1985/items/9de2dd02c9c2f6911f3b

導入

Amazon VPC とは? – Amazon Virtual Private Cloud
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Introduction.html

公式のいろいろ

料金 – Amazon VPC | AWS
https://aws.amazon.com/jp/vpc/pricing/

基本は無料だけどNATとVPNは別課金。

【AWS 再入門】VPC 環境に踏み台サーバーを構築して SSH 接続してみよう – NET BIZ DIV. TECH BLOG
https://tech.recruit-mp.co.jp/infrastructure/retry-aws-bastion-host-vpc/#i-3

ec2(Bastion)を配置する必要がありそう。

【AWS 再入門】EC2 + RDS によるミニマム構成なサーバー環境を構築してみよう – NET BIZ DIV. TECH BLOG
https://tech.recruit-mp.co.jp/infrastructure/retry-aws-minimum-vpc-server-environment/

VPC に推奨されるネットワーク ACL ルール – Amazon Virtual Private Cloud
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Appendix_NACLs.html

vpcでのネットワークのポリシーの例

Default VPC

AWSのDefault VPCを削除して困った話 – MikeTOKYO Developers
http://blog.miketokyo.com/post/49939300091/aws-default-vpc

デフォルトvpcは削除したらダメか。使い分けがわからん。

Amazon EC2 と Amazon Virtual Private Cloud – Amazon Elastic Compute Cloud
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-vpc.html

基本の機能はデフォルトとそうじゃないvpcは同じだけど、
デフォルトvpcがないとちゃんと機能しない。
デフォルトの属性によって、指定がないとipを紐付けたりする。

VPCネットワーク設計

これだけ押さえておけば大丈夫!Webサービス向けVPCネットワークの設計指針 | eureka tech blog
https://developers.eure.jp/tech/vpc_networking/

ネットワークは一度稼働させると移行が大変なので、初期設計が非常に重要になります。

わかりやすい。図が特に。

  • Bastion
  • NAT
  • Security Group

ENI

インフラエンジニアに贈るAmazon VPC入門 | シリーズ | Developers.IO
http://dev.classmethod.jp/series/vpcfor-infra-engineer/

サブネットで指定したIPアドレスのうち、先頭4つと末尾の1つはVPCで予約されるため使用できません。

VPCでは常にDHCP有効とするのがポイントです。

また、DHCPサービスで伝えられる情報(DHCPオプション)は、変更することもできます。

仮想マシンにひもづくENIにより、DHCPサーバーから毎回同じMACアドレス、IPアドレスが付与されます。これは、仮想マシンの状態に依存しないため、仮想マシンを再起動しようと、一旦シャットダウンしてしばらくしてから起動した場合でも必ず同じアドレスが付与されます。

ENI(Elastic Network Interface)か。。なるほど。でも、使うことはなさそうだな。

NAT

IPマスカレードが使えないVPC
NATは、Static(静的・サーバー用途)とElastic(仮想・クライアント用途)がある。
個人的には、このNATインスタンスの実装は、あまり好きではありません。動きがややこしいですし、ユーザーが自分でNATインスタンスの管理をしなければならないのも煩雑な印象を受けます。VPCのネットワークサービスの一つとして提供される機能であれば、ユーザーからはなるべく抽象化され仮想マシンとして意識されないようにするべきと考えます。
ただ、ユーザーから仮想マシンとして見える分、機能・実装が具体的に把握できる点やカスタマイズ性が高い点は良いとも思っています。

NAT インスタンスと NAT ゲートウェイの比較 – Amazon Virtual Private Cloud
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/vpc-nat-comparison.html

なるほど。。

Bastion

AWSで最低限セキュアな構成を組む – Qiita
http://qiita.com/ausuited/items/09b626fa5264f0c650fd

パブリックSubnetにEC2インスタンス(踏み台サーバーとして)
NATインスタンスを作成した要領で、パブリックSubnetにEC2インスタンスを作成する。Security groupは新規に作成してSSHをAnywhereに。Key pairは厳重に管理。尚、踏み台サーバーは、使用する時以外はStoppedにしておく事で、さらにセキュアな状態とする。このデザインパターンをOn Demand Bastionパターンと呼ぶらしい。

詳しい。「On Demand Bastionパターン」か。なるほど。

vpcへの踏み台サーバー
ポートフォワーディング、トンネルなどと同じ意味。

Network ACL

インスタンス単位じゃなくサブネット単位でより制限してセキュアにしたい場合に使うのかな。

安全なVPC設計 — Commerce Hack
http://tech.degica.com/ja/2016/01/07/designing-vpc-and-subnets/


結局どうするのか、、ひとまずNATはつかわずに、Bistionをつくってみる感じかな。

アベイラビリティーゾーン

リージョンごとでの、障害などで全部やられないように物理的にセグメントされた範囲の単位かな。
RDSではセグメントグループに2つ以上のゾーンを含める。でも、一つしか使わなくていい。ということか。s

RDSのVPC間の移動

サブネットグループの関連付けを変えればいいらしい。間違って設定したので移動した。

【小ネタ】知っていましたか?RDSを別のVPCに移動できることを | Developers.IO
http://dev.classmethod.jp/cloud/aws/rds_can_move_to_another_vpc/

Bastion作成作業をしてみる

主に下記を参考。

【AWS 再入門】EC2 + RDS によるミニマム構成なサーバー環境を構築してみよう – NET BIZ DIV. TECH BLOG
https://tech.recruit-mp.co.jp/infrastructure/retry-aws-minimum-vpc-server-environment/

  • サブネットってなんだっけとか復習。
  • ストレージはどうするのか。
    • とりあえずssdにしたけどマグネティックでよかったかなあ。

      • ssd:$0.12 : 1 か月にプロビジョニングされたストレージ 1 GB あたり
      • マグネティック: 0.05 USD/GB-月
  • public IPは設定必要だよね
  • market placeからamiを取得した方がいいの?
    • とりあえず公式のウィザードを使ったけど。
  • 認証にIAMが追加されていたので使ってみた
    • これとは別にキーペアは必要ってことかな。
  • CFnテンプレート(CloudFormationテンプレート)というのがあるらしい。。
    • これでつくりなおそうかな。。
  • サブネットとかいろいろネットワーク系の設定
    • なんだかんだいっていろいろあった
  • セキュリティグループ
    • エイリアスみたいなセキュリティグループにできたらいいのに。タグや名前で明示化かな。
    • bastionは22をあけて、rdsは5432をbastionからのみあける
  • ログイン
  • DNS
    • あれ、パブリックDNSがうまく割り振ってないな。。
      AWSでPublic DNS(パブリックDNS)が割り当てられない時の解決法 – Qiita
      http://qiita.com/sunadoridotnet/items/4ea689ce9f206e78a523
    • RDSのDNS
      • nslookupしたら内部ipがかえってくるのね。接続できないけどなんか気持ち悪いな。これかな。。
        外部からdnsを引けることを気にしている人は見かけなくて便利だからって話なのかね。
        【AWS】VPC内でPrivate DNSによる名前解決 – Qiita
        http://qiita.com/y_takeshita/items/2eb5e6abb5eb5516d1de

やってるうちはいいけど、しばらくやらないと設定の方法とか忘れそう。。こういうのは学習コストだけじゃないな。

PlantUMLで図にしておく

Kobito.hQIwJs.png

VPC内のRDSへLambdaから接続。。

しまった!アンチパターンだそうだ。。

Lambda+RDSはアンチパターン – Qiita
http://qiita.com/teradonburi/items/86400ea82a65699672ad

Lambda + RDS benchmark – Qiita
http://qiita.com/taruhachi/items/3f95ae3e84f56edb3787

新し目の記事でIAM認証でクリアできそうな。。

【全世界待望】Public AccessのRDSへIAM認証(+ SSL)で安全にLambda Pythonから接続する – サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/tech/2017/04/27/rds-iam-auth-lambda-python/


セキュアに接続するのと速度のトレードオフになっていたのが
IAM認証のおかげで両方可能になったということっぽい。
でも、ネットのスループット、コネクション数(料金・負荷)、など、、ほかにも気にすることが出て来そうで若干不安。
非同期でよければキューイングして一回投げっぱなしすればどうだろう。
もしくは、似てるけど、Lambdaから一回値を返してもらってからRDSへ投げ直す。
これでいっかなあ。。Lambdaの意味がなくなる?うーん。

今後

  • 疑問としてrdsなど内部向けのdnsを外から見れなくできないものか。
  • というか、rdsのエンドポイントって再起動したら変わったりしないかね。ipは固定されるのか。
    • たぶん、サブネット内でdhcpになるのでipは変動するけどエンドポイントは固定。。じゃないかしら。

posgresqlをつかうための情報

Amazon RDS 上の PostgreSQL – Amazon Relational Database Service
http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.SSL

続きを読む

Serverless Step FunctionsにてLambdaの環境変数にStatemachineのARNを指定する方法

結論

以下のようにserverless.ymlを記述することで、Lambdaの環境変数にstatemachineのARNを記述することが出来ます。

serverless.yml
functions:
  hello:
    handler: handler.hello
    environment:
        statemachine_arn: ${self:resources.Outputs.HelloStepfunc.Value}

stepFunctions:
  stateMachines:
    hellostepfunc:
      definition:
        <your definition>

resources:
  Outputs:
    HelloStepfunc:
      Description: The ARN of the example state machine
      Value:
        Ref: HellostepfuncStepFunctionsStateMachine

plugins:
  - serverless-step-functions

これでstatemachineを実行するだけのLambdaファンクションを作って、Lambdaのイベントからstatemachineを開始することが可能となります。

続きを読む