読者です 読者をやめる 読者になる 読者になる

HDE BLOG

コードもサーバも、雲の上

第21回 Monthly Technical Session (MTS) 開催!

勉強会 MTS

4/22に毎月行っている Monthly Technical Session (MTS) が開催されました。MTSは、主に技術的な興味関心、また現在行っている取り組みから得られた知見を共有するための取り組みで、今回で第21回目です。

今回は7名のメンバーが発表してくれました。グローバルメンバーが増えてきたこともあって、MTSは司会進行から質疑応答も含めて全編通して英語で行っています。

今回の司会進行はイスカンダルさんでした。

f:id:doi-t:20160422172056j:plain

トップバッターは大久保さん、MkDocsによるドキュメント生成について。ローカルに立てたサーバを使ってリアルタイムにドキュメントが更新される様子をデモで紹介していただきました。

f:id:doi-t:20160422172451j:plain

2人目はバグースさん、AWS lambda functionをVPC内に作った経験を発表していただきました。VPC内のlambda functionからVPC外のAWSリソースにアクセスするにはNAT GatewayやVPC endpointを用意する等、得られた知見を共有してくれました。

f:id:doi-t:20160422174332j:plain

3人目は小河さん、現在開発中のサービスと社内の開発体制について発表してもらいました。各チームメンバーのプロジェクト内における役割、Goを全面的に採用したプロジェクトではコードベースにどれほどインパクトがあるのか、等を社内向けに紹介していただきました。

f:id:doi-t:20160422175453j:plain

休憩を挟んで、4人目は小玉さん、マイクロソフトのActive Directory & Security Conference 2016に参加きた報告をしていただきました。マイクロソフトがAzure ADをどういった形でIDaaSとして提供しようとしているのか、実際にAzureAD認証を行うデモと共に紹介してくれました。

f:id:doi-t:20160422181357j:plain

5人目は4月1日に入社したばかりのジェフリーさん、LXCとは何かについてデモを交えつつ紹介していただきました。発表の中で、LXCのコンセプト、LXDとの関係、またdockerとの違いについて持っている知見を共有してくれました。

f:id:doi-t:20160422182446j:plain

6人目はヘンリーさん、インターンシップ中に開発したツールの紹介をしてくれました。3週間足らずでアイデアを形にして、デモを披露してくれました。

f:id:doi-t:20160422184615j:plain

7人目はグローバルビジネスインターンシップ中のナスタシアさん、出身のウクライナについて、歴史、食べ物、文化などたくさんの写真と共に紹介してくれました。

f:id:doi-t:20160422185502j:plain

この日は、ヘンリーさんの8週間に渡るインターンシップの最終日だったので、MTS終了後に修了式を執り行いました。ちょうど桜のシーズンだったこともあって、インターンシップだけでなく一緒に花見をしたり、夜桜を見に行ったりと、がっつり日本を楽しんでいってくれたように思います。

f:id:doi-t:20160422191600j:plain

当日は弊社CTOが着物で台湾に出張中だったため、ビデオレターにてヘンリーさんへのメッセージを届けてくれました (ビデオのオチで会場の爆笑を掻っ攫っていきました)。

f:id:doi-t:20160422191412j:plain

終わった後は、いつも通りみんなで乾杯!

f:id:doi-t:20160422193339j:plain

第20回 Monthly Technical Sessionが開催されました

勉強会 MTS

3/18に第20回 Monthly Technical Session (MTS) が開催されました。MTSは月一回執り行われる、主に社内向けに現在どのような事を技術者が行っているのかという情報やその中で得られた知見を共有するための取り組みです。

司会のシー・ハンさんが開催をアナウンスしてくれました

f:id:lestrrat:20160318173001j:plain

今回のお題は二つです。最初はイスカンダルさんによる、現在旧アーキテクチャから新アーキテクチャにデータ移行中のサービスの概要についてです。データの整合性の取り方や考えられる問題点等についての説明をしていただきました。

f:id:lestrrat:20160318174551j:plain

次は牧によるJSON Schemaとその関連技術を使ってコードを自動生成するための道のりの話です。サーバーのスケルトン、バリデーション、クライアントコードなどが全てひとつのスキーマから生成されるまでの仮定やなぜ他のツールではなくJSON Schemaを使うのか等の話をしました。

f:id:lestrrat:20160318180115j:plain

トークの後は軽食とビールの時間です!

f:id:lestrrat:20160318190126j:plain

自作Let's EncryptクライアントをGoで書いた話

開発部たなべです。

Let's Encrypt (以下LE)が今年の1月についにDNSベースのドメイン認可をプロダクション環境で有効にしました。

