EC2 Systems Manager で Ansibleを実行する【cloudpack大阪ブログ】

cloudpack大阪の佐々木です。
EC2 Systems Manager で Ansibleが直接実行できるらしいのでやってみました。
https://aws.amazon.com/jp/blogs/mt/running-ansible-playbooks-using-ec2-systems-manager-run-command-and-state-manager/

2017/05/26時点では、東京リージョンで AWS-RunAnsiblePlaybook のドキュメントが見つからないので、対応していないのかと思います。今回は、us-east-1で実行しています。

EC2の作成

OSはAmazonLinux(amzn-ami-hvm-2017.03.0.20170417-x86_64-gp2 (ami-c58c1dd3))でやってみます。
SSMが実行できるIAM Roleを適用します。
起動後にSSMエージェントと、ansibleのインストールが必要ですが、どうせならログインせずにやりたいので、UserDataをこんな感じにしときます。

#!/bin/sh
cd /tmp
curl https://amazon-ssm-$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//g').s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm -o amazon-ssm-agent.rpm
yum install -y amazon-ssm-agent.rpm
/usr/bin/pip install ansible

インストールに成功していれば、マネージドインスタンスの一覧に表示されているかと思います。

Kobito.PjHL2B.png

関連付けの作成

一覧から該当の実行するインスタンスをチェックし、関連付けの作成 をクリックします。

ドキュメントを選択 から AWS-RunAnsiblePlaybook を選択します。
Kobito.6Ll3yi.png

インスタンス選択し、パラメーターのところのにAnsibleの設定をします。
Playbook に下記のような実行したいAnsibleのPlaybookを入力します。

- hosts: all
  become: true

  tasks:
  - name: yum install for Apache Web Server
    yum: name=httpd24

  - name: Start and Enable to Apache
    service: name=httpd state=started enabled=yes

ログを残す場合は S3 への書き込み にチェックを入れ、バケット情報を入力します。
Kobito.Ujt33a.png

Playbookurlhttps://〜s3://〜 でyamlファイルを指定して、外部のPlaybookを読み込むこともできます。

関連付けの作成 をクリックします。

実行

しばらくすると、自動的に実行されます。ステータスが 成功 になっていれば適用されていると思います。

Kobito.T8jToh.png

S3にログを保存しているとこんなログが残ります。

ansible 2.3.0.0
  config file = 
  configured module search path = Default w/o overrides
  python version = 2.7.12 (default, Sep  1 2016, 22:14:00) [GCC 4.8.3 20140911 (Red Hat 4.8.3-9)]

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [yum install for Apache Web Server] ***************************************
changed: [localhost]

TASK [Start and Enable to Apache] **********************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=2    unreachable=0    failed=0   

まとめ

今までもUserDataやRunCommandで実行していましたが、yamlを書くだけでできるので、簡単に利用できるようになっています。
ただ、外部から取り込む場合、1ファイルで完結するPlaybookしか読み込めないようなので、Role等ディレクトリを分けて管理している場合は使えないのではないのかな・・・。
そうなると簡単なものしか使えないような気がしますので、そのあたりが改善されればって感じです。

続きを読む

AWS Lambdaが実行されているリージョンを取得する

AWS_DEFAULT_REGIONという環境変数にリージョンが設定されいるので、お使いの言語で環境変数にアクセスすれば取得できます。
pythonだと以下のようになります。

import os
def lambda_handler(event, context):
    print "REGION:" + os.getenv("AWS_DEFAULT_REGION")

続きを読む

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割の問題が解かれなかった。(作った人は凹んでた。作ったのに解かれないのは悲しい。)

最後に

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

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

続きを読む

ビンパッキング問題を利用してクラウド利用料を安くする

ビンパッキング問題を利用したクラウド利用の最適化

さて、AWSやAzure、GCPのようなクラウドを利用していると、どのアプリケーションをどのサイズの仮想マシンに登載すれば効率的なのか、迷うことがあります。
アプリケーションのCPU、メモリ、ディスク利用量が判明しているとして、アプリケーションをどのサイズの仮想マシンに入れれば良いか、コロケーションした方が良いのか、分散した方が良いのか・・・いろいろと考えることはあります。
クラウド利用歴の長い技術者は経験則でどのサイズを選ぶのか、わかったりするもののようです。
しかし今回はちょっとアプローチを変えて、最適化問題として解決策を見出だせないかな、と考えてみました。

