DRYな備忘録

Don't Repeat Yourself.

さようなら、CWL

このエントリは、 Common Workflow Language (CWL) Advent Calendar 2018 - Qiita の25日目です。

tl;dr

CWLって何よ

2017年4月にベルリンから逃げ帰って、某大学研究所に研究員として就職しました。当初は、自分が持ってるバイオインフォの個人事業で独立しようと思っており、半分はその営業・コネクション作りのつもりで行ったのですが、なんやかんやでそこで働くことになってました。今にして思えば、よい判断だったと思います。理由は最後のほうで書く。

ゲノム解析のプラットフォーム構築、あるいはその技術検証」というようなミッションで、ゲノム解析の実情・課題国内のスパコンの利用実態、日本および海外のクラウドサービスの利用状況、Docker / Singularity を用いた仮想化・再現性の担保などの研究?実装をしました。

そんな中、国際学会でもにわかに注目を集めていたのが「Common Workflow Language」略して「CWL」です。

CWLって何よ、っていうのは、この辺見たらよろしい。

世界中のゲノム解析作業者(←そのすべてが「バイオインフォマティシャン」とは限らないところがミソ)がそれぞれのスパコンのスペックで、秘伝のパッケージがインストールされた環境で、秘伝のシェルスクリプトを丹念につくりあげて論文を発表するも、当然それでは再現性が無かったりしてどーなのよ、となるのを「じゃあ統一記法があったらいいんでしょ」って発想で「Common」な「Workflow」の「Language」を 作りたかったらしい 作ったのが「Common Workflow Language」です。

正直しんどい

「お、じゃあいっちょCWLの思想信条を理解するのも兼ねて、エンジンをつくってみよじゃないの」と思ってGoによるシンプルなエンジンの実装を始めたんですけど、これがまた、しんどい。色々な概念をモリモリにしてしまって、仕様が収集つかなくなってる感じがあります。

細かいことは、去年 Webプログラマから見た「CWL」の功績と罪過 - DRYな備忘録 でガッツリ書いたのでここでは詳細は割愛しますが。

すっげー乱暴に言ったら、哲学が先行しており、実践がついてきてなくね?という感じです。

帰納的アプローチ

CWL自身も「いや、ウチは別に絶対的な統一記法を発明しようとしているわけちゃうよ?」「他にもいろいろあるからええやつ選んだらええんちゃう?」という態度です。

であるのであれば、無理にCWLに追従するのではなく、独自のワークフロー記法を作るぐらいの勢いでやるのがいいんじゃないかと思うんですが。

そのとき、CWLのように「かくあるべき」から降りてきて、途中途中に要求を吸収していくようなやり方ではなく、それぞれの参加者がそれぞれの業務フローに特化したソフトウェアをまずつくり、共通概念を抽出していくような、いわば帰納的なアプローチを取るべきだ(あるいはCWLはそういうアプローチを取るべきだったのではないか。まあそれをやるにはワールドワイドすぎるとは思うけど)と思うわけです僕は。

そんなわけで、ってほど必然性は無いんですが、僕は仕事の一環で「クラウドサービス上で任意のワークフローを動かし結果だけを得るエンジン」を作っておりました。「hotsub」っていうんですけど。

名前が某ポルノサイトに酷似してるってツッコミを受けました。ポルノだけに。

12月は無職でした

もちろん、業務フローに特化したエンジンを作ると、そこそこ長所短所・得手不得手があり、なんとなく職場ではこの "hotsub" 使われずじまいだったので、いちおう目標であった論文だけ(インターネットジャーナルですけど)投稿して、11月末に退職、ターンエンドと相成りました。

転職活動のほうは、各方面に迷惑をかけつつも、1月からちゃんと就職できることになりました。ありがとうございました。

となると12月無職になるわけですが、友人各位はご存知のように(?)当方は貯金など一切無く、12月どうやって行きていけばいいのかワカラン、仕方ないので持ち前のコネクションとコミュ力ゲノム解析の単発受託などをやり糊口を凌いでおりました。

そう、まさにこの "hotsub" を使ってね!

このままでも「hotsub」を使って受託をこなすのはドチャクソ便利なんですが、やはりソフトウェアというのは、実際に運用してみて始めて洗練されていくもので、いろいろな課題や要望が見えてきました。

そのうちの一つが「hotsubというエンジンに依存しないジョブインターフェースの定義」であります。

この延長に「ワークフロー記述方法」が透けて見えており、かなり手応えを感じます。(時すでに退職おそし感)

