「私、いくつに見える?」への返答機能をRoBoHoNに実装する(AWS Rekognition連携)

モバイル型ロボット電話 RoBoHoN に、AWS Rekognition APIを連携させ、ユーザーからの「私、いくつに見える?」という問いかけに返事をできるように実装しました。

キャプチャ.PNG

環境

Windows 7 SP1 64bit
Android Studio 2.3.1
RoBoHoN_SDK 1.2.0
RoBoHon端末ビルド番号 02.01.00
AWS SDK for Android 2.6.9

AWS Mobile SDK for Android 導入

  • 導入要件

 Android 2.3.3 (API Level 10) or higher

RoBoHoN は Android 5.0.2 (API Level 21 (Lollipop))

  • 参考

[AWS] Set Up the AWS Mobile SDK for Android
http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/setup.html

  1. Get the AWS Mobile SDK for Android.
  2. Set permissions in your AndroidManifest.xml file.
  3. Obtain AWS credentials using Amazon Cognito.

[qiita] Amazon Rekognitionで犬と唐揚げを見分けるアプリを作ってみた
https://qiita.com/unoemon/items/2bdf933127b6e225d036

  • 追加ライブラリ
compile 'com.amazonaws:aws-android-sdk-core:2.6.9'
compile 'com.amazonaws:aws-android-sdk-rekognition:2.6.9'
compile 'com.amazonaws:aws-android-sdk-cognito:2.6.9'

RoBoHoN実装

RoBoHoN独自の発語用 VoiceUI 、撮影用ライブラリ、そして Rekognition 通信を行き来をする実装を書いていきます。

  • Rekognition 通信部分参考

[AWS] Documentation » Amazon Rekognition » 開発者ガイド » Amazon Rekognition の開始方法 » ステップ 4: API の使用開始 » 演習 2: 顔の検出 (API)
http://docs.aws.amazon.com/ja_jp/rekognition/latest/dg/get-started-exercise-detect-faces.html

  • インターネット疎通とストレージパーミッション
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • RoBoHonシナリオ関連定義類
ScenarioDefinitions.java
/**
*  Guess my age? シーン、accost、通知設定
*/
public static final String SCN_CALL = PACKAGE + ".guess.call";
public static final String SCN_RES = PACKAGE + ".guess.res";

public static final String ACC_CALL = ScenarioDefinitions.PACKAGE + ".guess.call";
public static final String ACC_RES = ScenarioDefinitions.PACKAGE + ".guess.res";


public static final String FUNC_CALL = "guess_call";
public static final String FUNC_RES = "guess_res";


/**
* memory_pを指定するタグ
*/
public static final String MEM_P_RES = ScenarioDefinitions.TAG_MEMORY_PERMANENT + ScenarioDefinitions.PACKAGE + ".res"; 
  • HVML(ユーザーからの呼びかけで起動、年齢判定のための写真撮影の声かけ、年齢判定を通知する)
home.hvml
<?xml version="1.0" ?>
<hvml version="2.0">
    <head>
        <producer>com.dev.zdev.rekog</producer>
        <description>いくつにみえる?のホーム起動シナリオ</description>
        <scene value="home" />
        <version value="1.0" />
        <situation priority="78" topic_id="start" trigger="user-word">${Local:WORD_APPLICATION} eq
            いくつにみえる
        </situation>
        <situation priority="78" topic_id="start" trigger="user-word">
            ${Local:WORD_APPLICATION_FREEWORD} eq いくつにみえる
        </situation>
    </head>
    <body>
        <topic id="start" listen="false">
            <action index="1">
                <speech>${resolver:speech_ok(${resolver:ok_id})}</speech>
                <behavior id="${resolver:motion_ok(${resolver:ok_id})}" type="normal" />
                <control function="start_activity" target="home">
                    <data key="package_name" value="com.dev.zdev.rekog" />
                    <data key="class_name" value="com.dev.zdev.rekog.MainActivity" />
                </control>
            </action>
        </topic>
    </body>
</hvml>
rekog_call.hvml
<?xml version="1.0" ?>
<hvml version="2.0">
    <head>
        <producer>com.dev.zdev.rekog</producer>
        <description>Guess my age? 撮影呼びかけ</description>
        <scene value="com.dev.zdev.rekog.guess.call" />
        <version value="1.0" />
        <accost priority="75" topic_id="call" word="com.dev.zdev.rekog.guess.call" />
    </head>
    <body>
        <topic id="call" listen="false">
            <action index="1">
                <speech>お顔をよーく見せて……。写真を撮るよ…。<wait ms="300"/></speech>
                <behavior id="assign" type="normal" />
            </action>
            <action index="2">
                <control function="guess_call" target="com.dev.zdev.rekog"/>
            </action>
        </topic>
    </body>
</hvml>
rekog_res.hvml
<?xml version="1.0" ?>
<hvml version="2.0">
    <head>
        <producer>com.dev.zdev.rekog</producer>
        <description>Guess my age? 結果通知</description>
        <scene value="com.dev.zdev.rekog.guess.res" />
        <version value="1.0" />
        <accost priority="75" topic_id="call" word="com.dev.zdev.rekog.guess.res" />
    </head>
    <body>
        <topic id="call" listen="false">
            <action index="1">
                <speech>${memory_p:com.dev.zdev.rekog.res}にみえるみたいだよ</speech>
                <behavior id="assign" type="normal" />
            </action>
            <action index="2">
                <control function="guess_res" target="com.dev.zdev.rekog"/>
            </action>
        </topic>
    </body>
</hvml>
  • MainActivity(各所抜粋)
MainActivity.java

private boolean hascall;

//onCreate ファンクション にカメラ連携起動結果取得用レシーバー登録
        mCameraResultReceiver = new CameraResultReceiver();
        IntentFilter filterCamera = new IntentFilter(ACTION_RESULT_TAKE_PICTURE);
        registerReceiver(mCameraResultReceiver, filterCamera);

//onResume ファンクション にScenn有効化追記
        VoiceUIManagerUtil.enableScene(mVoiceUIManager, ScenarioDefinitions.SCN_CALL);
        VoiceUIManagerUtil.enableScene(mVoiceUIManager, ScenarioDefinitions.SCN_RES);

//onResume ファンクション にScenn有効化後、即時発話(初回のみ)

        if (mVoiceUIManager != null && !hascall) {
            VoiceUIVariableListHelper helper = new VoiceUIVariableListHelper().addAccost(ScenarioDefinitions.ACC_CALL);
            VoiceUIManagerUtil.updateAppInfo(mVoiceUIManager, helper.getVariableList(), true);
        }

//onPause ファンクション にScene無効化
        VoiceUIManagerUtil.disableScene(mVoiceUIManager, ScenarioDefinitions.SCN_CALL);
        VoiceUIManagerUtil.disableScene(mVoiceUIManager, ScenarioDefinitions.SCN_RES);        

//onDestroy ファンクション にカメラ連携起動結果取得用レシーバー破棄
        this.unregisterReceiver(mCameraResultReceiver);

    /**
     * VoiceUIListenerクラスからのコールバックを実装する.
     */
    @Override
    public void onExecCommand(String command, List<VoiceUIVariable> variables) {
        Log.v(TAG, "onExecCommand() : " + command);
        switch (command) {
            case ScenarioDefinitions.FUNC_CALL:
                // 写真呼びかけ状況設定
                hascall =true;
                //写真を撮る
                sendBroadcast(getIntentForPhoto(false));
                break;
            case ScenarioDefinitions.FUNC_RES:
                finish();
                break;
            case ScenarioDefinitions.FUNC_END_APP:
                finish();
                break;
            default:
                break;
        }
    }


    /**
     * カメラ連携の結果を受け取るためのBroadcastレシーバー クラス
     * それぞれの結果毎に処理を行う.
     */
    private class CameraResultReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.v(TAG, "CameraResultReceiver#onReceive() : " + action);
            switch (action) {
                case ACTION_RESULT_FACE_DETECTION:
                    int result = intent.getIntExtra(FaceDetectionUtil.EXTRA_RESULT_CODE, FaceDetectionUtil.RESULT_CANCELED);
                    break;
                case ACTION_RESULT_TAKE_PICTURE:
                    result = intent.getIntExtra(ShootMediaUtil.EXTRA_RESULT_CODE, ShootMediaUtil.RESULT_CANCELED);
                    if(result == ShootMediaUtil.RESULT_OK) {
                        // 1. 撮影画像ファイルパス取得 
                        final String path = intent.getStringExtra(ShootMediaUtil.EXTRA_PHOTO_TAKEN_PATH);
                        Log.v(TAG, "PICTURE_path : " + path);
                        Thread thread = new Thread(new Runnable() {public void run() {
                            try {
                                // 2. APIリクエスト、レスポンス取得
                                String res = (new GetAge()).inquireAge(path, getApplicationContext());
                                Log.v(TAG, "onExecCommand: RoBoHoN:" + res);
                                int ret = VoiceUIVariableUtil.setVariableData(mVoiceUIManager, ScenarioDefinitions.MEM_P_RES, res);
                                VoiceUIManagerUtil.stopSpeech();
                                // 3. RoBoHon 結果発話
                                if (mVoiceUIManager != null) {
                                    VoiceUIVariableListHelper helper = new VoiceUIVariableListHelper().addAccost(ScenarioDefinitions.ACC_RES);
                                    VoiceUIManagerUtil.updateAppInfo(mVoiceUIManager, helper.getVariableList(), true);
                                }
                            } catch (Exception e) {
                                Log.v(TAG, "onExecCommand: Exception" +  e.getMessage());
                            };
                        }});
                        thread.start();}
                    }
                    break;
                case ACTION_RESULT_REC_MOVIE:
                    result = intent.getIntExtra(ShootMediaUtil.EXTRA_RESULT_CODE, ShootMediaUtil.RESULT_CANCELED);
                    break;
                default:
                    break;
            }
        }
    }
  • AWS Rekognition通信