例えば以下のような状況で、どのサイズのアプリケーションをどのサイズの仮想マシンに入れれば、効率的でしょうか?

1.png

まずはおことわり

最適化問題が面白そうだったので、勉強がてら、自分にとって身近な問題で考えてみました。
最適化問題歴1週間なので、間違っている箇所やアドバイスはご指摘ください。

なお、勉強に使ったのは以下の本です。
Python言語によるビジネスアナリティクス 実務家のための最適化・統計解析・機械学習

問題設定

今回は必要な数のアプリケーションをクラウドの仮想マシンに登載した結果、費用が一番安くなる構成を、ビンパッキング問題として求めたいと思います。

ビンパッキング問題とは、ある入れ物(箱やビン、コンテナ)に荷物(重さや個数が定められている)を詰める際、必要な入れ物の最少数を求める組み合わせ最適化問題です。
例えば、引っ越しの際に荷物をダンボールに詰めると思いますが、そのダンボールの数を最少にする詰め方を解くものです。

2.png

荷物をダンボールに詰めるのであれば、ダンボール箱の体積(横×縦×高)と耐荷重量に対し、荷物の体積と重さを考慮して入れます。
これを見た時、荷物をアプリケーション、ダンボールを仮想マシンとして、体積や重さをCPU, RAM, Disk, 費用に置き換えれば、クラウドの仮想マシン利用を最適化することができる気がしたのが、今回の発端です。

環境

Pythonで最適化問題を解いてみたいと思います。
Pythonでは最適化問題を解くのに便利なライブラリが色々提供されていまして、ここに詳しく説明されています。
最適化におけるPython

今回はPython3.5(Anaconda)でopenoptを使いました。
OSはCentOS7.3です。
Openoptは数理最適化のモデルを作るライブラリです。

この環境へのopenoptのインストール方法は以下のとおりです。

conda install --channel https://conda.anaconda.org/cachemeorg funcdesigner openopt
pip install cvxopt
pip install glpk

やること

今回はアプリケーションを3種類に分けます。
小さいアプリケーション、中くらいのアプリケーション、大きいアプリケーションです。
それぞれのリソース利用量は以下とします。

小さいアプリケーション 中くらいのアプリケーション 大きいアプリケーション
CPU: 0.2 CPU: 0.5 CPU: 2.4
RAM: 256MB RAM: 512MB RAM: 2048MB
DISK: 1GB DISK: 10GB DISK: 40GB

これらを以下のEC2インスタンスサイズのうち、どれに詰め込むと一番安くなるか、ビンパッキング問題を使って解きます。

M4.4xlarge R3.2xlarge C4.2xlarge
CPU: 16vCPU CPU: 8vCPU CPU: 8vCPU
RAM: 64GB RAM: 61GB RAM: 15GB
Disk: 100GB Disk: 100GB Disk: 100GB
$1.032 / hour $0.798 / hour $0.504 / hour

なお、単価は本日(2017年5月21日)時点の東京リージョンでLinuxのオンデマンドインスタンスを使った場合の値段としています。参考
また、ディスクの費用(EBS)は含んでおりません。

プログラム

プログラム全文はこちらです。

# import openopt
from openopt import *

# 小さいアプリケーション、中くらいのアプリケーション、大きいアプリケーションの数を設定します。
small_num = 20
med_num = 12
large_num = 9

apps = []

# 各アプリケーションのリソース利用量をdictにし、リストに追加します。
for i in range(small_num):
    small_app = {
        'name': 'small%d' % i,
        'cpu': 0.2,
        'mem': 256,
        'disk': 1
        }
    apps.append(small_app)

for i in range(med_num):
    med_app = {
        'name': 'medium%d' % i,
        'cpu': 0.5,
        'mem': 512,
        'disk': 10
        }
    apps.append(med_app)

for i in range(large_num):
    large_app = {
        'name': 'large%d' % i,
        'cpu': 2.4,
        'mem': 2048,
        'disk': 40
        }
    apps.append(large_app)