今後の展望

すでにhotsub*1がCWLの実行を部分的にサポートしているのですが、今後はさらにhotsubが完全に「CWLのクラウド上実行のエンジン」となっていく展望は具体的に見えているのですが、いかんせん俺はもうバイオインフォ関係ない人になっちゃう。

加えて、CWLのコミュニティ活動の一環として上記 yacle*2の実装も、時間さえあれば進めていくつもりですが、もちろん給料など出ないのでありますから、牛の歩みになってしまうと思われます。

興味関心としても、上記のように「CWLは絶対のワークフロー記述方法ではない」という立場ですので、今後は僕は「CWLの動向をかなり遠くから見守りつつ、興味範囲でエンジンの実装と、独自ワークフロー記法の発明を進める」という感じになっていくと思われます。

まとめ

ドイツから帰ったとき、いきなり個人事業に集中していたら、たぶんこんなに業界のことを知れなかっただろうし、ネットワークもつくれなかったと思う。特に、CWL界隈・ワークフロー界隈・ワークフローミートアップのお歴々には、ソフトウェアへの貴重なご助言・フィードバックをいただき、彼ら無しでは僕はきっとバイオインフォで一切成果を出せなかったとすら思います。マジで。

なんかまともな謝辞になった。

まぁ、まとまらないんですけど、まとめると、「さようなら、CWL」となります。

WETな DRYな備忘録として

TypeScriptとExpoで始めるReactNativeアプリ開発

背景

Expo SDK v31 から、標準でTypeScriptをサポートしているらしく、ホンマかいな、というエントリです。

ゴール

  • Mac上のシミュレータで、アプリが動く
  • ソースコードがTypeScriptで書かれている

うるせえ動くもん見せろ

はい

github.com

以下、ログなので読まなくていいです。

簡単なアプリの作成

% expo --version
2.4.0
% expo init
? Choose a project name: MyTypeScriptRNApp
? Choose a template: blank
[17:33:56] Extracting project files...
[17:34:02] Customizing project...

Your project is ready at /Users/otiai10/proj/react-native/MyTypeScriptRNApp
To get started, you can type:

  cd MyTypeScriptRNApp
  expo start
% cd MyTypeScriptRNApp
% expo start

# 中略
  To run the app with live reloading, choose one of:
  • Sign in as @otiai10 in Expo Client on Android or iOS. Your projects will automatically appear in the "Projects" tab.
  • Scan the QR code above with the Expo app (Android) or the Camera app (iOS).
  • Press a for Android emulator, or i for iOS simulator.
  • Press e to send a link to your phone with email/SMS.

# とのことなので、 i と打つ

f:id:otiai10:20181120173814p:plain:w300

くっそ簡単やんけ。

以下、遊び心。