MainActivity.java
package com.dev.zdev.rekog;

/**
 * Created by zdev on 2017/12/10.
 */

import android.util.Log;
import android.content.Context;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.amazonaws.auth.CognitoCachingCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.rekognition.AmazonRekognitionClient;

import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.List;

import com.amazonaws.services.rekognition.model.DetectFacesRequest;
import com.amazonaws.services.rekognition.model.DetectFacesResult;
import com.amazonaws.services.rekognition.model.FaceDetail;
import com.amazonaws.services.rekognition.model.AgeRange;
import com.amazonaws.services.rekognition.model.Image;

public class GetAge {
    private static final String TAG = GetAge.class.getSimpleName();
    private static int newWidth = 326;
    private static int newHeight = 244;

    private String resMsg = "ゼロさいからひゃくさいの間 ";
    AmazonRekognitionClient amazonRekognitionClient = null;

    private Bitmap resizeImag(String path){
        return Bitmap.createScaledBitmap(BitmapFactory.decodeFile(path), newWidth, newHeight, true);
    };

    private void setAmazonRekognitionClient(Context appcontext){
        // Amazon Cognito 認証情報プロバイダーを初期化します
        CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
            appcontext,
            "us-east-1:XXXXXXXXXXXX", // ID プールの ID
            Regions.US_EAST_1 // リージョン
        );
        this.amazonRekognitionClient =  new AmazonRekognitionClient(credentialsProvider);
    };

    public synchronized String inquireAge(String path, Context appcontext) throws Exception {

        try {
            Bitmap img = resizeImag(path);

            if (this.amazonRekognitionClient == null) {
                setAmazonRekognitionClient(appcontext);
            }

            ByteBuffer imageBytes = null;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            img.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            imageBytes = ByteBuffer.wrap(baos.toByteArray());

            DetectFacesRequest request = new DetectFacesRequest()
                    .withImage(new Image()
                            .withBytes(imageBytes))
                    .withAttributes("ALL");

            DetectFacesResult result = amazonRekognitionClient.detectFaces(request);
            List<FaceDetail> faceDetails = result.getFaceDetails();

            Log.v(TAG, "inquireAge: " + faceDetails.toString());

            for (FaceDetail face: faceDetails) {
                if (request.getAttributes().contains("ALL")) {
                    AgeRange ageRange = face.getAgeRange();
                    Log.v(TAG, "inquireAge: " + ageRange.getLow().toString() + " and " + ageRange.getHigh().toString() + " years old.");
                    this.resMsg = ageRange.getLow().toString() + " さいから " + ageRange.getHigh().toString() + " さいの間 ";
                } else { // non-default attributes have null values.
                    Log.v(TAG, "inquireAge: " + "Here's the default set of attributes:");
                }
            }

            return this.resMsg;

        } catch (Exception e) {
            Log.v(TAG, "inquireAge: exception: " + e.toString());
            return this.resMsg;
        }
    }
}

実行の様子と感想

年末も近いし、色々とひとが集まる機会に使えたらいいな、と、パーティアプリにしたく、実装しました。
(Microsoft「How-Old.net」が流行ったときのように、1~2回/人 試して場が沸いたら上出来!という)

家族で試したところ、下記のようになりました。

  • 30代後半男性: 45 ~ 63 才 (!)の間
  • 30代後半女性: 26 ~ 38 才の間
  • 9才 … 6 ~ 13 才の間
  • 4才 … 4 ~ 7 才の間、4 ~ 9 才の間

私(30代後半)は 「14 ~ 23 才の間」というスコアも叩き出せたので、家族が沸き「ロボホンがひいきしてる!(子供たちの声)」「なんか匙加減して実装してない?」など、”結果をロボホンが発声する”1 という文脈も楽しめました。



  1. ロボホンSDK内規定(0201_SR01MW_Personality_and_Speech_Regulations_V01_00_01)には “ロボホンはユーザに対して誠実です。ユーザを裏切ることはありません(中略) 不確実な情報を話すときは、それとわかる言い回しをする(例:「雨になるよ」→「予報によると、雨になるみたいだよ」” があります。そのため、今回も結果通知の語尾に「~才にみえるよ」でなく「~才にみえるみたいだよ」とつけています。(また、同規定書には “主観を持たない”というくだり(”ロボホンはロボットです 。ロボットは 、基本的に プログラムされたとおりに動くものです 。ロボホン自身の主観(好き嫌いや感想など ロボホン自身の主観(好き嫌いや感想など 、人によって感じ方が変わるもの 、人によって感じ方が変わるもの )は 持たないのが基本的考え方です 。”)ともあります) 

続きを読む

Windows 10 ローカルに AWS S3 のクローン(minio)を手軽につくる

2017/12/10

Dockerのほうが動かなかったのでWSL側で動かしてみたらすぐにできたのでメモ。
(windowsでkitematic上で手軽に終えたかったのですが)

WSL: Windows Subsystem for Linux

(minioにたどり着くまでに、fakes3とs3ninjaをdockerで使ってみましたが、aws-sdkでput時にエラーが出たので乗り換えました)

minio のインストールと起動まで

以下からLinux向けをダウンロード
https://github.com/minio/minio

  • rootユーザーでやりましたが、rootである必要はないかも・・・
cd /root
wget https://dl.minio.io/server/minio/release/linux-amd64/minio

chmod +x minio
mkdir /minio_data

./minio server /root/minio_data

動作すると下記のような表示が出ます。

Created minio configuration file successfully at /root/.minio
Endpoint: ~省略~ http://127.0.0.1:9000
AccessKey: ~省略~
SecretKey: ~省略~

Browser Access: ~省略~ http://127.0.0.1:9000

Command-line Access: ~省略~ 

Object API (Amazon S3 compatible):
   Go:         https://docs.minio.io/docs/golang-client-quickstart-guide
   Java:       https://docs.minio.io/docs/java-client-quickstart-guide
   Python:     https://docs.minio.io/docs/python-client-quickstart-guide
   JavaScript: https://docs.minio.io/docs/javascript-client-quickstart-guide
   .NET:       https://docs.minio.io/docs/dotnet-client-quickstart-guide

Drive Capacity: 532 GiB Free, 910 GiB Total

minio の UI を使ってみる

  • ブラウザで http://127.0.0.1:9000 にアクセス

image.png

  • 上記のメッセージに出てきたアクセスキーとシークレットキーを入力してログイン

image.png

  • バケットを作る (入力してenter)

image.png

  • バケットを消す(消す機能はUIにない?)

仕方なく・・・ rm -rf で削除

# ll /root/minio_data/
合計 0
drwxrwxrwx 0 root root 4096 12月 11 01:17 ./
drwx------ 0 root root 4096 12月 11 00:50 ../
drwxrwxrwx 0 root root 4096 12月 11 00:57 .minio.sys/
drwxrwxrwx 0 root root 4096 12月 11 01:16 sample/
drwxrwxrwx 0 root root 4096 12月 11 01:17 sample2/
rm -rf /root/minio_data/sample2

ちゃんと消えました

spring boot から minio にアクセスしてみたときのポイント

接続情報としては下記でOKでした(SDKバージョンなどで書き方は少し違いがあるかもしれません)

エンドポイント:http://127.0.0.1:9000
アクセスキーとシークレットキーは上記のもの

ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setProtocol(Protocol.HTTP); <- ここがポイント!

EndpointConfiguration endpointConfiguration = new EndpointConfiguration("http://127.0.0.1:9000", null); <- ここがポイント!

AWSCredentials credentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY); <- ここがポイント!
AWSStaticCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);