# AWS EC2インスタンスのサイズを設定します。
# 各リソースを9掛けにしているのは、OSがリソースの10%を使うと仮定しているためです。
instance_sizes = [
    {
        'name': 'm4.x4large',
        'cost': 1.032 * 24 * 30,
        'size': {
            'cpu': 16 * 0.9,
            'mem': 64 * 1024 * 0.9, 
            'disk': 1000 * 0.9
        }
    },
    {
        'name': 'r3.2xlarge',
        'cost': 0.798 * 24 * 30,
        'size': {
            'cpu': 8 * 0.9,
            'mem': 61 * 1024 * 0.9, 
            'disk': 1000 * 0.9
        }
    },
    {
        'name': 'c4.2xlarge',
        'cost': 0.504 * 24 * 30,
        'size': {
            'cpu': 8 * 0.9,
            'mem': 15 * 1024 * 0.9, 
            'disk': 1000 * 0.9
        }
    }
]

# ビンパッキングです。
# openoptのBPPという関数を使います。
def bin_pack_instance(apps, instance_size):
    cost = instance_size['cost']    
    p = BPP(apps, instance_size['size'], goal = 'min')
    r = p.solve('glpk', iprint = 0)
    instances = len(r.xf)
    total_cost = instances * cost
    return r, instances, total_cost

# 実行します。
# 各インスタンスサイズでビンパッキングを行い、最も安くなるものを探します。
if __name__ == '__main__':
    list_cost = []
    for instance in instance_sizes:
        r, instances, total_cost = bin_pack_instance(apps, instance)
        list_cost.append({'instance': instance['name'], 'total_cost': total_cost})

        print("\r") 
        print("Bin packing for : {0}".format(instance['name']))
        print("Total number of apps is " + str(len(apps)))
        print("Total {0} instance used is {1}".format(instance['name'], instances))
        print("Total cost is {0}".format(total_cost))

        for i,s in enumerate(r.xf):
            print ("Instance {0} contains {1} apps".format(i, len(s)))
            print("\t CPU: {0}vCPU\t RAM: {1}MB\t Disk: {2}GB"
                  .format(r.values['cpu'][i], r.values['mem'][i], r.values['disk'][i]))
            print("\t Contains: {0}".format(r.xf[i]))

        print("\r")  

    print("Result: {0}".format(list_cost))

結果はこちらのとおりになります。

------------------------- OpenOpt 0.5625 -------------------------
problem: unnamed   type: MILP    goal: min
solver: glpk
  iter  objFunVal  log10(maxResidual)  
    0  0.000e+00               0.00 
    1  0.000e+00            -100.00 
istop: 1000 (optimal)
Solver:   Time Elapsed = 0.12   CPU Time Elapsed = 0.12
objFuncValue: 3 (feasible, MaxResidual = 0)

Bin packing for : m4.x4large
Total number of apps is 41
Total m4.x4large instance used is 3
Total cost is 2229.12
Instance 0 contains 18 apps
     CPU: 14.200000000000001vCPU     RAM: 13312.0MB  Disk: 228.0GB
     Contains: ('small0', 'small3', 'small4', 'small5', 'small6', 'small7', 'small8', 'small13', 'medium0', 'medium1', 'medium2', 'medium3', 'medium4', 'medium5', 'large3', 'large4', 'large6', 'large7')
Instance 1 contains 17 apps
     CPU: 14.4vCPU   RAM: 13312.0MB  Disk: 212.0GB
     Contains: ('small1', 'small2', 'small9', 'small10', 'small11', 'small12', 'small14', 'small15', 'small16', 'small17', 'small18', 'small19', 'large0', 'large1', 'large2', 'large5', 'large8')
Instance 2 contains 6 apps
     CPU: 3.0vCPU    RAM: 3072.0MB   Disk: 60.0GB
     Contains: ('medium6', 'medium7', 'medium8', 'medium9', 'medium10', 'medium11')


------------------------- OpenOpt 0.5625 -------------------------
problem: unnamed   type: MILP    goal: min
solver: glpk
  iter  objFunVal  log10(maxResidual)  
    0  0.000e+00               0.00 
    1  0.000e+00            -100.00 
istop: 1000 (optimal)
Solver:   Time Elapsed = 0.24   CPU Time Elapsed = 0.23
objFuncValue: 5 (feasible, MaxResidual = 0)

Bin packing for : r3.2xlarge
Total number of apps is 41
Total r3.2xlarge instance used is 5
Total cost is 2872.8
Instance 0 contains 3 apps
     CPU: 7.199999999999999vCPU  RAM: 6144.0MB   Disk: 120.0GB
     Contains: ('large0', 'large4', 'large7')
Instance 1 contains 11 apps
     CPU: 7.199999999999999vCPU  RAM: 6912.0MB   Disk: 107.0GB
     Contains: ('small5', 'small6', 'small7', 'small8', 'small9', 'small18', 'small19', 'medium0', 'medium1', 'large1', 'large2')