これにより、証明書発行が完全自動化できるのを記念(?)して先月の社内勉強会で少し話しました。つまりは昨年のアドベントカレンダーの続きです。 スライドでも触れましたが、勉強会の当日(1/22)にAWSからACMが発表されるというちょっとしたハプニングがありました。

speakerdeck.com

AAA Updates

AAAとは私が開発しているACMEプロトコルのクライアント実装です。Goで実装しています。

github.com

主な特徴はAWS内で完結させていることです。つまり、

  • すべてのコードはLambda Functionとして実行
  • すべてのデータはサーバサイド暗号化を適用したS3へ保存

することでステートレスでサーバレスを実現しています。アドベントカレンダー以後のアップデートとしては、

  1. 証明書自動更新に対応しました。

    Goで実装したcliアプリをLambda向けにzipし、CloudWatch Eventsを使い、証明書の自動更新処理を行ないます。 Go製のcliをNodeでラップし、Lambda Functionとするのが私の中で王道になりつつあります。OS Xで開発・実行できるうえに、一瞬でLinux向けにビルドできるのでまさにLambda Functionにぴったりです。 早くLambdaのGo対応きてほしいですね。

  2. Slackインテグレーションに対応しました。

    ドメインの認可と証明書の発行がSlackからできます。こちらはAPI Gateway経由でLambda Functionを実行しているだけなので、他とのインテグレーションも難しくないと思います。

  3. ドメイン認可プロセスのDNSチャレンジに対応しました。

    こちらが目玉機能です。Route53環境があれば対象のサーバなしで証明書が発行できます。

今後はApexを利用してLambda Functionを管理できるようにする予定です(ただし、Apex自体ではCloudWatch Eventsには対応せず、Terraformに任せる予定のようです)

Let's EncryptとAmazon Certificate Manager (ACM)

スライドの最後でも触れましたが、改めてLEとACMについて触れます。

ACMはまだ出たばかりでus-eastのみです。現時点ではLEのほうが使い勝手がよさそうです。 リージョンの問題がなくなった場合、ELB連携は魅力的です。AWS内で完結できるのはとてもありがたいです。 また、ACMはワイルドカード証明書にも対応しているので一枚あれば事足りるのも魅力的です。

ACMEプロトコル側でもワイルドカードサポートの議論が始まっています。

github.com

一方で、ACMの証明書発行プロセスではメールでドメインを認可する必要があり、ここが自動化の障害となっています。 でも、証明書の期限は13ヶ月と長いのが幸い、というところでしょうか。

今後ACMEプロトコルの利用が進み、いい感じになったところでACMがACMEプロトコルに対応してくれればすべて丸く収まる…というのが私の妄想です。

ではまた!

Building AWS Lambda function in Rust

AWS (Amazon Web Services) Rust AWS Lambda Python

This post is a summary of my presentation on 18th Monthly Technical Session.

As I worked more on AWS Lambda for some feature of our service, I looked into developing AWS Lambda functions with languages not supported by Amazon. Recently, I'm working on some private project in Rust so it is worth a try to see whether it is possible to run Rust code on AWS Lambda.

How to run Rust code on AWS Lambda

According to the document of AWS Lambda, the function is run on Amazon Linux with some language runtime and library. It is also possible to spawn new process to run some executable. So there is really little limitation on how the function executes aside from the limitation on CPU, memory and network usage.

There are 2 possible ways to run code in languages not supported:

  • Spawn a new process to run some executable.

    With this way, some standalone executable that is runnable on Amazon Linux is built. The AWS Lambda function creates a new process to run it.

  • Build the code into dynamic load library and load the library with language supported and call the function. (Python or Javascript)

Code written in Rust can be easily compiled into dynamically linked (shared object) library which only depends on GNU libc on a Linux distribution. Also, Python supports loading this kind of library naturally. So the second option is quite adoptable.

Sample project

Here is the code of a sample project to build an AWS Lambda function in Rust with Python code as a loader.

https://github.com/yxd-hde/lambda-rust-demo

The Python loader

To implement handler function in Rust, some code in Python is required to load the library built from Rust and call the function in the library.

Python's cdll package is used to load the library built from Rust (which is named with libhandler.so and uses standard C calling convention) and then the code call the handler function with event and context serialized into json strings.

The code is quite simple and uses simplejson library to do json serialization.

from ctypes import cdll

import simplejson as json

lib = cdll.LoadLibrary('./libhandler.so')


def handler(event, context):
    ret = lib.handle(json.dumps(event),
                     json.dumps(context, default=encode_context))
    return ret