AmazonS3 client = AmazonS3ClientBuilder.standard()
                            .withCredentials(credentialsProvider)
                            .withClientConfiguration(clientConfig)
                            .withEndpointConfiguration(endpointConfiguration).build();

今日はここまで m(_ _)m

続きを読む

upgrade amazon aws from Micro to Medium

さらに表示: aws add volume to running instance, ec2 change instance type while running, migrate ec2 instance to another region, aws resize ebs volume, aws change instance type greyed out, any data on the ephemeral storage of your instances will be lost., aws expand root volume windows, resize … 続きを読む

AWS EC2上のUbuntu16.04にデスクトップ環境を構築してMacからつなぐ

はじめに

やりたいこと

AWS EC2上にUbuntu16.04のインスタンスをたてて、そのインスタンスにMacからリモートデスクトップが接続する

なんでこの記事を書いたか

ぐぐってみると、日本語、英語で色々なドキュメントが出てきた。それらを参考に色々試したがサクッとはいかなかった。「どれを参考にすればいいねん!」って人向けに「これを実行すればサクッと構築できるよ」という情報を提供したかったから書いた。
ちなみに、X Window System、ubuntu-desktop、xrdp、Xfce4、GNOME、KDE、Unity、vncなどなど、
用語がわからなすぎたのでハードルが高く感じた。

いまはただのメモ

とりあえずメモ代わりに投稿するかってくらいのモチベーションで投稿してます。
もしここの記述がようわからんとかあれば、コメントいただければ少しずつ細かく書いていきます。

想定している読者レベル

  • EC2インスタンスをたてたことがある
  • なんとなくlinuxコマンドがつかえる

用語

X Window System

ディスプレイにウィンドウを表示したり、マウスやキーボードを使ってやりとりするためのシステム。WindowsやMacではOSとこのソフトウェアが一体化しているが、Linuxでは一体化してないのでもし先述のことを行いたい(=GUI)場合はインストールする必要がある。MacのOS Xの「X」とWindowsの「Window」がまざった「X Window System」という名称で紛らわしい。単に「X」と呼ばれることもある。

Xfce, GNOME, KDE, Unity,

デスクトップ環境を実現するためのシステム。色々あってややこしいが、デスクトップ上のデザインや機能が微妙に違うだけ。今回はXfceを使った。

vnc

ネットワーク越しに、別のコンピューターのデスクトップ画面を表示してGUI操作することができるシステム。今回Ubuntuで環境を構築するにあたって参照した記事ではvnc4serverかTightVNCのどちらかを使っていることが多かった。

手順

EC2インスタンス作成

下記参照にEC2インスタンスを作成
– AMIはクイックスタートにあるUbuntu 16.04
– セキュリティグループのインバウンドにポート5901を追加
– とりあえずt2.microでいい

デスクトップ環境構築

この記事のとおりでOK

sudo apt update && sudo apt upgrade

sudo sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
sudo /etc/init.d/ssh restart

sudo passwd ubuntu

sudo apt install xrdp xfce4 xfce4-goodies tightvncserver

echo xfce4-session> /home/ubuntu/.xsession

sudo cp /home/ubuntu/.xsession /etc/skel

sudo sed -i '0,/-1/s//ask-1/' /etc/xrdp/xrdp.ini

sudo service xrdp restart

tightvncserver

つなぐ

Finder起動->移動->サーバへ接続で、vnc://XX.XX.XX.XX:5901に接続。
XX.XX.XX.XXは作成したEC2インスタンスのIPかパブリックDNSを指定。
ただしvncはそのままでは暗号化されてないので、セキュアなことをやりたい場合はご自身で対応をお願いします。

ついでに日本語化

chromeをインストールしたら、日本語が文字化けしてたので日本語化してみた。
“Language support” icon missing in System Settings
英語環境でセットアップしてしまったUbuntuで日本語を使えるようにする

補足

  • tightvncserverでなくてvnc4serverでもOKだと思います(試してない)
  • xrdpはaptからのインストールでOK

続きを読む

AWS 上に JobScheduler を構築した話

AWSには自前でジョブ実行用のサービスがあるので、こういうのはあまりやらないと思いますが、色々とハマったのでメモ。

インストール