Instance 2 contains 13 apps
     CPU: 7.0vCPU    RAM: 6912.0MB   Disk: 91.0GB
     Contains: ('small0', 'small1', 'small2', 'small10', 'small11', 'small12', 'small13', 'small14', 'small15', 'small16', 'small17', 'large5', 'large6')
Instance 3 contains 8 apps
     CPU: 7.199999999999999vCPU  RAM: 6656.0MB   Disk: 122.0GB
     Contains: ('small3', 'small4', 'medium2', 'medium3', 'medium4', 'medium5', 'large3', 'large8')
Instance 4 contains 6 apps
     CPU: 3.0vCPU    RAM: 3072.0MB   Disk: 60.0GB
     Contains: ('medium6', 'medium7', 'medium8', 'medium9', 'medium10', 'medium11')


------------------------- OpenOpt 0.5625 -------------------------
problem: unnamed   type: MILP    goal: min
solver: glpk
  iter  objFunVal  log10(maxResidual)  
    0  0.000e+00               0.00 
    1  0.000e+00            -100.00 
istop: 1000 (optimal)
Solver:   Time Elapsed = 0.14   CPU Time Elapsed = 0.14
objFuncValue: 5 (feasible, MaxResidual = 0)

Bin packing for : c4.2xlarge
Total number of apps is 41
Total c4.2xlarge instance used is 5
Total cost is 1814.4
Instance 0 contains 7 apps
     CPU: 5.4vCPU    RAM: 5120.0MB   Disk: 100.0GB
     Contains: ('medium0', 'medium1', 'medium2', 'medium3', 'medium4', 'medium5', 'large6')
Instance 1 contains 15 apps
     CPU: 7.0vCPU    RAM: 7168.0MB   Disk: 108.0GB
     Contains: ('small8', 'small9', 'small10', 'small14', 'small16', 'small17', 'small18', 'small19', 'medium6', 'medium7', 'medium8', 'medium9', 'medium10', 'medium11', 'large0')
Instance 2 contains 14 apps
     CPU: 7.199999999999999vCPU  RAM: 7168.0MB   Disk: 92.0GB
     Contains: ('small0', 'small1', 'small2', 'small3', 'small4', 'small5', 'small6', 'small7', 'small11', 'small12', 'small13', 'small15', 'large3', 'large4')
Instance 3 contains 3 apps
     CPU: 7.199999999999999vCPU  RAM: 6144.0MB   Disk: 120.0GB
     Contains: ('large1', 'large2', 'large5')
Instance 4 contains 2 apps
     CPU: 4.8vCPU    RAM: 4096.0MB   Disk: 80.0GB
     Contains: ('large7', 'large8')

Result: [{'instance': 'm4.x4large', 'total_cost': 2229.12}, {'instance': 'r3.2xlarge', 'total_cost': 2872.8}, {'instance': 'c4.2xlarge', 'total_cost': 1814.4}]


長くなりますが、結果としてc4.2xlargeを4台に詰め込むのが最も効率が良く、月額$1814.4で済むようです。

感想

今回はアプリケーション配置を最適化問題として考えてみました。
もちろん同一サイズのインスタンスに全アプリケーションを詰め込むケースは少ないでしょうし、サブネット分離等々、アーキテクチャを考える上で考えなければならない点は多いです。
本当は複数インスタンスサイズを混ぜた構成(c4.2xlarge 3台、t2.micro 4台、みたいな)を算出したかったのですが、サイズの違う複数ビンでのパッキング方法がわからず、このような形になりました。
これは今後の課題にします。
もし詳しい方がおりましたら、教えて下さい。

参考

組合せ最適化を使おう
組合せ最適化 – 標準問題と実行方法
最適化におけるPython
ビンパッキング問題の解き方
Python言語によるビジネスアナリティクス 実務家のための最適化・統計解析・機械学習
https://github.com/PythonCharmers/OOSuite/blob/master/OpenOpt/openopt/examples/bpp_2.py

続きを読む

Amazon EC2でAWSが提供するWindows AMIの検索方法 (AWS Tools for Windows PowerShell)

Get-EC2ImageByNameは日本語版が検索の対象になっていない。

AMIの名前