def encode_context(context):
    return {
        "function_name": context.function_name,
        "function_version": context.function_version,
        "invoked_function_arn": context.invoked_function_arn,
        "memory_limit_in_mb": context.memory_limit_in_mb,
        "aws_request_id": context.aws_request_id,
        "log_group_name": context.log_group_name,
        "log_stream_name": context.log_stream_name

        # add others if it is required.
    }

The handler in Rust

In Rust code, the event and context parameters are in C string and need to be converted into Rust strings for further processing. Some unsafe conversion is required to be done before handling them. After that, all things can be done in Rust safely.

Here, Rust's libc library is used for the type of C char pointer, which represents a string in C.

extern crate libc;

use std::ffi::CStr;
use libc::c_char;

#[no_mangle]
pub extern "C" fn handle(c_event: *const c_char,
                         c_context: *const c_char) -> i32 {
    let event = unsafe { CStr::from_ptr(c_event).to_string_lossy()
                         .into_owned() };
    let context = unsafe { CStr::from_ptr(c_context).to_string_lossy()
                           .into_owned() };

    real_handle(event, context)
}

fn real_handle(event: String, context: String) -> i32 {
    println!("Event: {}", event);
    println!("Context: {}", context);

    // Do the real handling

    return 0;
}

Wind them together

To wind them together, there are some extra work to do.

Build the Rust code into an .so file

In Cargo.toml, it is required to tell Rust's build tool cargo that the build target is a dynamic library.

...

[lib]
name = "handler"
crate-type = ["dylib"]

...

Add all the dependencies

The dependencies in Rust are managed by cargo, while requirements.txt is used for Python though there is only simplejson required.

Make the zip package to deploy

Python code, simplejson library and libhandler.so file built from Rust needs to be packaged together in one zip file to deploy.

The libhandler.so file should be binary compatible with Amazon Linux. It is recommended to build it on a distribution that is binary compatible with Amazon Linux.

AWS Lambda settings

An AWS Lambda function with Python environment is required and the handler needs to be set to Python's handler function.

Others

logs

Rust function can just output to stdout for logging as this is supported by AWS Lambda.

error handling

For the code above, the return value of Rust's handler can be used to decide whether the execution succeeded.

Finally

Rust code is safe and supposed to be as performant as C and C++. With this way of implementation, it is possible to use Rust as the language to develop AWS Lambda function easily. It is worth a try if there are requirements to develop performant AWS Lambda function, especially when the function is computation focused.

Developing with Vagrant and Docker

Hi, this is Shi Han from HDE Inc. Before joining HDE Inc. as a software engineer, I was involved in the field of computational physics mainly focusing on computational fluid dynamics and granular materials simulations. The simulations are commonly developed in a monolithic style where the whole simulation is treated/built as a single unit. As for setting up the development environment, usually it only requires the developer to deal the the makefile. As a newcomer in the field of software engineering, I found that things are not quite the same over here. The "recent" trend is that the application can be divided into several small services (microservice architecture) and communicating via HTTP resource API (API-centric architecture). This practice is often applied on applications that are being deployed on the cloud as it allows each services to be deployed and scaled independently.

続きを読む

Tool to help developing AWS Lambda function in Python on your local machine.

AWS (Amazon Web Services) Python JavaScript

We are trying to migrate some part of our service from daemon on EC2 server to serverless function on Lambda. By doing this, we will be able to save some pennies on AWS service and save some time from server maintainence.

At first, we did some development in Javascript on Lambda. And the development went quite well with the awesome tool lambda-local developed by Ahmad Shiina san

ashiina.github.io

With this tool, we are able to develop and debug Javascript code on developer's machine without having to upload it to the cloud. With a shortened develop-deploy-test-fix cycle, we managed to develop features really fast.

We were just about to go all with Javascript when AWS enabled developing Lambda functions in Python2.7 at re:Invent 2015.

Using Python in an AWS Lambda Function | AWS Compute Blog

Since part of our stack is based on Python2 and most of our developers are more familiar with Python than Javascript. We decided to give it a try.

However, one problem is that there is no tool like lambda-local for Python right now. So we built one by ourselves and opensourced it on github.

github.com

We have also released it on PyPI

pypi.python.org

So you may try it our by installing it into a Python2.7 environment with just one command:

$ pip install python-lambda-local

Currently, it is quite feature complete except lacking enough support for the Context API. We will continue improving it.

The usage of the python-lambda-local command is quite similar with lambda-local. So there should be no hassle if you are familiar with lambda-local.

Ideas and pull requests are welcomed.

Happy hacking!