--- a/App.js
+++ b/App.js
@@ -5,7 +5,7 @@ export default class App extends React.Component {
   render() {
     return (
       <View style={styles.container}>
-        <Text>Open up App.js to start working on your app!</Text>
+        <Text style={{fontSize: 120, fontFamily: "Courier"}}>Foo Bar Bla Bla</Text>
       </View>
     );
   }

こんなすると、

f:id:otiai10:20181120174710p:plain:w300

こんななる。

TypeScriptにしていく

github.com

公式にサポートしているらしいので、いっちょ適当にやってみる。

% npm install --save-dev typescript

# tsconfig.jsonをつくる
% ./node_modules/.bin/tsc --init
# 拡張子変えるだけ
% mv App.js App.tsx
% expo start

f:id:otiai10:20181120180434p:plain:w300

めっちゃいけてるやんけ。

開発環境ととのえる

エディタに、 @types がもろもろ無いというお叱りを受けている。

f:id:otiai10:20181120180643p:plain

このままではなんのためのTypeScriptやねん、という感じなので。

% npm install --save-dev \
  @types/react \
  @types/react-native \
  @types/expo

f:id:otiai10:20181120180939p:plain

jsxね。

--- a/tsconfig.json
+++ b/tsconfig.json
@@ -6,7 +6,7 @@
     // "lib": [],                             /* Specify library files to be included in the compilation. */
     // "allowJs": true,                       /* Allow javascript files to be compiled. */
     // "checkJs": true,                       /* Report errors in .js files. */
-    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
+    "jsx": "react-native",                    /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
     // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */
     // "sourceMap": true,                     /* Generates corresponding '.map' file. */

f:id:otiai10:20181120181551p:plain

TypeScriptっぽいことをしてみる。(返り値の型を定義しただけ)

--- a/App.tsx
+++ b/App.tsx
@@ -1,14 +1,26 @@
 import React from 'react';
-import { StyleSheet, Text, View } from 'react-native';
+import {
+  StyleSheet, Text, View,
+  TouchableHighlight,
+} from 'react-native';

 export default class App extends React.Component {
   render() {
     return (
       <View style={styles.container}>
         <Text style={{fontSize: 120, fontFamily: "Courier"}}>Foo Bar Bla Bla</Text>
+        <TouchableHighlight onPress={() => this._showTime()}>
+          <Text>What time is it now?</Text>
+        </TouchableHighlight>
       </View>
     );
   }
+  _showTime() {
+    alert(this._getText());
+  }
+  _getText(): string {
+    return (new Date()).toLocaleString();
+  }
 }

 const styles = StyleSheet.create({

f:id:otiai10:20181120182142p:plain

いいですね。

DRYな備忘録として

速習 React 速習シリーズ

速習 React 速習シリーズ

React Native+Expoではじめるスマホアプリ開発 ~JavaScriptによるアプリ構築の実際~

React Native+Expoではじめるスマホアプリ開発 ~JavaScriptによるアプリ構築の実際~

Learning React Native: Building Native Mobile Apps with JavaScript (English Edition)

Learning React Native: Building Native Mobile Apps with JavaScript (English Edition)

Mac上で「歌声りっぷ」を使う【Boot Camp】【Windows10】

背景

  • ある曲のボーカルを抽出したものが欲しい(公式のオフボーカルは手元にある)
    • Ableton Live でオフボーカルトラックの逆位相をオリジナルトラックにぶつける方法でボーカルを抽出しようとした
      • あんまりうまくいかない
    • PhonicMind で1曲だけ利用枠購入してボーカルを抽出しようとした
      • 曲調によってはうまくいく
  • Macだけど「歌声りっぷ」も使ってみて、品質を比較したい

※ 本エントリ末尾に、実際に聞ける形で結果の比較があります。

概要

  1. MacBoot Campで、Windows10を使えるようにする
    1. Windows10のプロダクトキーをAmazonで購入しとく
    2. Windows10のISOファイルをダウンロードする
    3. Windows10のインストールと起動+初期化
  2. MacWindowsを選択的に起動する
    1. 電源オフ状態 → Mac / Windows の選択
    2. Mac起動時 → Windows
    3. Windows起動時 → Mac
  3. 「歌声りっぷ」を利用可能な状態にする
    1. ソースのダウンロードとlzhの解凍
  4. 「歌声りっぷ」の使用
    1. 16bitのwavでなければいけない
    2. 実行!

手順の記録

1. MacBoot Campで、Windows10を使えるようにする

1-a. Windows10のプロダクトキーをAmazonで購入しとく

箱でも変えるっぽいけど、オンラインコードで買ったほうがいろいろ楽だと思われ。僕はこちらをポチった。金無いけど。

購入が完了して「注文履歴」→「注文の詳細」で「ライブラリに移動」すると、プロダクトキーが表示されてる。

f:id:otiai10:20181019151248p:plain

f:id:otiai10:20181019151947p:plain

このプロダクトキー、携帯のカメラなりでメモっとくのがいいです。1-cでWindowsをアクティベートするとき、当然ながらこの画面をこのPCで開く術が無いのでw

1-b. Windows10のISOファイルをダウンロードする

上記で購入したものは、Windowsをマシンにインストールしてアクティベートするときに必要な「プロダクトキー」であり、WindowsのOSそのものではないので、OSのソースコードをダウンロードしてくる必要があります。まあまあデカい。

1-c. Windows10のインストールと起動+初期化

Boot Camp Assistant」という標準でMacに入ってるアプリケーションを使って、上記でダウンロードできたWindows10のISOファイルを元に、Windows10をこのマシンにインストールする。必要なソフトウェアのダウンロードなどを含むので、ある程度太い回線につないで実行するのがよいかと思われます。

f:id:otiai10:20181019154341p:plain

インストールが終わると、Windowsでの再起動を提案されるので、Yesです。

Windowsが立ち上がり、言語やキーボードレイアウトなどを聞かれたのち、プロダクトキーを入力する場面になるが、それはもう1-aで購入しているので、それを使う。

f:id:otiai10:20181019155155p:plain

2. MacWindowsを選択的に起動する

2-a. 電源オフ状態 → Mac / Windows の選択

support.apple.com

以上。

2-b. Mac起動時 → Windows

support.apple.com

以上。

2-c. Windows起動時 → Mac

これが問題で、ほんまは「右下の△」→「ひし形マーク」→「OS Xでの再起動」を選択したらBootCampできるらしんだけど、macOS High Sierra からどうやらそれが動かないらしいので、

2-aと同じ方法を取る、つまり一度シャットダウンするよりほかなさそう。

参考: itkhoshi.com

3.「歌声りっぷ」を利用可能な状態にする

無事、MacでWindows10が動くことが確認できたので、つぎに「歌声りっぷ」を調達する。

3-a. ソースのダウンロードとlzhの解凍

ソースそのものはここでダウンロード可能

www.vector.co.jp

ただ、落としてきたものがlzhファイルで、この解凍ソフトウェアがデフォルトで入っていないので、

forest.watch.impress.co.jp

これを落としてきて、ショートカットをデスクトップに作成して、そこに「歌声りっぷ」のlzhファイルをドラッグアンドドロップすると、無事、解凍され、中に.exeファイルがあったので、これをめんどくさいのでそのままデスクトップに移動した。

4. 「歌声りっぷ」の使用

4-a. 16bitのwavでなければいけない

GUIめんどいので、MacなりLinux環境で、ffmpegCLIをつかった

# オリジナルトラックとオフボーカルトラック両方用意する
% ffmpeg -i ./original.mp3 -acodec pcm_s16le original.wav
% ffmpeg -i ./offvocal.mp3 -acodec pcm_s16le offvocal.wav

4-b. 実行!

Google Driveかなんかに入れて、Windowsに渡して、歌声りっぷする。した。

結果の比較

Phonic Mind
Ableton Live
歌声りっぷ

結論

  • 今回のケースでは「Phonic Mind」が段違いに性能悪いように聞こえるが、曲によってはバッチリ抜けることもある
  • 「Ableton Live」で自分で頑張る場合には、ここからさらにEffect/Filterなどでならしていく余地があるし、やっぱり楽
  • 何も設定いじらず、「歌声りっぷ」が今回は最も良い結果になった。がんばってWindows環境構築してよかった

謝辞

どうしても歌声りっぷ使ってみたいという今回の検証にあたって、大好きなトラックメーカーであるハナカミリュウさん、DJの先生であるKAZZONE大先生、間接的ではありますがCoNoSyuNya氏、にたいへん助けていただきました。ありがとうございます。

なお、今回がんばってアレしたソレで、はじめてのマッシュアップトラックをつくって、来たる 11月2日(金曜日)の Sound Sandbox vol.3 で流そうと画策しています!どうぞ遊びに来てください!

soundsandbox.tokyo

で、完成したもの

上記のイベントでかけた。マッシュアップたのしい。

soundcloud.com

DRYな備忘録として

CSSアニメーションで水面の波紋を表現

背景

某これウィジェット*1のローディングインジケータに、水面の波紋のアニメーションGIFを使ってたんですが、アニメーションGIFをインターネッツで漁ったりライセンス確認しなきゃならんうえにカスタマイズできないのがしんどくなったので、CSSで作れないかなと思った次第。

方針

  1. 丸いdivをつくる
  2. 大きさを keyframe animation する
  3. box-shadow inset とかで波っぽくする
  4. 外に行くにつれて薄くすれば消えていく感じになるかな
  5. それらを複数、ずらして重ねればよさそう
  6. 楕円にして水面表現する
  7. その他のチューニング

うるせえ動くもの見せろ

これです

あと読まなくていいです。

1. 丸いdivをつくる

div.circle {
  width:  80%;
  height: 80%;
  border: solid thin #303030;
  border-radius: 50%;
}

f:id:otiai10:20180902000244p:plain

2. 大きさを keyframe animation する

div.circle {
  /* 略 */
  animation: wave 2s infinite;
}

@keyframes wave {
  from {
    width:  0%;
    height: 0%;
  }
  to {
    width:  100%;
    height: 100%;
  }
}

f:id:otiai10:20180902001043g:plain

Chromeのデフォルトのtiming-functionが都合よくうごいてる。

3. box-shadow inset とかで波っぽくする

@keyframes wave {
  from {
    /* 略 */
    box-shadow: 0 0 100px inset #3f3f3f;
  }
  to {
    /* 略 */
  }
}

f:id:otiai10:20180902001939g:plain

だいぶそれっぽいやんけ。

4. 外に行くにつれて薄くすれば消えていく感じになるかな

@keyframes wave {
  from {
    /* 略 */
  }
  to {
    /* 略 */
    opacity: 0;
  }
}

f:id:otiai10:20180902001758g:plain

かなりそれっぽいやんけ。

5. それらを複数、ずらして重ねればよさそう

      <div class="box">
        <div class="circle layer-0"></div>
        <div class="circle layer-1"></div>
        <div class="circle layer-2"></div>
        <div class="circle layer-3"></div>
      </div>
.box {
    /* 略 */
    position: relative;
}

.circle {
    /* 略 */
    position: absolute;
}

div.circle.layer-0 {
  animation-delay: 0s;
}
div.circle.layer-1 {
  animation-delay: 0.2s;
}
div.circle.layer-2 {
  animation-delay: 0.4s;
}
div.circle.layer-3 {
  animation-delay: 0.6s;
}

f:id:otiai10:20180902002930g:plain

できてるやん。

6. 楕円にして水面表現する

これ、サイズが相対なので、transform使うまでもねえわ。

.box {
    height: 10vw;
    /* 略 */
}

f:id:otiai10:20180902004633g:plain

もうほぼ水面やんけ。

水滴が4つ落ちるのではなく、1滴に対して4種類の波が発生するべき

今、4つの水滴が逐次的に落ちて、それぞれ同じ波が4つ生まれているけど、自然には、1つの水滴が落ちて、複数の種類の波が発生すべきなので、ずらし方を改善する。

f:id:otiai10:20180902004509g:plain

いい感じやんけ。

色をちゃんとする

色のセンス無いんだわ〜

f:id:otiai10:20180902005414g:plain

横波をつけてみる

まず沈み込んで、盛り上がって、もっかい沈み込んで、で平常状態に戻る、みたいな感じかな。

f:id:otiai10:20180902010901g:plain

それっぽくなったけど、典型的な「がんばった結果もっさいデザイン」になった気がする。shadowいらないんじゃないかな。

雑感

  • opacityは多く使うのはパフォーマンス的に難あるかもしれない
  • ミニマムな実装としてはこれで満たしてるから、あとはチューニング
  • 他にも方法あったらおしえてください
  • わりとちゃんと働いてがっつり給料もらえる職場があれば紹介してください

DRYな備忘録として

今すぐ使えるCSSレシピブック

今すぐ使えるCSSレシピブック

Go GCP Client で ComputeEngine インスタンスの作成・取得

やりたいことを gcloud SDK で確認

% gcloud compute instances create \
    --project otiai10-sandbox \
    --zone asia-northeast1-a \
    testetst

% gcloud compute instances list \
    --project otiai10-sandbox \
    --filter zone:asia-northeast1-a

Go GCP Client でだいたい同じことやる

これです

github.com

以下全文

package main

import (
    "context"
    "flag"
    "fmt"
    "log"
    "time"

    "google.golang.org/api/googleapi"

    "github.com/otiai10/debug"
    "golang.org/x/oauth2/google"
    compute "google.golang.org/api/compute/v1"
)

var (
    project string
    zone    string
    name    string
)

func init() {
    flag.StringVar(&project, "project", "otiai10-sandbox", "Project name on GCP")
    flag.StringVar(&zone, "zone", "asia-northeast1-a", "Zone of GCP")
    flag.StringVar(&name, "name", "test-instance", "Instance name to create")
    flag.Parse()
}

func main() {

    ctx := context.Background()
    client, err := google.DefaultClient(ctx, compute.ComputeScope)
    if err != nil {
        debug.Fatalln(err)
    }

    service, err := compute.New(client)
    if err != nil {
        debug.Fatalln(err)
    }

    // Read
    instance, err := service.Instances.Get(project, zone, name).Do()

    if err == nil && instance != nil {
        // Delete
        log.Printf("Instance found, trying to delete.")
        _, err := service.Instances.Delete(project, zone, name).Do()
        if err != nil {
            debug.Fatalln(err)
        }
        for count := 0; ; count++ {
            fmt.Print(".")
            _, err := service.Instances.Get(project, zone, name).Do()
            if apierror, ok := err.(*googleapi.Error); ok && apierror.Code == 404 {
                fmt.Print("\n")
                break
            }
            time.Sleep(2 * time.Second)
            if count > 15 {
                debug.Fatalln("Couldn't wait for instance deletion ;(")
            }
        }
        log.Printf("Deleted: %v", name)
    } else if apierror, ok := err.(*googleapi.Error); !ok || apierror.Code != 404 {
        debug.Fatalln(err)
    }

    // Create
    instance = &compute.Instance{
        Description: "This is test",
        Name:        name,
        MachineType: fmt.Sprintf("zones/%s/machineTypes/n1-standard-1", zone),
        NetworkInterfaces: []*compute.NetworkInterface{
            &compute.NetworkInterface{
                Network: fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/global/networks/default", project),
            },
        },
        Disks: []*compute.AttachedDisk{
            &compute.AttachedDisk{
                AutoDelete: true,
                Boot:       true,
                Type:       "PERSISTENT",
                InitializeParams: &compute.AttachedDiskInitializeParams{
                    SourceImage: "projects/debian-cloud/global/images/debian-9-stretch-v20180806",
                    DiskSizeGb:  10,
                },
            },
        },
    }
    _, err = service.Instances.Insert(project, zone, instance).Do()
    if err != nil {
        debug.Fatalln(err)
    }

    log.Println("Created:", instance.Name)
}

雑感

  • AWSより概念が細分化されており、SDKとしての Hello World まで行くのはわりと大変だったけど、一度動いてしまったら、概念が明確で、とても使いやすい印象

DRYな備忘録として

クラウドエンジニア養成読本[クラウドを武器にするための知識&実例満載! ] (Software Design plusシリーズ)

クラウドエンジニア養成読本[クラウドを武器にするための知識&実例満載! ] (Software Design plusシリーズ)

【メモ】Slackチャンネルへの画像の投稿

参考

curl

% curl -XPOST "https://slack.com/api/files.upload" \
    -H "Content-Type: multipart/form-data" \
    -F file=@/Users/otiai10/Desktop/ritsu.jpeg \
    -F token=xoxb-123-456-xxxxxxxxx \
    -F channels=bot-dev \
    | jq
{
  "ok": true,
  "file": {
    "url_private": "https://files.slack.com/files-pri/ABCDEFGHIJKLMNOPQRSTUVWXYZ/ritsu.jpeg",
    "url_private_download": "https://files.slack.com/files-pri/ABCDEFGHIJKLMNOPQRSTUVWXYZ/download/ritsu.jpeg",
    // いろいろ省略
}

DRY

【メモ】VPCエンドポイントについて

背景

  • EC2とS3が密に関係するソフトウェアを書いてるんですが、VPCエンドポイントの概念を知らなかったので、非常に悔やまれます。

資料

VPCエンドポイントが解決する問題

  • EC2インスタンスなどVPC内のサービスから、S3を参照するさい、InternetGatewayやNATを通って一度インターネットに出る必要がある
  • これを、VPCエンドポイントという概念を使って、インターネットに出ずに、AWSのネットワーク内でS3まで到達できるようになった
    • 具体的には、 S3のエンドポイントをDestinationとし、VPCエンドポイント(vpce-から始まるリソース)をTargetとするRouteをRouteTablesに追加することによって実現する
    • リージョンはまたげない
  • NATの負荷軽減、セキュリティの強化が期待できる

使い方の概要

概念的なところ。

  1. 確認用に、インターネットに出ていけないSubnetをつくる
    • のちにこれにsshして動作確認するので、必要なら、自宅なりオフィスのIPアドレスDestinationとしInternetGatewayをTargetに持つRouteだけは、追加しておく
  2. このSubnetの配下にEC2インスタンスを作成する
    • SecurityGroupはiptablesみたいなもので今回の検証とはレイヤーが違うので、検証環境からsshできるIn/Outを設定すればよい
  3. このEC2インスタンスsshする
    • あとで使うので、必要なら sudo yum install -y python-pip && pip install awscli とかしとく
  4. ping google.comとかやって、インターネットに出ていけないことを確認する
  5. aws s3 ls your-bucket などして無反応なことを確認する
    • なぜなら、EC2からS3は、デフォルトではインターネット経由だから
  6. VPCエンドポイントを作成し、このSubnetと紐付ける( ≒ RouteをRouteTablesに追加する)
  7. やはり、ping google.com は通らない
  8. しかし、aws s3 ls your-bucket は通る
    • なぜなら、EC2からS3への疎通はVPCエンドポイントが使われるようになったから

※ リージョン跨げないので、your-bucketはEC2と同リージョンである必要がある

DRYな備忘録として

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版