AWS提供のWindowsAMIの名前パターン

  • OSバージョン Windows_Server-2016, Windows_Server-2012-R2_RTM, …
  • 言語 Japanese, English, …
  • Full, Core, Nano
  • Base(SQLServerなし), SQL_2016_Standard, SQL_2016_Web, …
  • AMIのリリース年月日

検索条件

  • region = 検索するリージョン
  • owner = “amazon”
  • platform = “windows”
  • name = 先頭から末尾までのワイルドカード(?*)、大文字小文字を区別する(CaseSensitive)検索

名前で検索して最新の1件を取得する

Get-EC2Image `
    -Region ap-northeast-1 `
    -Owner amazon `
    -Filter `
        @{name="platform"; values="windows"}, `
        @{name="name"; values='Windows_Server-2016-Japanese-Full-Base-*'} `
    | sort CreationDate -Descending `
    | select name, imageid, Description -First 1

続きを読む

redashでAWS Athena使おうとしたら、DataSourceに出てこなくてはまったので解決策

redashでAWS Athena使おうとしたら、はまったので解決策

使うぞって思ってたら、
Data SourceのType欄に出てこなかったので
解決策を記載しておきます:smiley:

※すべて2017/5/18現在の事象です

場面

今回は以下の場面です

  • AWSのEC2のAMIを利用
  • ソースをダウンロードしてインストール

Hostedでは、問題なく選択できました

redashのインストール

redashのインストール方法を記載しておきます

パターン1. AWS EC2でredashのAMIを利用する

  • EC2インスタンス作成時に、redashで提供されているAMIを選択する

Setting up a Redash Instance

※現時点(2017/5/18)では、1.0.1+b2833 がインストールされます

パターン2. ソースを持ってきてインストールする

  • EC2インスタンス作成時に、OSは、ubuntuを選択
  • 以下を実行

ソースゲット

cd /usr/local/src/

wget https://raw.githubusercontent.com/getredash/redash/master/setup/ubuntu/bootstrap.sh

スクリプト実行

sh bootstrap.sh

アップグレード

cd /opt/redash/current
sudo bin/upgrade

確認

ls -l /opt/redash/

※現時点(2017/5/18)では、1.0.3.b2850 にアップグレードされます

本題のAWS Athenaへの接続

現象

上記2つの方法で設定すると以下の画像のように
AWS Athenaが出てきません:cry:


redash01.png


調査

/opt/redash/redash.1.0.3.b2850/redash/query_runner/athena.py

ファイルあるしなぁと調査したり

解決策

公式のサーポートに書いてました:joy:

Support for AWS Athena

方法

/opt/redash/.env

に以下を追加

export REDASH_ADDITIONAL_QUERY_RUNNERS="redash.query_runner.athena"

再起動して、反映

/etc/init.d/supervisor reload

するとredash02.png

出てきました!:tiger::tiger::tiger:

あとは、
AWS AthenaへのKey等を設定してください~

※注意※

redashのバージョンが、0.12以下の場合はエラーになるので注意!

続きを読む

クラウドサーバーサービス(IaaS)の性能比較・ディスク編~IOPSの計測~

はじめに

 今回は以下のクラウドサーバーを対象にIOPSを計測し、ストレージの性能を比較します。IDCFクラウドについては初期のゾーンであるhenryと最新ゾーンのluxの2種類を計測し、ゾーン間の違いも計測してみます。

計測対象:

  • Amazon Web Services (AWS) (ボリュームタイプ:gp2/SSD)
  • Google Cloud Platform (GCP) (SSD)
  • IDCFクラウド(ゾーン:lux/SSD)
  • IDCFクラウド(ゾーン:henry/HDD)

1. 前提知識

 ディスクの性能がなぜ大事?IOPSとは?
 (自明な方は読み飛ばして下さい:bow:

1.1 仮想化環境とストレージ性能

  • 仮想化環境ではストレージの性能がネックになりやすい
  • HDDはシーケンシャルI/O、SSDはランダムI/Oが得意
  • 仮想化環境では主にランダムアクセスに対する性能が重要になる(複数の仮想マシンからのアクセスが発生するから)

参考:
 IT機器の進化とHDD性能とのギャップ
 ストレージのいろは|ソフトバンク コマース&サービス
 クラウドを加速させるSSD技術 - @IT

1.2 IOPSとは?

  • ストレージ性能を図る指標
  • ディスクが1秒当たりに処理できるI/Oアクセスの数
  • IOPSが高ければ高いほど,高性能なディスクと言える
  • IOPSはブロックサイズが小さいと大きな値になる傾向がある
  • IOPSは読み込みと書き込みの割合で値が大きく変わる

参考:
 サーバー選択の基礎 – Part4 IOPSを理解する:ITpro
 ストレージのいろは|ソフトバンク コマース&サービス

2. 計測方法

2.1 実施環境

  • 対象サーバ
AWS(EC2) GCP IDCF(HDD) IDCF(SSD)
ゾーン ap-northeast-1 asia-northeast1-a henry lux
マシンスペック m4.large(2vCPUメモリ8GB) n1-standard-2(2vCPUメモリ7.5GB) standard.M8 (2vCPUメモリ8GB) standard.M8 (2vCPUメモリ8GB)
OS CentOS 7 CentOS 7 CentOS 7 CentOS 7
ディスクサイズ 8GB 10GB 15GB 15GB

マシンスペックはAWSのm4.largeに合わせてみました。
ディスクサイズはデフォルトのままとします。

2.1 ツール

 ベンチマークツールとしてfioを使用します。

2.1.1 fioのインストール

  • # yum install epel-release
      まず、EPELのリポジトリをインストールします。

  • # yum repolist all epel*   
      追加したリポジトリが有効かどうか確認。   

  • # yum install fio
      fioをインストール。

2.1.2 計測パラメータの設定

 小さめのブロックサイズの方がベストエフォートに近いはずなので、今回はブロックサイズを4KBに設定し、以下のパターンで比較してみます。

  • ランダムリード
  • ランダムライト
  • ランダムリードライト

 パラメータ条件をfioのパラメータ設定ファイルとして準備します。

Rand-Read-4k.fio
[global]
ioengine=libaio
direct=1
ioscheduler=noop
invalidate=1
group_reporting
directory=/home
runtime=60

[Rand-Read-4k]
readwrite=randread
size=4G
bs=4k
iodepth=32
numjobs=1
Rand-Write-4k.fio
[global]
ioengine=libaio
direct=1
ioscheduler=noop
invalidate=1
group_reporting
directory=/home
runtime=60

[Rand-Write-4k]
readwrite=randwrite
size=4G
bs=4k
iodepth=32
numjobs=1
Rand-ReadWrite-4k.fio
[global]
ioengine=libaio
direct=1
ioscheduler=noop
invalidate=1
group_reporting
directory=/home
runtime=60

[Rand-ReadWrite-4k]
readwrite=randrw
size=4G
bs=4k
iodepth=32
numjobs=1

 fioを実行します。
fio -f Rand-Read-4k.fio -filename=/tmp/fio_test -output Rand-Read-4k.result
fio -f Rand-Write-4k.fio -filename=/tmp/fio_test -output Rand-Write-4k.result
fio -f Rand-ReadWrite-4k.fio -filename=/tmp/fio_test -output Rand-ReadWrite-4k.result

2. 計測結果

AWS GCP IDCF(henry) IDCF(lux)
Rand-Read-4k 3110 2749 2664 80282
Rand-Write-4k 3110 1814 2540 41347
Rand-ReadWrite-4k 1555 884 1269 27666

※ 2017/05/15の実測値です。

  • AWSはボリュームタイプをgp2にしたので、3000IOPSがバーストの上限です。これ以上のI/O性能が求められる場合は Provisioned IOPS [PIOPS]を選択するべき、ということですね。
  • IDCFの最新ゾーンであるluxは非常に高いI/O性能を持っていることがわかりました。
  • 同じIDCFでも、古いゾーンであるhenryはluxよりもだいぶディスク性能が劣ることがわかりました。でも、ディスク性能に限って言えばGCPと大差ないようです。

続きを読む

EC2インスタンス起動時に自動でDNS設定を行う

EC2インスタンスを起動する時に自動でDNS設定を行い、同じ接続先でアクセスできるようにします。

背景

EC2インスタンスは起動する度にPublic IPアドレスが変わるため、外からアクセスする時にいちいち接続先を更新しないといけないのが面倒です。

Elastic IPを使うことでインスタンスのPublic IPアドレスを固定することはできます。
が、インスタンス停止中はElastic IPに課金が発生するのであまり使いたくない…

そこで、インスタンス起動時にDNSを更新するようにして、Elastic IPを使わずとも接続先が同じになる仕組みを作ってみました。

目的

EC2インスタンス起動時にDNSを設定して、停止前と同じ接続先でアクセスできるようにします。

使うサービス

  • EC2
  • Route53
  • IAM(ロールとポリシー)

手順

コンソール上での作業

1. Route53でHosted Zoneを作成

Route53でHosted Zoneを作成します。
ドメイン名とHostedZoneIdを控えておきます。

2. IAMロールを作成し、EC2インスタンスにアタッチする

ロールがすでにEC2インスタンスにアタッチされていれば必要なし。
ロールの中身は空で問題ないです。

(ロールをEC2にアタッチする参考リンク)
[アップデート] EC2コンソールで既存のEC2インスタンスに対してIAM Roleをアタッチ、変更ができるようになりました

3. IAMポリシーを作成

EC2インスタンスがRoute53でDNSを更新できるようにIAMポリシー(カスタマー管理ポリシー)を作成します。
DNSの設定に使用するドメインのレコードのみ更新できるよう許可します。
XXXXXXXXXXXXXの部分は1.で作成したホストゾーンのHostedZoneIdに置き換えてください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "route53:ChangeResourceRecordSets"
            ],
            "Resource": "arn:aws:route53:::hostedzone/XXXXXXXXXXXXX"
        },
        {
            "Effect": "Allow",
            "Action": [
                "route53:ListResourceRecordSets",
                "route53:GetChange"
            ],
            "Resource": "*"
        }
    ]
}

4. IAMロールにポリシーを追加

EC2インスタンスにアタッチしたIAMロールにポリシーを追加します。

EC2インスタンス上での作業

1. AWSCLIをインストール

http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html
※OSがAmazonLinuxの場合は必要なし。

Redhat系OSの場合

curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
sudo python get-pip.py
sudo pip install awscli

Ubuntuの場合

sudo apt-get -y update
sudo apt-get -y upgrade
sudo apt-get -y install python-dev
curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
sudo python get-pip.py
sudo pip install awscli

2. スクリプト作成とcron設定

sudo mkdir /var/scripts/
sudo vi /var/scripts/updatedns.sh
sudo chmod 700 /var/scripts/updatedns.sh
sudo vi /etc/rc.local
updatedns.sh
#!/bin/sh

#メタデータから自身のPublicIP取得
publicIp=`curl http://169.254.169.254/latest/meta-data/public-ipv4` 
#DNS設定(Route53で設定したドメイン名と、サブドメインを入れる)
domain=test.example.com