JobScheduler インストール

  1. インストーラーをここからダウンロードします。

    スクリーンショット 2017-06-08 0.33.37.png

  2. 解凍した中にある jobscheduler_install.xml を以下の形に修正します。

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!--
    XML configuration file for JobScheduler setup
    
    The JobScheduler is available with a dual licensing model.
    - GNU GPL 2.0 License (see http://www.gnu.org/licenses/gpl-2.0.html)
    - JobScheduler Commercial License (see licence.txt)
    
    The setup asks you for the desired license model
    (see <entry key="licenceOptions" .../> below).
    
    If you call the setup with this XML file then you accept
    at the same time the terms of the chosen license agreement.
    -->
    <AutomatedInstallation langpack="eng">
    <com.izforge.izpack.panels.UserInputPanel id="home">
        <userInput/>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="licences">
        <userInput>
    
            <!-- Select the license model (GPL or Commercial) -->
            <entry key="licenceOptions" value="GPL"/>
    
            <!-- If you selected GPL as license model than the licence must be empty.
                 Otherwise please enter a license key if available.
                 It is also possible to modify the license key later. -->
            <entry key="licence" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.HTMLLicencePanel id="gpl_licence"/>
    <com.izforge.izpack.panels.HTMLLicencePanel id="commercial_licence"/>
    <com.izforge.izpack.panels.TargetPanel id="target">
    
        <!-- SELECT THE INSTALLATION PATH FOR THE BINARIES AND LIBRARIES
             The installation expands this path with the Scheduler ID as subdirectory.
             The path must be absolute!
             Default paths are
             /opt/sos-berlin.com/jobscheduler for Unix
             C:Program Filessos-berlin.comjobscheduler for Windows -->
        <installpath>/opt/sos-berlin.com/jobscheduler</installpath>
    
    </com.izforge.izpack.panels.TargetPanel>
    <com.izforge.izpack.panels.UserPathPanel id="userpath">
    
        <!-- SELECT THE DATA PATH FOR CONFIGURATION AND LOG FILES
             The installation expands this path with the Scheduler ID as subdirectory.
             The path must be absolute!
             Default paths are
             /home/[user]/sos-berlin.com/jobscheduler for Unix
             C:ProgramDatasos-berlin.comjobscheduler for Windows -->
        <UserPathPanelElement>/home/joc/jobscheduler</UserPathPanelElement>
    
    </com.izforge.izpack.panels.UserPathPanel>
    <com.izforge.izpack.panels.PacksPanel id="package">
    
        <!-- SELECT THE PACKS WHICH YOU WANT INSTALL -->
    
        <!-- Package: JobScheduler
             JobScheduler Basic Installation
             THIS PACK IS REQUIRED. IT MUST BE TRUE -->
        <pack index="0" name="Job Scheduler" selected="true"/>
    
        <!-- Package: Database Support
             Job history and log files can be stored in a database. Database support is
             available for MySQL, PostgreSQL, Oracle, SQL Server, DB2.
             THIS PACK IS REQUIRED. IT MUST BE TRUE -->
        <pack index="2" name="Database Support" selected="true"/>
    
        <!-- Package: Housekeeping Jobs
             Housekeeping Jobs are automatically launched by the Job Scheduler, e.g. to send
             buffered logs by mail, to remove temporary files or to restart the JobScheduler. -->
        <pack index="5" name="Housekeeping Jobs" selected="true"/>
    
    </com.izforge.izpack.panels.PacksPanel>
    <com.izforge.izpack.panels.UserInputPanel id="network">
        <userInput>
            <!-- Network Configuration -->
    
            <!-- Enter the name or ip address of the host on which the JobScheduler is operated -->
            <entry key="schedulerHost" value="localhost"/>
    
            <!-- Enter the port for TCP communication -->
            <entry key="schedulerPort" value="4444"/>
    
            <!-- Enter the port for HTTP communication -->
            <entry key="schedulerHTTPPort" value="40444"/>
    
            <!-- To enter a JobScheduler ID is required.
                 The IDs of multiple instances of the JobScheduler must be unique per server.
                 The JobScheduler ID expands the above installation paths as subdirectory.
                 Please omit special characters like: /  : ; * ? ! $ % & " < > ( ) | ^ -->
            <entry key="schedulerId" value="schedulerId_XXXX"/>
    
            <!-- It is recommended to enable TCP access for the host where the JobScheduler will install,
                 optionally enter additional host names or ip addresses. To enable all hosts in your
                 network to access the JobScheduler enter '0.0.0.0'. -->
            <entry key="schedulerAllowedHost" value="0.0.0.0"/>
    
            <!-- Choose (yes or no) wether the JobScheduler should be started at the end of the installation -->
            <entry key="launchScheduler" value="yes"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="cluster">
        <userInput>
            <!-- Cluster Configuration -->
    
            <!-- The JobScheduler can be installed independent of other possibly JobSchedulers,
                 as a primary JobScheduler in a backup system or as a backup JobScheduler.
                 Use '' for a standalone, '-exclusive' for a primary
                 or '-exclusive -backup' for a backup JobScheduler.
                 A database is required for a backup system. All JobSchedulers in a backup system
                 must have the same JobScheduler ID and the same database.
                 Further you can set '-distributed-orders' for a load balancing cluster.
                 For more information see
                 http://www.sos-berlin.com/doc/de/scheduler.doc/backupscheduler.xml
                 http://www.sos-berlin.com/doc/de/scheduler.doc/distributed_orders.xml -->
            <entry key="clusterOptions" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="smtp">
        <userInput>
            <!-- Mail Recipients Configuration / SMTP Authentication -->
    
            <!-- Enter the ip address or host name and port (default: 25) of your SMTP server -->
            <entry key="mailServer" value=""/>
            <entry key="mailPort" value="25"/>
    
            <!-- Configure the SMTP authentication if necessary. -->
            <entry key="smtpAccount" value=""/>
            <entry key="smtpPass" value=""/>
    
            <!-- Enter the addresses of recipients to which mails with log files are automatically
                 forwarded. Separate multiple recipients by commas -->
    
            <!-- Account from which mails are sent -->
            <entry key="mailFrom" value=""/>
    
            <!-- Recipients of mails -->
            <entry key="mailTo" value=""/>
    
            <!-- Recipients of carbon copies: -->
            <entry key="mailCc" value=""/>
    
            <!-- Recipients of blind carbon copies -->
            <entry key="mailBcc" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="email">
        <userInput>
            <!-- Mail Configuration / Event Handler -->
    
            <!-- Choose in which cases mails with log files are automatically forwarded. -->
            <entry key="mailOnError" value="no"/>
            <entry key="mailOnWarning" value="no"/>
            <entry key="mailOnSuccess" value="no"/>
    
            <!-- The Housekeeping package is required for configure JobScheduler as event handler
                 Choose this option if you intend to use JobScheduler Events and
                 - this JobScheduler instance is the only instance which processes Events
                 - this JobScheduler instance is a supervisor for other JobSchedulers which submit Events -->
            <entry key="jobEvents" value="off"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="database">
        <userInput>
            <!-- JobScheduler Database Configuration -->
    
            <!-- Choose the database management system. Supported values are 'mysql' for MySQL,
                 'oracle' for Oracle, 'mssql' for MS SQL Server, 'pgsql' for PostgreSQL,
                 'db2' for DB2 and 'sybase' for Sybase. -->
            <entry key="databaseDbms" value="mysql"/>
    
            <!-- You can choose between 'on' or 'off' to create the database tables.
                 If you have modified the initial data of an already existing installation,
                 then the modifications will be undone. Data added remains unchanged.
                 This entry should be only 'off', when you sure, that all tables are already created. -->
            <entry key="databaseCreate" value="on"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="dbconnection">
        <userInput>
            <!-- JobScheduler Database Configuration -->
    
            <!-- Enter the name or ip address of the database host -->
            <entry key="databaseHost" value="the host of RDS"/>
    
            <!-- Enter the port number for the database instance. Default ports are for MySQL 3306,
                 Oracle 1521, MS SQL Server 1433, postgreSQL 5432, DB2 50000, Sybase 5000. -->
            <entry key="databasePort" value="3306"/>
    
            <!-- Enter the schema -->
            <entry key="databaseSchema" value="jobscheduler_data"/>
    
            <!-- Enter the user name for database access -->
            <entry key="databaseUser" value="databaseUser"/>
    
            <!-- Enter the password for database access -->
            <entry key="databasePassword" value="databasePassword"/>
    
            <!-- You have to provide the MySQL, MS SQL Server, Sybase or DB2 JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL, Sybase and MS SQL Server JDBC Drivers are
                 not provided. Alternatively you can use the mariadb JDBC Driver for MySQL and
                 the jTDS JDBC Driver for MS SQL Server and Sybase which is provided. -->
    
            <!-- You can choose between 'yes' or 'no' for using the jTDS JDBC Driver
                 This entry affects only MS SQL Server or Sybase -->
            <entry key="connectorJTDS" value="yes"/>
    
            <!-- You can choose between 'yes' or 'no' for using the mariadb JDBC Driver
                 This entry affects only MySQL -->
            <entry key="connectorMaria" value="yes"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="jdbc">
        <userInput>
            <!-- JobScheduler Database Configuration -->
    
            <!-- Configuration for JDBC Driver
                 This entry is only necessary if you selected a DBMS type such as MySQL,
                 MS SQL Server, Sybase ot DB2 in the previous <userInput> element. -->
    
            <!-- You have to provide the MySQL, MS SQL Server, Sybase or DB2 JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL and MS SQL Server JDBC Drivers are
                 not provided. Specify the JDBC Driver source (e.g. mysql-connector-java-*.jar for MySQL,
                 sqljdbc.jar for MS SQL Server, jconn3.jar for Sybase). Alternatively you can use the mariadb
                 JDBC Driver for MySQL and the jTDS JDBC Driver for MS SQL Server and Sybase which is provided. -->
    
            <!-- Select the path to JDBC Driver -->
            <entry key="connector" value="/usr/share/java/mariadb-connector-java.jar"/>
    
            <!-- Only for DB2: Select the path to DB2 license file for JDBC Driver -->
            <entry key="connectorLicense" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="reportingDatabase">
        <userInput>
            <!-- Reporting Database Configuration
                 NOT SUPPORTED FOR SYBASE AND DB2 -->
    
            <!-- Set 'yes' if the JobScheduler and the Reporting database are the same.
                 If 'yes' then further Reporting database variables are ignored. -->
            <entry key="sameDbConnection" value="yes"/>
    
            <!-- Choose the database management system. Supported values are 'mysql' for MySQL,
                 'oracle' for Oracle, 'mssql' for MS SQL Server, 'pgsql' for PostgreSQL. -->
            <entry key="reporting.databaseDbms" value="mysql"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="reportingDbconnection">
        <userInput>
            <!-- Reporting Database Configuration
                 NOT SUPPORTED FOR SYBASE AND DB2 -->
    
            <!-- Enter the name or ip address of the database host -->
            <entry key="reporting.databaseHost" value="qnet-jobscheduler.c58hqrvwigfw.ap-northeast-1.rds.amazonaws.com"/>
    
            <!-- Enter the port number for the database instance. Default ports are for MySQL 3306,
                 Oracle 1521, MS SQL Server 1433, postgreSQL 5432. -->
            <entry key="reporting.databasePort" value="3306"/>
    
            <!-- Enter the schema -->
            <entry key="reporting.databaseSchema" value="jobscheduler_data"/>
    
            <!-- Enter the user name for database access -->
            <entry key="reporting.databaseUser" value="reporting.databaseUser"/>
    
            <!-- Enter the password for database access -->
            <entry key="reporting.databasePassword" value="reporting.databasePassword"/>
    
            <!-- You have to provide the MySQL or MS SQL Server JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL and MS SQL Server JDBC Drivers
                 are not provided. Alternatively you can use the mariadb JDBC Driver for MySQL and the
                 jTDS JDBC Driver for MS SQL Server which is provided. -->
    
            <!-- You can choose between 'yes' or 'no' for using the jTDS JDBC Driver
                 This entry affects only MS SQL Server -->
            <entry key="reporting.connectorJTDS" value="yes"/>
    
            <!-- You can choose between 'yes' or 'no' for using the mariadb JDBC Driver
                 This entry affects only MySQL -->
            <entry key="reporting.connectorMaria" value="yes"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="reportingJdbc">
        <userInput>
            <!-- Reporting Database Configuration
                 NOT SUPPORTED FOR SYBASE AND DB2 -->
    
            <!-- Configuration for JDBC Driver
                 This entry is only necessary if the package 'Database Support' is chosen and you
                 selected a DBMS type MySQL or MS SQL Server in the previous
                 <userInput> element. -->
    
            <!-- You have to provide the MySQL or MS SQL Server JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL and MS SQL Server JDBC Drivers are
                 not provided. Specify the JDBC Driver source (e.g. mysql-connector-java-*.jar for MySQL,
                 sqljdbc.jar for MS SQL Server). Alternatively you can use the mariadb JDBC Driver for
                 MySQL and the jTDS JDBC Driver for MS SQL Server which is provided. -->
    
            <!-- Select the path to JDBC Driver -->
            <entry key="reporting.connector" value="/usr/share/java/mariadb-connector-java.jar"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="end">
        <userInput/>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.InstallPanel id="install"/>
    <com.izforge.izpack.panels.ProcessPanel id="process"/>
    <com.izforge.izpack.panels.FinishPanel id="finish"/>
    </AutomatedInstallation>
    
    
  3. setup.sh を実行します

    ./setup.sh jobscheduler_install.xml
    

JOC インストール

  1. JobScheduler と同様に JOC をダウンロードします。

    スクリーンショット 2017-06-08 0.35.42.png

  2. joc_install.xml を修正します。

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!--
    XML configuration file for JOC
    
    If you call the installer with this XML file then
    you accept at the same time the terms of the
    licence agreement under GNU GPL 2.0 License
    (see http://www.gnu.org/licenses/gpl-2.0.html)
    -->
    <AutomatedInstallation langpack="eng">
    <com.izforge.izpack.panels.UserInputPanel id="home">
        <userInput/>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.HTMLLicencePanel id="gpl_licence"/>
    <com.izforge.izpack.panels.TargetPanel id="target">
    
        <!-- SELECT THE INSTALLATION PATH
             It must be absolute!
             For example:
             /opt/sos-berlin.com/joc on Linux
             C:Program Filessos-berlin.comjoc on Windows -->
        <installpath>/opt/sos-berlin.com/joc</installpath>
    
    </com.izforge.izpack.panels.TargetPanel>
    <com.izforge.izpack.panels.UserInputPanel id="jetty">
        <userInput>
    
            <!-- JOC requires a servlet container such as Jetty.
                 If a servlet container already installed then you can use it.
                 Otherwise a Jetty will be installed in addition if withJettyInstall=yes.
                 You need root permissions to install JOC with Jetty. -->
            <entry key="withJettyInstall" value="yes"/>
            <entry key="jettyPort" value="4446"/>
            <!-- Only necessary for Windows -->
            <entry key="jettyStopPort" value="40446"/>
            <!-- Only necessary for Unix (root permissions required) -->
            <entry key="withJocInstallAsDaemon" value="yes"/>
            <!-- Path to Jetty base directory
                 For example:
                 /homer/[user]/sos-berlin.com/joc on Linux
                 C:ProgramDatasos-berlin.comjoc on Windows -->
            <entry key="jettyBaseDir" value="/home/joc/jetty"/>
    
            <!-- Java options for Jetty. -->
            <!-- Initial memory pool (-Xms) in MB -->
            <entry key="jettyOptionXms" value="128"/>
            <!-- Maximum memory pool (-Xmx) in MB -->
            <entry key="jettyOptionXmx" value="512"/>
            <!-- Thread stack size (-Xss) in KB -->
            <entry key="jettyOptionXss" value="4000"/>
            <!-- Further Java options -->
            <entry key="jettyOptions" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="reportingDatabase">
        <userInput>
            <!-- Reporting Database Configuration -->
    
            <!-- Choose the database management system. Supported values are 'mysql' for MySQL,
                 'oracle' for Oracle, 'mssql' for MS SQL Server, 'pgsql' for PostgreSQL. -->
            <entry key="reporting.databaseDbms" value="mysql"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="reportingDbconnection">
        <userInput>
            <!-- Reporting Database Configuration -->
    
            <!-- Enter the name or ip address of the database host -->
            <entry key="reporting.databaseHost" value="qnet-jobscheduler.c58hqrvwigfw.ap-northeast-1.rds.amazonaws.com"/>
    
            <!-- Enter the port number for the database instance. Default ports are for MySQL 3306,
                 Oracle 1521, MS SQL Server 1433, postgreSQL 5432. -->
            <entry key="reporting.databasePort" value="3306"/>
    
            <!-- Enter the schema -->
            <entry key="reporting.databaseSchema" value="jobscheduler_data"/>
    
            <!-- Enter the user name for database access -->
            <entry key="reporting.databaseUser" value="qnet_admin"/>
    
            <!-- Enter the password for database access -->
            <entry key="reporting.databasePassword" value="7sYne7aFEsFSK7xh"/>
    
            <!-- You have to provide the MySQL or MS SQL Server JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL and MS SQL Server JDBC Drivers are
                 not provided. Alternatively you can use the mariadb JDBC Driver for MySQL and
                 the jTDS JDBC Driver for MS SQL Server which is provided. -->
    
            <!-- You can choose between 'yes' or 'no' for using the jTDS JDBC Driver
                 This entry affects only MS SQL Server -->
            <entry key="reporting.connectorJTDS" value="yes"/>
    
            <!-- You can choose between 'yes' or 'no' for using the mariadb JDBC Driver
                 This entry affects only MySQL -->
            <entry key="reporting.connectorMaria" value="yes"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="reportingJdbc">
        <userInput>
            <!-- Reporting Database Configuration -->
    
            <!-- Configuration for JDBC Driver
                 This entry is only necessary if you selected a DBMS type such as MySQL and
                 MS SQL Server in the previous <userInput> element. -->
    
            <!-- You have to provide the MySQL or MS SQL Server JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL and MS SQL Server JDBC Drivers are
                 not provided. Specify the JDBC Driver source (e.g. mysql-connector-java-*.jar for MySQL,
                 sqljdbc.jar for MS SQL Server). Alternatively you can use the mariadb
                 JDBC Driver for MySQL and the jTDS JDBC Driver for MS SQL Server which is provided. -->
    
            <!-- Select the path to JDBC Driver -->
            <entry key="reporting.connector" value="/usr/share/java/mariadb-connector-java.jar"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="database">
        <userInput>
            <!-- JobScheduler Database Configuration -->
    
            <!-- Set 'yes' if the Reporting and the JobScheduler database are the same.
                 If 'yes' then further JobScheduler database variables are ignored. -->
            <entry key="sameDbConnection" value="yes"/>
    
            <!-- Choose the database management system. Supported values are 'mysql' for MySQL,
                 'oracle' for Oracle, 'mssql' for MS SQL Server, 'pgsql' for PostgreSQL,
                 'db2' for DB2 and 'sybase' for Sybase. -->
            <entry key="databaseDbms" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="dbconnection">
        <userInput>
            <!-- JobScheduler Database Configuration -->
    
            <!-- Enter the name or ip address of the database host -->
            <entry key="databaseHost" value="qnet-jobscheduler.c58hqrvwigfw.ap-northeast-1.rds.amazonaws.com"/>
    
            <!-- Enter the port number for the database instance. Default ports are for MySQL 3306,
                 Oracle 1521, MS SQL Server 1433, postgreSQL 5432, DB2 50000, Sybase 5000. -->
            <entry key="databasePort" value="3306"/>
    
            <!-- Enter the schema -->
            <entry key="databaseSchema" value="jobscheduler_data"/>
    
            <!-- Enter the user name for database access -->
            <entry key="databaseUser" value="qnet_admin"/>
    
            <!-- Enter the password for database access -->
            <entry key="databasePassword" value="7sYne7aFEsFSK7xh"/>
    
            <!-- You have to provide the MySQL, MS SQL Server, Sybase or DB2 JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL, Sybase and MS SQL Server JDBC Drivers are
                 not provided. Alternatively you can use the mariadb JDBC Driver for MySQL and
                 the jTDS JDBC Driver for MS SQL Server and Sybase which is provided. -->
    
            <!-- You can choose between 'yes' or 'no' for using the jTDS JDBC Driver
                 This entry affects only MS SQL Server or Sybase -->
            <entry key="connectorJTDS" value="yes"/>
    
            <!-- You can choose between 'yes' or 'no' for using the mariadb JDBC Driver
                 This entry affects only MySQL -->
            <entry key="connectorMaria" value="yes"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="jdbc">
        <userInput>
            <!-- JobScheduler Database Configuration -->
    
            <!-- Configuration for JDBC Driver
                 This entry is only necessary if you selected a DBMS type such as MySQL,
                 MS SQL Server, Sybase ot DB2 in the previous <userInput> element. -->
    
            <!-- You have to provide the MySQL, MS SQL Server, Sybase or DB2 JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL and MS SQL Server JDBC Drivers are
                 not provided. Specify the JDBC Driver source (e.g. mysql-connector-java-*.jar for MySQL,
                 sqljdbc.jar for MS SQL Server, jconn3.jar for Sybase). Alternatively you can use the mariadb
                 JDBC Driver for MySQL and the jTDS JDBC Driver for MS SQL Server and Sybase which is provided. -->
    
            <!-- Select the path to JDBC Driver -->
            <entry key="connector" value="/usr/share/java/mariadb-connector-java.jar"/>
    
            <!-- Only for DB2: Select the path to DB2 license file for JDBC Driver -->
            <entry key="connectorLicense" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="end">
        <userInput/>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.InstallPanel id="install"/>
    <com.izforge.izpack.panels.ProcessPanel id="process"/>
    <com.izforge.izpack.panels.FinishPanel id="finish"/>
    </AutomatedInstallation>
    
  3. setup.sh を実行します

    ./setup.sh joc_install.xml
    

続きを読む

AWS Fargateを使用してNginxを起動した(ENI使用)

AWS Fargateとは

AWS re:Invent2017でAWSが発表したコンテナホスト(インスタンス)を意識せずにコンテナを管理できるオーケストレーションサービスです。
現時点ではバージニア(us-east-1)リージョンのみでGAとなっています。
ちなみに、re:Inventに参加したので、現地でキーノートを聞いていましたが、同時にEKSも発表され待望のサービスが来た!という感じで私も会場もめちゃくちゃ興奮してました。

やってみる

クラスタの作成

リージョンはバージニアを選択し、Elastic Container Serviceの画面を開きます。
クラスターの作成ボタンを押してクラスタの作成を始めます。
(私の環境は元々別のクラスタが作成してあったので初めての場合表示が違うかもしれません)
console_aws_amazon_com_ecs_home_region_us-east-1.png

クラスタテンプレートの選択

以下の3つのクラスタテンプレートが選択できます。

  • Network only
  • EC2 Linux + Networking
  • EC2 Windows + Networking

Network onlyがFargateのようなので、こちらを選択して次のステップへ進みます。
console_aws_amazon_com_ecs_home_region_us-east-1__1_.png

クラスタの設定

ここではクラスタ名とネットワークの設定をします。
クラスタ名はFargateTestにしてみました。
また、このクラスタ用にVPCも合わせて作ってくれるオプションがあったので選択しました。
値はデフォルトのままで作成
console_aws_amazon_com_ecs_home_region_us-east-1__2_.png

起動ステータスの確認

作成が始まるとCloudFormationスタックが走ります。
しばらくするとイイ感じにクラスタができあがります。
console_aws_amazon_com_ecs_home_region_us-east-1__3_.png

クラスタの状態を確認

当然ですが実行中のタスクもサービスもありません。
console_aws_amazon_com_ecs_home_region_us-east-1__4_.png

タスク定義作成

新しくNginxを起動するタスクを定義します。
(私の環境は元々別のタスクが登録してあったので初めての場合表示が違うかもしれません)
console_aws_amazon_com_ecs_home_region_us-east-1__5_.png

ローンチタイプの選択

FARGATEEC2が選択できるので、当然FARGATEを選んで次のステップに進みます。
console_aws_amazon_com_ecs_home_region_us-east-1__6_.png

タスク定義の設定

適当にタスク定義に名前をつけます。ここではTestNginxとしました。
タスクのサイズ指定でメモリとvCPUを選択できます。
メモリは0.5GBと1GB~30GBまで1GB刻みで調整できるようです。
CPUは0.25、0.5、1、2、4から選択します。
ここではどちらも最小値の0.5GB、0.25vCPUを選択しました。
続いてコンテナの追加を行います。
console_aws_amazon_com_ecs_home_region_us-east-1__7_.png

コンテナの追加

コンテナ名を適当に定義します。ここではTestNginxにしました。
また、使用するコンテナイメージを指定します。DockerHubで公開されているNginxイメージをそのまま指定しました。
Nginxコンテナはポート80でListenするのでポートマッピングの設定は80となります。
その他は特に変更せずに追加し、そのまま作成します。
console_aws_amazon_com_ecs_home_region_us-east-1__8_.png

ローンチステータスの確認

ECSタスクと必要なIAM Roleが定義されたようです。
console_aws_amazon_com_ecs_home_region_us-east-1__9_.png

サービスの作成

クラスタの一覧から今回作成したFargateTestを選択します。
console_aws_amazon_com_ecs_home_region_us-east-1__11_.png

サービスの作成

サービスタブ内から作成します。
console_aws_amazon_com_ecs_home_region_us-east-1__12_.png

サービスの設定

Launch Typeは当然FARGATEを選択します。
また、タスク定義は先程作成したTestNginxを指定します。
サービス名には適当な名前をつけます。ここではTestNginxとしました。
console_aws_amazon_com_ecs_home_region_us-east-1__13_.png

ネットワーク構成の設定

参加するVPCを指定します。たぶん最初に作ったVPC IDが指定されていると思います。
コンテナが起動するサブネットを追加します。AZごとに別れていると思います。
また、セキュリティグループを編集することで既存のセキュリティグループを指定したり新規作成の内容を微調整できるようです。デフォルトのままだとポート80をAnyで公開します。
今回はELBを使用せずに直接コンテナに接続してみたいのでELBタイプはなしを選択しました。
このまま次のステップに進みます。
console_aws_amazon_com_ecs_home_region_us-east-1__14_.png

オートスケールの設定

オートスケールの設定ができますが、今回は実施しないのでそのまま次のステップに進みます。
console_aws_amazon_com_ecs_home_region_us-east-1__15_.png

サービスの確認

内容を確認してサービスの作成をします。
console_aws_amazon_com_ecs_home_region_us-east-1__16_.png

作成ステータスの確認

セキュリティグループの設定やサービスの設定が進みます。
console_aws_amazon_com_ecs_home_region_us-east-1__17_.png

動作確認

タスクのステータス確認

クラスタ内のタスクタブでステータスがRUNNINGになっていることを確認します。少し時間がかかる場合があります。
起動中のタスクIDを選択して詳細を確認します。
console_aws_amazon_com_ecs_home_region_us-east-1__18_.png

タスクの詳細確認

Networkの部分を見ると、ENI idがアタッチされていることが確認できます。
コンテナは外部に対してこのENIで通信します。
ENI IDを選択するとENIの画面に遷移します。
console_aws_amazon_com_ecs_home_region_us-east-1__19_.png

ENIの確認

ENIの画面に遷移したら、IPv4パブリックIPの部分を参照します。
ここに表示されているIPアドレスでコンテナと通信できます。
us-east-1_console_aws_amazon_com_ec2_v2_home_region_us-east-1.png

Nginxにアクセス

ブラウザで先程確認したIPアドレスにアクセスしてみます。
スクリーンショット 2017-12-05 17.28.17.png
無事Nginxが起動していました。

後片付け

作成したクラスタを削除します。
…と言いたいところですが、単純に削除したところ途中でエラーが出ました。
サービスを作成した際にできたセキュリティグループが残ってしまうので、CloudFormationStackが削除できないことが原因でした。
おそらく正しい手順はサービスの削除 -> セキュリティグループの削除 -> クラスタの削除となります。
まさか最後にアンチパターンにぶつかるとは。。。
console_aws_amazon_com_ecs_home_region_us-east-1__20_.png

最後に

インスタンスを意識する必要がないので保守範囲が減り、期待通りかなり魅力あるサービスだと感じました。
運用面では監視に課題が出てきそうなのかなーと思いました。
なんにせよ、Terraformへの組み込みと、東京リージョンでのサービス開始が待ち遠しいです。

続きを読む

AWS Systems Manager を試してみた

はじめに

12月1日よりオープンストリームに JOIN させて頂きました。
「オープンストリーム Advent Calendar 2017」5日目として先日開催された「AWS re:Invent 2017」で発表された「AWS Systems Manager」を試してみた感想を紹介したいと思います。

AWS Systems Manager とは

「AWS re:Invent 2017」で発表された管理系の新サービスです。
内容としては以前からあった「EC2 systems manager」や「AWS config」、「AWS CloudTrail」等の管理系のサービスを統合したインターフェースで利用できるイメージです。

https://aws.amazon.com/jp/blogs/news/aws-systems-manager/

AWS Systems ManagerはクラウドとハイブリッドIT環境を管理する新しい方法です。AWS Systems Managerは、リソースとアプリケーション管理を簡素化し、運用の問題を検知して解決する時間を短くし、セキュアに大規模なインフラを運用および管理することを容易にします。こちらのサービスは機能のすべてが含まれています。

なお、AWSとしては「EC2 systems manager」は旧サービスという扱いであり、「EC2 systems manager」を拡張させたのが「AWS Systems Manager」ということの様です。

https://aws.amazon.com/jp/blogs/news/aws-systems-manager/

EC2 Systems Manager (SSMと時々呼ばれます)は以前使用していたものです。aws ssmコマンドは引き続き呼び出し可能です。しかしAWS Systems ManagerはEC2 Systems Managerによって提供されるたくさんのツールの上に構築され、強化されています。

利用料金

AWS Systems Manager自体の利用料金は無料となっています。

開始方法

マネジメントコンソールのサービスから「開発者用ツール」のカテゴリー下で提供されているサービスとなっています。

リージョン

リージョン別のサービスとなっている様です。
そのため、東京リージョンのリソースは東京リージョン以外のAWS Systems Managerでは管理できない様なので注意が必要です。

サービスメニュー

以下のサービスメニューが選択できます。

264399db-6915-4ab5-8b3c-54b452151886.png

リソースグループ

リソースグループは簡単にいうと AWSのリソースをグルーピングできる機能となっています。
今までも「リソースグループ」自体はありましたが、今までのリソースグループからアップデートされた内容となっており、後述しますがリソースグループを利用して「AWS config」等の他の管理サービスが利用できる様になっています。1

Find Resources

リソースグループの新規登録画面です。リソースグループは「リソースタイプ」と「タグ」の組み合わせで定義し、複数の条件を AND 条件で複数指定する事もできます。ここらへんは今までのリソースグループと同じですね。
また、指定条件のクエリ結果も確かめる事ができます。

リソースグループの保存時には「グループ名」「グループの説明」「タグ」を指定できます。
なお、タグについてはリソースグループに所属しているリソースにタグを付けられるのではなく、リソースグループ自体にタグを付与する様です。

dc964c2b-914a-485e-8b1c-5895eb0aad48.jpg

Saved Resource Groups

保存したリソースグループの一覧とリソースグループに所属しているリソースを確認できます。

c979bebd-165d-482a-bce6-d502ce2c188d.jpg

インサイト

「AWS Config」「CloudTrail」「EC2 systems manager」等の管理系機能の情報を俯瞰的に参照できる機能です。
また、リソースグループを設定しておくことでグルーピング毎の情報の参照やフィルタリングする事も可能になっており、各々の機能で情報を参照するより利便性が高まった様な印象です。

Built-In Insights

Built-In Insights では以下の情報が参照できます。

  • Config

    • リソースグループ毎のAWS Config Rule の準拠状況のグラフ表示(compliment数/non compliment数)
    • リソースグループ紐付けの各リソースのAWS Config Ruleの準拠状況
    • リソースグループ紐付けの変更されたリソース及び変更回数
  • CloudTrail
    • リソースグループ紐付けの各リソースの最終イベント日時及びイベント内容
  • Personal Health Dashboard
    •  Personal Health Dashboardの問題の一覧
    •  リソースグループによるフィルタリングは不可
  •  Trusted Advisor
    •  Trusted Advisor のオーバービュー
    •  (問題なしの項目/推奨される調査/推奨されるアクションの総数)

Dashboard by CloudWatch

保存した cloudwatch ダッシュボードの一覧とダッシュボードを表示できます。
また、新規でダッシュボードを作成する事も可能です。
ただし、リソースグループによるメトリクスのフィルタリングはできない様です。

Inventory

「EC2 systems manager」で取得したインベントリ情報を元にインベントリデータをグラフ表示で俯瞰的に確認する事ができます。

  • トップ 5 の OS バージョン
  • トップ 5 のアプリケーション
  • トップ 5 のサーバーロール (Windows のみ)
  • トップ 5 のサービス
  • インベントリ取得対象のインスタンス一覧

4580bd08-4483-4299-8409-a95f6b68fea6.jpg

また、フィルタリング機能も要しており、リソースグループによるフィルタリングも可能ですが、リソースグループでフィルタするにはIAMサービスロールを作成する必要がある様です。

f1ac8f19-e46b-4eb1-b77b-37c5a4256be8.png

Compliance

「EC2 systems manager」の設定コンプライアンスの状況を棒グラフにより俯瞰的に確認することができます。
こちらもフィルタリング機能も要しており、リソースグループによるフィルタリングも可能ですが、リソースグループでフィルタするにはIAMサービスロールを作成する必要がある様です。

7f6d7441-2b98-4239-96fa-97f96cd2cbb4.jpg

また、個々のインスタンスの設定コンプライアンス状況も一覧で確認することができます。

アクション/共有リソース

「アクション」及び「共有リソース」は「EC2 systems manager」の機能している様です。
「EC2 systems manager」からUIが一部変更されており、「Automation」の機能ではリソースグループを利用して入力パラメータの指定を行う事が可能になった様です。

a1acf56b-dbd8-4094-befa-26e33d09a9ee.jpg

尚、個々の機能の説明は「EC2 systems manager」の説明となるため、割愛します。

まとめ

結局、サービス紹介となってしまいましたが、別機能として独立していた管理系の機能を同一機能上で確認できる様になった点は便利になったのかなという印象です。
また、リソースグループの機能もグルーピングの情報を他のサービスで利用できる様になったのも良いアップデート内容であったと感じました。
今後、本機能についてより良い利用方法を考えていきたいと思います。


  1. 今までのリソースグループはClassic グループとして継続利用できます。 

続きを読む

クラウドベンダーの比較

はじめに

3大クラウドと呼ばれているAWS、GCP,Azureのリソースを比べてみました。
2017年11月時点の比較となります。

インフラ・サービスレベル

比較項目 AWS GCP Azure 備考
データセンター 各地で借りている すべて自前 各地で借りている(一部自前)
仮想化技術 Xen KVM Hyper-V
リージョン(国内) 1個所 1個所 2個所
リージョン(全国) 15個所 12個所 36個所
SLA 99.95 99.95 99.95 仮想サーバ

サービス面

比較項目 AWS GCP Azure 備考
仮想サーバ Amazon EC2 Google Compute Engine Azure Virtual Machines
仮想サーバ対応OS Amazon Linux,CentOS,RedHat,Windows Server,等 CentOS,RedHat,SLES,Windows Server,等 CentOS,RedHat,Windows Server,等
仮想サーバディスク SSD,HDD SSD,HDD SSD,HDD
仮想サーバスナップショット
仮想サーバオートスケール
コンテナ Amazon ECS Container Engine Container Service
RDB RDS Cloud SQL SQL Database
RDB冗長化
RDBリードレプリカ
RDB DB種別 Aurora,MySQL,MariaDB,Oracle,SQL Server,PostgreSQL MySQL,PostgreSQL SQL Server
NoSQL DynamoDB Cloud Datastore Cosmos DB
ビックデータ Redshift BigQuery App Service
メール Amazon SES
モニタリングツール CloudWatch Stackdriver Azure Monitor
ロードバランサー(L4) CLB Network load balancing Azure Load Barancer
ロードバランサー(L7) ALB HTTP load balancing Application Gateway
CDN Amazon CloudFront Google Cloud CDN Azure CDN
VPN Amazon VPC Google Cloud VPN VPN Gateway
DNS Route53 Google Cloud DNS Azure DNS
専用線 Direct connect Dedicated Interconnect Express Route

サポート面

比較項目 AWS GCP Azure 備考
ランク低 開発者 ($29/月 or 利用料の 3%/月) シルバー ($150/月) Standard($300/月)
ランク中 ビジネス($100/月 or 利用料 の10%/月) ゴールド($400/月) Professional Direct($1,000/月)
ランク高 エンタープライズ($15,000/月 or 利用料の10%) プラチナ(問合せ) Premier(問合せ)

費用面(リージョン日本)

比較項目 AWS GCP Azure 備考
課金単位
ディスカウント リザーブドインスタンス(前払い) 継続利用割引、利用確約の割引(前払い) エンタープライズ契約(前払い)
仮想サーバ(Type) t2.medium(2vCPU,4GB) n1-standard-2(2コア,7.5GB) A2 V2(2コア,4GB)
仮想サーバ(時) $0.0464(5.336円)※1 $0.0950(10.925円)※1 $0.15(17.25円)※1
仮想サーバ(月) $33.408(3841.92円)※1 $48.17(5539.55円)※1,※2 $108(12,420円)※1
インターネットへの転送量 $0.140/GB(10TBまで) $0.12/GB(1TBまで) $0.138/GB(5GB-10TB、5GBまでは無料)
ストレージ利用料 $0.025/GB (最初の50TB/月まで) ※S3 $0.016/GB 月 ※Regional Storage $0.2/GB(最初の50TB/月まで) ※BLOG Storage

※1 $1=115円換算
※2 継続利用割引含む

総括

 AWS、GCP,Azureでのサービス面では同じようなサービスを展開していることが判明。
 インフラ・サービスレベルでは、Azureがリージョン36個とTOPに。
世界的に見て幅を利かせているように思えた。
ただ、GCPはすべて自前のセンターでクラウドサービスを展開していることから、
新しいことをやるにも制約が低いように思えた。
私のイメージ的に一番シェアが高いAWSは、インフラ面ではGCP,Azureに劣っている結果となった。
 費用面では、Azureは割高。AWSが思ったよりも頑張っているように思えた。
 イメージ的にGCPは費用は安いと思っていたが、仮想サーバ比較だと、継続利用割引を使用してもAWSのほうが安い結果となった。
 ただ、費用に関しては、日々値下げ合戦が繰り広げられているので、今後のベンダーさんの努力に期待です。

最後に、費用面での算出に使用した見積もりツールです。
【AWS】http://calculator.s3.amazonaws.com/index.html
【GCP】https://cloud.google.com/products/calculator/?hl=ja
【Azure】https://azure.microsoft.com/ja-jp/pricing/calculator

続きを読む

AWSをさわってみたのでつまずいた点などをメモ – Qiita

… ですが、2度の故障を経て、重たい腰を上げました。別にWindows使いたいわけもなく「ローカルが煩わしい」だけなので、 Windowsアプリは一切インストールしていません 。で、どうやって暮らしてるの? というお話です。 TL;DR このあたり↓を組み合わせていけば、クラウド生活可能: GCP (or AWS) Codeanywhere (or Kod. 続きを読む

VPC内に置いたElasticsearch ServiceにEC2のプロキシ経由でアクセスする

先日のアップデートでElasticsearch ServiceをVPC内で使えるようになりました。
https://aws.amazon.com/jp/blogs/news/amazon-elasticsearch-service-now-supports-vpc/

これまではパブリックなエンドポイントしか使えず、VPC内からアクセスするにはパブリックサブネットからの通信が必要でした。
VPC内に配置できれば、通信も全部VPC内で完結しますし、よりセキュアに使うことができるようになりますね。

さて、VPC内に配置したときに起きる問題の一つが、 直接ローカルからKibanaを見ることができない という問題です。
パブリックサブネットに配置してセキュリティグループで接続許可すれば行けるだろう、と最初は思ったんですが、どうやら無理みたいです。
※うまく行った、という方がいたらご教示ください…。

これを解決するためにどうするかについてはいろいろ調べてみました。
1. ALBを使う。
こちらを参考
https://dev.classmethod.jp/cloud/aws/make-public-kibana-amazon-es/
メリットは管理するサーバが増えないこと。
デメリットは、Elasticsearch ServiceのプライベートIPは可変なのに対し、ALBはターゲットにIPかEC2インスタンスしか設定できず、ターゲットのIPを定期更新するなどしなければならないこと。
1. EC2にKibanaをインストールして、Easticsearch Serviceを参照するようにする。
こちらを参考
https://dev.classmethod.jp/cloud/aws/make-public-kibana-amazon-es2/

メリットは、ドメイン指定が可能なのでElasticsearch ServiceのIPが変わっても大丈夫なことなど。 デメリットは、Kibanaの部分がEC2依存になること。
1. Windowsのインスタンスを立ててそこにリモートデスクトップでアクセスし、Windowsインスタンス内のブラウザからKibanaにアクセスする。
読んで字のごとくです。
メリットはやることが単純明快なことかな?
デメリットは大抵のケースで余計なEC2インスタンスを増やさざるを得ないこと。
1. EC2をプロキシサーバにする。(今回の方法)
EC2にKibanaを入れるパターンに近いですが、KibanaもElasticsearch Serviceのものを使用するので、Kibanaの可用性をElasticsearch Service(つまりAmazon側)に依存させたままにできるのがメリットです。
デメリットはこちらもアクセスがEC2依存になること。

今回は調べてもVPC内に配置したElasticsearch Serviceを参照するために使用したという例が見つからなかった、プロキシサーバを使う例について書いてみます。
※別の目的でプロキシサーバ経由にする例はたくさんありましたが、いずれも今回のアップデート以前の情報でした。
今回の例ではnginxを使用しますが、別にApacheでもなんでもいいと思います。

方法

パブリックサブネットにEC2インスタンスを用意する。

特に何も考えずにAmazon Linuxでよいと思います。
インスタンスタイプはとりあえずt2.microでもいいですが、
使ってるうちに負荷がしんどいなと思ったら適宜変更しましょう。
当然のことながら、SSHに加えhttpでアクセスできるようにセキュリティグループを設定します。
場合によっては踏み台サーバと共用とかでも大丈夫かなと。
※今回の例ではhttpを使用し、httpsではやらないようにします。
httpsを使用する例はこちら。(今回の設定もこちらを参考にしています。)
http://inokara.hateblo.jp/entry/2016/10/22/123538

用意したEC2からElasticsearch Serviceクラスタにアクセスできるようにする。

セキュリティグループの設定およびアクセスポリシーを適切に設定します。
セキュリティグループだけにしてもいいですし、リソースベース、IPベース、IAMユーザ・ロールベース等ポリシー設定できるのでその時の要件に沿って適切に設定すればOK。
http://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-createupdatedomains.html#es-createdomain-configure-access-policies
余談ですが、Elasticserch Serviceの設定変更には意外と時間がかかるので、なるべく設定変更が少ないほうが気持ちが楽だと思います。

EC2インスタンスにnginxをインストールする。

深く考えずにyumでOKです。

sudo yum -y install nginx

/etc/nginx/nginx.confを編集する。

50行目付近に

nginx.confの一部
        include /etc/nginx/default.d/*.conf;
        location / {
        }

みたいに空で設定されているところがあるので、下記のようにします。
※抜粋、略記しています。

nginx.confの一部
        include /etc/nginx/default.d/*.conf;
        location / {
            proxy_pass https://xxxxxxxxxxxxxx.amazonaws.com/;
        }

といった感じに、proxy_pathでVPCエンドポイントを指定します。
httpsじゃなくてもいいみたいですが、httpsで問題なくアクセスできます。

nginxを起動する。

nginxのサービスを起動します。ついでに自動起動もONにしておきましょう。

sudo service nginx start
sudo chkconfig nginx on

これで
http://{{設定したインスタンスのパブリックIP}}/_plugin/kibana
にアクセスしてやれば、EC2を経由して該当のElasticsearch ClusterのKibanaにアクセスできます。

課題とかおまけとか

後ろに_plugin/kibanaをつけないでアクセスするとElasticsearchにもアクセスできちゃうので、それを良しとするかどうかは要検討です。
逆にローカルから手軽にデータ投入できたりもするわけですが…。どこまで許容するかですね。
そこを気にするのであれば、nginxの設定とかでディレクトリごとにアクセス制御するとかが必要かもしれません。

あと、Elasticsearch Serviceを配置したVPCにVPN接続している場合はこんなことしなくてもVPNエンドポイントを指定して直接参照できる気がするので、試した方いたらご教示くださると嬉しいです。

ALBでElasticsearch Serviceのインスタンスを指定できるようになればいいんですけどねえ。

続きを読む