AWS re:Invent 2015行ってきました & 新サービスAmazon Snowballについて

■AWS re:Invent 2015行ってきました

f:id:miyamotokazuaki:20151022185547j:plain

 Amazon Web Serviceの巨大イベント、AWS re:Invent 2015に参加してきました。ラスベガスです。昼も夜も渋谷より騒がしい街があったことは衝撃的でした。うちの会社(HDE)は昔から渋谷にあり、私自身もかつて渋谷に住んでみたこともあって、"昼も夜も渋谷ほど騒がしい街は世界中どこにもないだろう"という確信を持っていて(あまりに落ち着かないので、さすがに自宅は半年で渋谷区じゃないところに転出したのですが)、まぁしかし、その数倍騒がしかったですね、ラスベガスは。Crazyです。

 というわけで、今日はラスベガスの若干の写真と、re:Inventの全体の雰囲気、今回Amazonから発表されたサービスの一つを紹介しつつ、最後にちょっとした宣伝(!)をさせていただく、という構成にしています。是非最後までお読みください。

 さて、まずはラスベガスらしい写真をいくつか上げておきます。

f:id:miyamotokazuaki:20151022185736j:plain
↑とりあえず肉は食っておこう、みたいな感じ

f:id:miyamotokazuaki:20151022185754j:plain
↑カジノに手を出すのはやめました

f:id:miyamotokazuaki:20151023103253j:plain
↑世界最大の観覧車High Rollerから見下ろすホテル群

f:id:miyamotokazuaki:20151022185829j:plain
↑ホテルでかすぎて、入り口入ってから迷う、迷う。ツアーメンバーがFacebookグループに「会場までの近道」を写真入りでアップしたらそれにたくさんいいね!がつくぐらい。

■会場の様子

 上の写真にある、一番繁華街のストリップ通りに面したベネチアンっていうところが会場でした。

 AWS re:Inventでは毎年、Amazon Web Serviceの様々な新機能発表がされます。今年もたくさん発表がありました。簡単にデータ分析ができる、Amazon QuickSight, 大量のデータ移行につかえる、Amazon Snowball, そしてKinesis Firehose, AWS Config Rules, Amazon Inspector, AWS Database Migration Service, AWS Schema Conversion Tool, Kinesis analytics, 新しいEC2インスタンスファミリーX1や、コンテナをより使いやすくする新サービスAmazon EC2 Container Registry, Python for Lambda, AWS Mobile Hubおよび、とどめAWS IoT。小さいものを含めるともっとたくさんあります。

 個々のサービスの内容は、数百人に登る日本からの参加者の皆さんがblog等で紹介されているので、このあたりから辿ってもらえればと思います。

aws.typepad.com

 全般的にはAmazonの「ビジネス面」の勢いを感じさせるものが多かったです。私の記憶では、数年前には、「システムのテストフェーズとかで使うと便利だからどんどん使ってくださいね」というトーンでした。今年は、「製造業や金融のミッションクリティカルかつ巨大なデータを扱う実環境としていけますよ!」と。データベース、データ分析のツール、IoT関連、いずれも出てくる事例は大企業、時代が変わっていっていることが見てとれます。

f:id:miyamotokazuaki:20151022185945j:plain ←BMWの事例

f:id:miyamotokazuaki:20151022185953j:plain ←工場でのIoT利用モデル

■個人的に一番印象的だったのはAmazon Snowballというサービス

 個々の新サービスの紹介をしはじめるとキリがないので、個人的に象徴的だと思ったものを一つ上げたいと思います。それはAmazon Snowball。これはなんとアプライアンスです。

f:id:miyamotokazuaki:20151022190008j:plain

 メジャーなクラウドベンダーがアプライアンス的なものを出すのは初めてじゃないでしょうか。

 これ、何の目的に使われるかというと、オンプレミスのデータをAmazonのS3に引っ越すためのものです。Amazon Snowballをオンプレミスのサーバに繋いでデータを吸い出して、それをAmazonに送るとAWSのS3にセキュアにアップロードしてくれるというもの。1台で50TBのデータを扱えます。

 我々も、エンドユーザ様から過去のメールを弊社サービス(HDE One)に入れてくれ、みたいな要望をいただいたり、そのアップロードの際に、転送速度をうまくコントロールしないと翌月の請求額が跳ね上がったり、そういう経験をしているので、こういうの必要だよね、と改めて感じました。データを引っ越す時に気になること、たとえば物理的破損だったり、セキュリティだったり、予想外の請求額だったり、そういったエンジニアや担当者が留意すべきところを全部考えなくていいよ、という隙間ソリューションです。例え、「フルスタックエンジニア」であっても、HDDが破損しない梱包の仕方とかっていうノウハウは持ってないですからね。  そして、そういう足回りのベタなところを(周りのサードパーティーがやるのではなくて)Amazon自身がやるんだということに少し驚きましたし、ここまで徹底してやるから伸びているのか、とある種の納得を感じました。