#JSON作成
cat <<EOT > /tmp/dns_recordset.json 
{ "Changes": [{"Action":"UPSERT","ResourceRecordSet":{"Name": "$domain","Type": "A","TTL":600,"ResourceRecords":[{"Value":"$publicIp"}]}}]}
EOT
#DNS更新
aws route53 change-resource-record-sets --hosted-zone-id XXXXXXXXXXXXX --change-batch file:///tmp/dns_recordset.json
#更新に使用したJSONを削除
rm /tmp/dns_recordset.json 

ドメイン名やHostedZoneIdの部分はRoute53で作成したものに置き換えてください。

/etc/rc.local
#以下追記
/var/scripts/updatedns.sh

※RedHat系OSの場合は/etc/rc.d/rc.localに実行権限を与える必要があります。

Redhat系のみ
sudo chmod u+x /etc/rc.d/rc.local

ここまで作業すると、rebootで再起動した際やインスタンスを停止→起動した際にDNSが自動で更新されるようになります。

ホストゾーンとElastic IPの月額料金

Route 53のホストゾーンと、EC2インスタンスが起動していない時にElatic IPにかかる料金を調べてみました。

(参考リンク)
https://aws.amazon.com/jp/route53/pricing/
https://aws.amazon.com/jp/ec2/pricing/on-demand/#Elastic_IP_Addresses

ホストゾーン ElasticIP(1日中停止) ElasticIP(1日あたり16時間稼働)
0.5 USD 0.005*24時間*30日=3.6 USD 0.005*8時間*30日=1.2 USD

※ElasticIPはap-northeast-1a(東京)で取得した場合を仮定

ホストゾーンは一つ作ってしまえば、その中にいくらレコードを追加しても費用は変わりません。
ドメインの料金は別途必要ですが、使っていない時があるElasticIPがあれば費用の削減にもなりそうですね。

まとめ

EC2インスタンスを停止→起動した時にDNSを更新して接続先を変えずともアクセスできるようにしました。

続きを読む