■実物見てみると

 このSnowball、そばでみるとごっついです。アメリカンサイズ。床に落とすと床の方が壊れるんじゃないかと(Keynoteでは床に落としてみせてましたが)。最近の超小型HDDとか見ていると、ちょっとびっくりするぐらいゴツい。

 ちなみに、何でsnowballっていう名前かっていうのを会場で聞いてみたところ、雪の球を投げつける=物理的なものを移動する=アプライアンスを搬送する、というようなことでした。加えて、帰国してからネットで調べると、「Cerro Torre(邦題:クライマー パタゴニアの彼方へ)」っていう2013年の映画の副題が a snowball's chance in hellっていって、ここから取ったのかも、というニュアンスの記事を見つけたので、これが(も)ビンゴかもしれません。

f:id:miyamotokazuaki:20151022190030j:plain

f:id:miyamotokazuaki:20151022190037j:plain

■いずれは消えるサービスだが、時代を象徴しているサービス

 このサービス、世の中のデータがことごとくクラウドに移行されちゃったら消えるサービス(?)ではないかと思います。オンプレミスからクラウドへの移行期ならではの象徴的なサービスかと。

 とはいえ、クラウドへのインポートだけではなく、export/importの両方をうたっています。説明ではImportの話が印象的だったので、てっきり、「Amazonにロックオンするone wayなサービスキター」と思ってたんですが、後からサイトを見ると「緊急時の復旧等の目的でexport使えるよ」って書いてありました。

 値段もお手頃。

 デバイス処理 $80.00〜$99.00(リージョンによって異なる) : 処理されるストレージデバイスあたり  データ読み込み時間 $2.49〜$2.99(リージョンによって異なる) : データ読み込み時間あたり。(2015/10/23時点)

 ただし、東京リージョンでは現時点(2015/10/23時点)ではまだやってません。アクセスすると、

Import/Export Snowball is not available in アジアパシフィック (東京). Please select another region.

 って表示が出ちゃいます。

 あと、「SnowballをAmazonに送る時にGPS付けてたらデータセンターの場所がバレちゃったりしないのかな?」というのは、re:Inventツアー参加メンバーの中で少し話題になっていましたが、さすがに会場では訊けずじまいでした。

■ペタバイトは今年のre:Inventのキーワードの一つ

 さて、このSnowballの説明には、”to transfer petabytes of data into or out of AWS(ペタバイトのデータを出し入れできるよ)"って書いてあります。この「ペタバイト」っていうのは、今年のre:Inventの隠れたキーワードのような気がしました。  キーノートの前日に開催されたパートナーサミットでもAndyがもうデータのサイズがペタバイトを超えるのは普通だ、って発言してました。私が聞きに言ったセッションの中にも、”Security and Compliance at Petabyte Scale”っていうゲノム解析データの事例が出ていました。  Amazon Japan様によれば、日本ではまだペタバイトのデータをAWSに預けているところって数社のようですが、これから増えていくでしょうね。

f:id:miyamotokazuaki:20151023103529j:plain ←パートナーサミットの様子

■宣伝!ペタバイト祭りやるよ

 さて、ここから宣伝です(笑)。

 HDEでもついに、AWSに預けているデータがペタバイトを超えました。そこで、これを記念するとともにAWS技術者に感謝するために、「ペタバイト祭り」なるものを催すことにしました。

 YAPC主催の牧大輔さん(@lestrrat)、AWS界隈で有名なMichael H. Oshitaさん(@ijin)を迎えて、「ペタバイト級データを支えるクラウドサービスの表と裏」〜ペタバイトまでの道のりと障害、そして、開発と運用のチームをどのように融合するかについて〜というテーマでパネルディスカッションやります。  モデレータは、なんと今話題のソラコムの玉川 憲さん!豪華な布陣ですが、無料です。場所はみなさんの大好きな渋谷です。面白そうだと思ったエンジニアの方は是非おいでください。

 f:id:miyamotokazuaki:20151023102707j:plain  f:id:miyamotokazuaki:20151023102502j:plain

 参加希望はFacebookイベントページ「ペタバイト祭り」

 https://www.facebook.com/events/1496829413966727/

 にて、「参加希望」ボタンをポチッと押してください。

 どうぞよろしくお願いいたします。

 以上です。