A10のリバースプロキシで外部サーバへ転送する設定

A10の調べ物で色々ググるがあまり出てこないので,今回はA10でのリバースプロキシの設定をまとめておこうと思う.
A10のハードウェアアプライアンスA10 Thunder 4430である.

現状確認と要件

オンプレ環境にLBとしてA10を設置しており,A10ではインターネット(エンドユーザ)からのトラフィックを配下のLANに流している.仮にhoge.co.jpというサービスをオンプレ環境にホストしているとして,https://hoge.co.jp/fuga.txtというファイルにアクセスされたらそのトラフィックを外部のサーバに流し,それ以外のパスについては従来通り配下のLANに流すような要求が発生したとする.外部サーバにはhttpsで通信し,外部サーバのFQDNpiyo.co.jpのようにhoge.co.jpとは異なることを想定している.今回の外部サーバはAWSにあるものとし,443番ポートを受け付けているALB(Application Load Balancer)とそこに80番ポートを受け付けているEC2がぶら下がっている構成にする.イメージを下図に示す.

f:id:a-mochan:20201218234415p:plain
構成図

上記の要件を実現するためにA10で実施すべきことの詳細を説明する.

SNATの必要性

上記の通信を実現するには,A10で外部からのリクエストを受け取ったとき,ネットワーク層のソースIPをNAT(SNAT)させる必要がある.なぜなら,SNATをしないと外部サーバへたどり着くリクエストのソースIPはクライアントのものになり,外部サーバからのレスポンスがA10を経由せずクライアントに直接返されてしまうからである.クライアントからするとリクエストはA10に送信したのに,レスポンスは外部サーバから受け取ってしまう形となり通信ができない状態となる.したがってA10ではSNATも考慮する.

復号化と再暗号化

A10では受け取ったリクエストのパスで振り分け先を判断するので,一度復号しないとパスを確認することができない.また,A10・外部サーバ間はhttpsの通信を想定している.したがってA10では,受け取ったリクエストのアプリケーション層の情報(主にパス)を確認するために一度復号化し,再度暗号化して外部サーバへ通信する必要がある.

ホストの書き換え

A10配下のLANにホストしてあるFQDNhoge.co.jpで,外部サーバにホストしてあるFQDNpiyo.co.jpを想定しているので,A10では外部サーバへ転送する際にホストを書き換える必要がある.

実現方法

上記で説明してきた要件をA10では以下の手順で設定していく.

  1. ALBをサーバとして登録,サーバをサービスグループとして登録
  2. IP Source Pool作成
  3. Client SSL,Server SSLテンプレート作成
  4. aFlex作成
  5. バーチャルサーバ作成

1. ALBをサーバとして登録

外部サーバとしてA10にALBを登録する.外部サーバの登録方法としてIPかFQDNを選べるので今回はALBから払い出されるDNS名を指定する.ヘルスチェックは外部サーバによって決めればよいが,今回は443ポートチェックで行う.作成したサーバをサービスグループとして登録する.

slb server piyo-alb piyo-alb-1111111111.ap-northeast-1.elb.amazonaws.com
  port 443 tcp
    health-check tcp_443
slb service-group piyo-sg tcp
  member piyo-alb 443

2. IP Source Pool作成

SNATのためのIPプール作成.

ip nat pool global_ip_pool 33.44.55.1 33.44.55.10 netmask /24 ip-rr

3. Client SSL,Server SSLテンプレート作成

復号化・暗号化するためのClient SSL,Server SSLテンプレート作成.秘密鍵や証明書の登録は割愛する.

slb template client-ssl any.co.jp
  ca-cert CA
  cert any.co.jp
  key any.co.jp
slb template server-ssl reverse-proxy-re-encrypt

4. aFlex作成

A10のリバースプロキシを実現するキモとなるのがこのaFlexである.1~3で設定した内容をaFlexのスクリプトで定義する.また,ホストの書き換えもaFlexで行う.reverse-proxy-aflexという名前で作成する.

when HTTP_REQUEST {
  if { [HTTP::path] matches_regex "^/fuga.txt$"} {
    HTTP::header insert X-Forwarded-For [IP::client_addr]   # クライアントのIPを外部サーバのアプリケーションログに出したければこの設定を入れる
    HTTP::header Host "piyo.co.jp"
    pool piyo-sg
    snatpool global_ip_pool
    SSL::template serverside reverse-proxy-re-encrypt
  }
}

5. バーチャルサーバ作成

/fuga.txtの場合はaFlexで処理し,それ以外の場合はLANに流すサービスグループを指定したバーチャルサーバを作成.

slb virtual-server reverse-proxy-vs 111.222.11.22
  port 443 https
    aflex reverse-proxy-aflex
    service-group hoge-sg   # `/fuga.txt`ではないパスの場合はLANに流すようにサービスグループを設定
    template client-ssl any.co.jp   #復号化

以上の設定でhttps://hoge.co.jp/fuga.txtにアクセスするとALBに転送され,その他のパスについてはLANに流れるようになる.

まとめ

  • A10のリバースプロキシで外部サーバへ転送した
  • 今回はインターネットを経由するパターンで設定したが,専用線などが引いてありインターネットを経由しない場合は再暗号化しなくてもよいと思われ,今回の設定からいくつかステップを省略することが考えられる
  • A10を使用しているオンプレからAWSへ移行する際には使用する場合があるかもしれない

CloudFormation StackSetsを使う上で覚えておきたいこと

業務でCloudFormationのStackSets(以降StackSets)という機能を使ってマルチアカウント・マルチリージョンデプロイを試してみて、いくつか気をつけるべき点があったのでメモがてらまとめておこうと思う.

StackSetsについて

StackSetsを簡単に説明する.StackSetsとは,複数のAWSアカウントや複数のリージョンに跨ってAWSサービスをデプロイする時に使用するサービスである.単一のアカウントにデプロイするサービスとしてCloudFormation Stackがあるが,その拡張版といってよい.StackSetsでは,StackSetsを実行するアカウントとStackSetsによってサービスがデプロイされるアカウントが存在する.前者を親アカウント,後者を子アカウントと呼ぶことにする.親アカウントでStackSetsを実行すると,子アカウントにスタックが作成され,そのスタックのテンプレートに記載されている内容が子アカウント上で設定される.

https://d2908q01vomqb2.cloudfront.net/972a67c48192728a34979d9a35164c1295401b71/2019/09/04/6955-1-CloudFormation-StackSets.png

StackSetsを実行すると親アカウントにスタックセットと呼ばれる子アカウントのスタックを管理するリソースが作成され,そのスタックセット配下には各アカウントの各リージョン毎に一意なスタックインスタンス(子アカウントのスタックへのリファレンス)が作成される.詳しくは公式ページを参照あれ.

docs.aws.amazon.com

StackSetsを使う際の注意点

AWS CLIのバージョンの違いによるaws cloudformation describe-stack-setの表示項目の違い

aws cloudformation describe-stack-setは作成したスタックセットの詳細を取得するコマンドである.AWS OrganizationsのOrganization Unit(以降OU)を使ったデプロイを使っている場合,aws cloudformation describe-stack-setを実行することで,OrganizationalUnitIdsの項目に対象のスタックセットがどのOUにデプロイされているかが表示される.しかし,古いAWSコマンドのバージョンによってはOrganizationalUnitIdsという項目が表示されない事象がある.どのバージョンまでが表示されなくて,どのバージョンから表示されるかは分からないが,自分の環境のバージョンで試した結果は少なくともaws-cli/1.16.250では表示されず,aws-cli/1.18.125では表示された.OUを使ったデプロイが今年に入ってからの機能なので,AWSコマンドの古いバージョンを使っている場合は注意する.

aws.amazon.com

親アカウントが属しているOUにデプロイするとき,親アカウント自身にはデプロイされない

OUを使うデプロイを考えた時,子アカウントだけでなく親アカウントもOUに含めることで親アカウントにもデプロイするよう試してみたが,親アカウントにはデプロイできなかった. これは公式ページにも記載されている.親アカウントにもデプロイしたい場合は別途StackやStackSetsを使ってデプロイしなければならない.

StackSets は、マスターアカウントが組織内または組織の OU 内にあっても、スタックインスタンスを組織のマスターアカウントにデプロイしません。

このページの「サービスマネージド型のアクセス許可を持つスタックセットを作成する際の考慮事項」はOUを使ったデプロイを想定している方はよく読んでおくとよいかもしれない. docs.aws.amazon.com

マルチリージョンにデプロイする際,グローバルリージョンにしか存在しないリソースの設定には気をつける

マルチリージョンにサービスをデプロイする前提で,グローバルリージョンにしか存在しないサービス(例えばIAM)をStackSetsで設定する場合は気をつけなければならない.例えば,ap-northeast-1のリージョンでIAMロールを作成し,us-east-1のリージョンでもIAMロールを作成した時,作成した2つのIAMロール名が同じ場合はエラーになる.この対応としては「どこか1つのリージョンで設定する」もしくは「IAMロール名をリージョン毎に変える」等で対応できる.これは当たり前といえば当たり前だが,意外とグローバルリージョンにしか存在しないサービスはあるので頭の片隅に置いておくとよいと思う.

サービスによってはクロスリージョンの通信ができないことによってStackSetsの実行が失敗する場合がある

サービスによってはクロスリージョンの通信ができないことによりStackSetsの実行が失敗するものがあるのでそれらを考慮する必要がある.
例えば,ap-northeast-1に作成したAWS Configで通知をAmazon Simple Notification Service(以降SNS)に送信したい時,SNSap-northeast-1に作成されている必要がある.これを例えばus-east-1に作成したSNSに通知しようとするとエラーとなる.他にも例えば,LambdaをStackSetsでデプロイする際,ap-northeast-1に作成されたLambdaのアーティファクトS3はap-northeast-1に作成されている必要がある.これを例えばus-east-1に作成したアーティファクトS3からコードを取得しようとするとエラーとなる.
このように,サービスによってはクロスリージョンアクセス不可能な設定があるので,それぞれのリージョンで必要なサービスを配置しておかないとStackSetsを流した時にエラーになることがある.
個人的な見解になるが,サービスによってクロスリージョンアクセスする・しないを分けるのはややこしいので,特に強い理由がなければ連携するサービスは1つのリージョンにおさめるのが分かりやすくて良いと思っている.

まとめ

  • StackSetsを使う上での注意点を列挙した
  • OUと連携できるようになってからStackSetsは余計な設定をすることなく使えるようになったので重宝しそう

JumpCloudの鍵認証で使用されるauthorized_keys.jcorigを理解する

業務上AWSのEC2のユーザ管理をJumpCloudで統一して管理している.JumpCloud上で管理対象のEC2に鍵認証を許可することができるのだが,公開鍵を設定する方法として「JumpCloudのコンソール上で設定する方法」と「実際にサーバに手動で設定する方法」がある.後者で設定しようとした際に~/.ssh/authorized_keysの他に~/.ssh/authorized_keys.jcorigというファイルがあることに気づいた(以降authorized_keysauthorized_keys.jcorigと表記する).今回はこれがなんのためにあるものなのか調べてみた.

authorized_keys.jcorigとは

公式には詳細については書いていなかった. support.jumpcloud.com

実際にauthorized_keys.jcorigの中身を確認したところ

# Keys added to this file will be automatically
# copied to your authorized_keys file by the JumpCloud agent.

と書いてあり,authorized_keys.jcorigに書くとJumpCloudエージェントがauthorized_keysにコピーしてくれるようだ.

さらにauthorized_keysを確認すると

# Keys added to this file will be automatically
# copied to your authorized_keys file by the JumpCloud agent.

# Constructed by the JumpCloud agent, you can add keys manually in /home/hoge/.ssh/authorized_keys.jcorig

と書いてあり,サーバ上で手動で設定するならauthorized_keys.jcorigに書き込めという旨が書いてある.

検証

公式にそこまで情報はないがauthorized_keys.jcorigに書き込めばauthorized_keysにJumpCloudエージェントが内容を反映してくれるのだろうという予想はできたので,実際に色々と試して検証してみることにする.JumpCloudエージェントがインストールされたEC2を用意し以下を確認していく.

  • サーバ上に手動で設定するパターン
    • authorized_keys.jcorigに公開鍵を追加
    • authorized_keysに公開鍵を追加
  • JumpCloud上で設定するパターン
    • 公開鍵を追加
    • 公開鍵を削除

サーバ上でauthorized_keys.jcorigに手動で公開鍵を追加

まずは正当な方法であろうauthorized_keys.jcorigに手動で公開鍵を追加する.しかし,しばらくしてもauthorized_keys.jcorigの内容がauthorized_keysにコピーされずログインはできなかった.そこで以下3パターンでログインの可否を確認する.

  • EC2を再起動するとauthorized_keys.jcorigの内容がauthorized_keysにコピーされログインできた
  • authorized_keysにも公開鍵を記述するとログインできた(その後EC2を再起動しても特に問題なし)
  • JumpCloudエージェントを再起動する方法ではauthorized_keysに内容がコピーされることはなくログインできなかった

サーバ上でauthorized_keysに手動で追加

次にauthorized_keysに公開鍵を追加してみた.するとログインできるようになったが,EC2を再起動をするとauthorized_keysから公開鍵が消えてしまいログインできなくなった.

ここまでの検証で以下のことがわかる.

  • 基本的にはauthorized_keysに公開鍵が登録されているかどうかで認証の機能が動作する一般的なLinuxの仕組みと同じ動きをする
  • authorized_keys.jcorigに公開鍵を記述してもauthorized_keysに記述されないと鍵認証されないので,即時でログインしたい場合はEC2を再起動するauthorized_keysにも同じ内容を書くことが必須
  • 手動で公開鍵を追加するにはauthorized_keys.jcorigに書かないと永続化されない
  • 公開鍵を削除する際は少なくともauthorized_keys.jcorigの公開鍵を削除しないと,EC2を再起動した際に再びauthorized_keysに書き込まれてしまう
  • 公開鍵を削除する際,即時にログインできないようにするにはauthorized_keys.jcorigの公開鍵を削除してEC2を再起動するかauthorized_keys.jcorigauthorized_keys両ファイルから公開鍵を削除する必要がある
  • authorized_keys.jcorigの内容をauthorized_keysにコピーする方法として,JumpCloudエージェントの再起動は使えない
  • 公開鍵の追加・削除共にauthorized_keys.jcorigが正として振る舞っている

JumpCloudコンソールから公開鍵を追加

JumpCloudコンソールを使って公開鍵を追加すると,EC2を再起動しなくともしばらくするとauthorized_keysに公開鍵が追加される.一方authorized_keys.jcorigには何も追加されない.また公開鍵を手動で追加した場合とJumpCloudコンソールから追加した場合とでauthorized_keysに記述される公開鍵の位置が以下のように異なる.

$ cat authorized_keys
# Keys added to this file will be automatically
# copied to your authorized_keys file by the JumpCloud agent.
[authorized_keys.jcorigからコピーされた手動で設定した公開鍵]

# Constructed by the JumpCloud agent, you can add keys manually in /home/yuichiro.takarada/.ssh/authorized_keys.jcorig
[JumpCloudコンソールで設定した公開鍵]

JumpCloudコンソールから公開鍵を削除

JumpCloudコンソールを使って公開鍵を削除すると,EC2を再起動しなくともしばらくするとauthorized_keysから公開鍵が削除される.ちなみに,JumpCloudコンソールから設定されたauthorized_keysに記述してある公開鍵を手動で削除するともちろんログインはできなくなるがJumpCloudのコンソールからは削除されない.そこからEC2を再起動するとauthorized_keysにJumpCloudコンソールで設定した公開鍵が再び設定される.

ここまでの検証で以下のことが分かる.

  • JumpCloudコンソールを使って追加された公開鍵はauthorized_keys.jcorigに書き込まれず,authorized_keysにのみ書き込まれる
  • JumpCloudコンソールを使って追加・削除された公開鍵は,EC2を再起動せずとも自動でauthorized_keysに追加・削除が行われる
  • JumpCloudコンソールを使って追加された公開鍵がauthorized_keysからサーバ上で手動により削除された場合でも,JumpCloudコンソールから削除されていなければ,EC2の再起動後再びauthorized_keysに書き込まれる
  • JumpCloudコンソールの状態を正として振舞う

検証結果からの学び

検証結果から,JumpCloudエージェントが入ったインスタンスでは「サーバ上で手動による公開鍵を設定する」・「JumpCloudで公開鍵を設定する」という2つの公開鍵設定方法がある中で,前者の方法ではauthorized_keys.jcorigを正としてauthorized_keysに公開鍵をコピーし,後者の方法ではJumpCloudコンソールを正としてauthorized_keysに公開鍵をコピーしていることが分かった.運用においては基本JumpCloudコンソール上から設定する方法でなんら問題ないと思うのでそうするつもりだが,どうしても手動で設定する必要がある場合だけ今回の調査を生かしてauthorized_keys.jcorigに公開鍵を記述する運用にしたい.とにかく,authorized_keys.jcorigが「サーバ上で手動による公開鍵を設定する」ためのファイルだということは理解した.

まとめ

  • JumpCloudエージェントが入ったインスタンスauthorized_keys.jcorigというファイルがなんのためにあるのかということを調べた
  • authorized_keys.jcorigは「サーバ上で公開鍵を設定する」場合の公開鍵を管理するファイルであることが分かった

LambdaとSSMでEC2からS3のオブジェクト取得させる

AWS環境で,Lambdaを用いてS3からEC2にオブジェクトを取得させる設定をしたのでメモがてら残しておく.

概要

Lambdaを使い,AWS Systems Manager(SSM)経由でEC2にAWSコマンドを実行させ,S3からオブジェクトを取得する.また,S3にあるオブジェクトは他AWSアカウントからPUTされたと想定する.以下に図を示す.

f:id:a-mochan:20200312213744j:plain

S3のバケットポリシーの設定

AWSアカウント間をまたぐS3バケットへのアップロードでは,オブジェクトの権限に気をつける.
例えば,AというAWSアカウントがS3バケットを作成したとして,Bという他のAWSアカウントからS3バケットへオブジェクトをPUTする.PUTする際にオプションを何も指定しなければ,S3バケットへPUTされたオブジェクトの所有者はBとなってしまい,AにあるEC2からはGETできないしマネージメントコンソールからもダウンロードできない.これを避けるため,PUTする際(aws-cliの場合)に--acl bucket-owner-full-controlオプションをつけて実行する.これにより,PUTしたオブジェクトの所有者がAアカウントになりAアカウントからGETすることが可能となる.詳しくは以下のブログが参考になった.

qiita.com

test-bucketというS3バケットを用意し,他のアカウントからPUTしてもらう.PUTしてもらう際に--acl bucket-owner-full-controlオプションをつけておかないとPUTできないようにConditionを設定したバケットポリシーを以下に示す.もっと制限をかけたければPrincipalCondtionを適宜追加する.

{
    "Version": "2012-10-17",
    "Id": "PolicyId2",
    "Statement": [
        {
            "Sid": "Test",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::test-bucket/*",
            "Condition": {
                "StringEquals": "s3:x-amz-acl": "bucket-owner-full-control"
            }
        }
    ]
}

EC2の設定

EC2では,S3からオブジェクトを取得するために,今回はAWSコマンドを使う.AWSコマンドがない場合はインストールを行う.また,LambdaでSSMを使うのでEC2インスタンスにSSMエージェントが入っていない場合もインストールしておく.さらに,SSMがEC2を扱うことができるようにAmazonEC2RoleforSSMポリシーが付与されたロールをEC2にアタッチしておく.

Lambdaの設定

Lambdaでは,SSMを使ってEC2上でAWSコマンドを実行してS3からオブジェクトをEC2上に配置する.まずは,LambdaがSSMを扱うことができるようにAmazonSSMFullAccessポリシーが付与されたロールをLambdaにアタッチする.また,EC2上で実行するAWSコマンドで必要なシークレットIDとシークレットキーは環境変数としてLambdaで渡すようにする.Pythonで記述したLambdaの例を以下に示す.

import boto3
import os

ACCESS_KEY_ID = os.environ['ACCESS_KEY_ID']
SECRET_ACCESS_KEY = os.environ['SECRET_ACCESS_KEY']

ssm = boto3.client('ssm')

def lambda_handler(event, context):
    bucket = 'test-bukect/'
    ec2_dir = '/var/tmp'
    s3_dir = 'test/'
    
    commands = [
        "export AWS_ACCESS_KEY_ID=" + ACCESS_KEY_ID,
        "export AWS_SECRET_ACCESS_KEY=" + SECRET_ACCESS_KEY,
        "export AWS_DEFAULT_REGION=ap-northeast-1",
        'aws s3 sync s3://' + bucket + s3_dir + " " + ec2_dir
    ]
    ssm.send_command(
            InstanceIds = ('i-123456789',),
            DocumentName = "AWS-RunShellScript",
            Parameters = {
                "commands": commands,
                "executionTimeout": ["3600"]
            }
    )

これで,Lambdaを実行すればtest-bucketの/testディレクトリ以下にある内容がEC2上の/var/tmp以下にコピーされる.

まとめ

  • LambdaとSSMを用いてEC2からS3のオブジェクト取得させた
  • 他アカウントからのS3へのPUTではbucket-owner-full-controlをつける

Route53 Resolverを使う際気をつけたいこと

会社で,あるサービスをオンプレからAWSへ移行する際,Direct Connect(DX)を張って移行した.その際AWS環境からオンプレにある外部に公開していないDNSサーバへ名前解決する必要があったのでRoute53 Resolverを使用した.Route53 Resolverを使ってみて2つほど注意したいことがあったのでメモとして残しておこうと思う.

Route53 Resolver

Route53 Resolverとは,オンプレとVPCがDXやVPNで繋がっている環境で,オンプレからRoute53のプライベートホストゾーンへアクセスさせたり,逆にVPC内からオンプレの外部に公開していないDNSサーバへアクセスさせたい時に利用するサービスである.両アクセスはRoute53 Resolverによって作成されるエンドポイントを経由してそれぞれの権威サーバへアクセスが行われる.詳しい設定は以下のブログが参考になる.

dev.classmethod.jp

サブドメインの柔軟な名前解決が難しい

1つめの注意すべきことだが,タイトルだけでは何を言っているか分かりにくいと思う.
例として,Route53 Resolverを使ってAWS環境からオンプレのDNSexample.com)に名前解決する場合を考えてみる.example.comドメインRoute53 Resolverを作成すると,example.comおよびそのサブドメインはすべてオンプレのDNSに名前解決するようになる.
ここで,aaa.example.comの名前解決だけオンプレのDNSではなくRoute53に向けたい場合を考えると,example.comサブドメインもすべてオンプレのDNSへ名前解決しにいくので一筋縄ではいかない.この場合,オンプレDNS側でaaa.example.comはRoute53へ向けるNSレコードなどを追加して対応する必要があると思う.
では逆に,aaa.example.comの名前解決だけオンプレのDNSへ向けたい場合を考えると,これは単純にaaa.example.comドメインRoute53 Resolverを作成すればよいことになる.
要するにここで注意したいのは,Route53 Resolver作成時に設定するドメインとそのサブドメインはもれなく指定したDNSへ名前解決されてしまう点である.

さらに補足すると,example.comドメインaaa.example.comドメインのそれぞれでRoute53 Resolverを作成することができる.その場合はaaa.example.comドメインおよびそのサブドメインの名前解決はaaa.example.comドメインで作成したRoute53 Resolverを経由する.それ以外のexample.comドメインおよびそのサブドメインexample.comドメインで作成したRoute53 Resolverを経由する.つまり,最長一致のような動きをする.ただし,Route53 Resolverで設定するDNSにRoute53は指定できない.

f:id:a-mochan:20200229160945p:plain
ゾルバルール作成画面の説明

コストに注意

Route53のトラフィックフローなど他のRoute53の機能もそうなのだが,Route53の料金体系として設置しているだけでコストがかかるタイプが多い.Route53 Resolverの場合,設置するだけで一時間0.125USDなので一ヶ月で90USDかかる.そして,この90USDはElastic Network Interface(ENI)ごとにかかり,Route53 ResolverではDNSクエリに対して最低でも2つのIPアドレス(ENI)を必要とするので,設置するだけで一ヶ月180USD(90USD*2)かかる.さらに,通信量が上乗せされていくのでRoute53 Resolverを使う際は設置コストも頭に入れておくとよいかもしれない.

aws.amazon.com

まとめ

  • Route53 Resolverで気をつけるを紹介した
    • Route53 Resolverを経由させるサブドメインの扱いに注意する
    • 通信量の他に設置コストもかかる

簡単!ワークフロービルダーで業務効率化してみた

去年の10月頃にSlackの機能としてワークフロービルダーがリリースされた.ワークフロービルダーとはある程度決められた業務フローをSlackで自動化できる機能である.最近業務で使ったので事例紹介と使ってみての感想を書こうと思う.

事例の説明

弊社はワークフローのSaaSを使って業務フローを効率化しているが,エンジニアの業務フローの中にはSaaSを使う必要のないフローがあったりする.その一例として個人が使うサンドボックスAWSアカウントの作成がある.弊社では,開発エンジニアはインフラへ申請すれば,検証のための個人用AWSアカウントを発行できるルールになっている.今回はその申請をワークフロービルダーを使って出せるようにした.
全体の流れを説明すると,まず申請者はAというチャンネルでワークフロービルダーを使って申請を行う.すると,インフラがワークフロー通知用に作ったBというチャンネルに内容が表示される.そして,インフラが申請内容についての作業を行った後,再びAチャンネルに作業完了の通知が表示される.

手順

ワークフローを作成するには,Slackの左上にある自分の名前やワークスペース名が表示されている部分をクリックし,「ワークフロービルダー」を選択する.すると以下のような画面が出てくる. f:id:a-mochan:20200202112008p:plain

「作成」を押すと,ワークフロー作成後に上記のワークフロー一覧画面で表示される名前の入力を求められるので,「個人用AWSアカウント申請」という名前で登録する. f:id:a-mochan:20200202112140p:plain

次に,ワークフローをどのトリガーで発火させるかを選ぶ.この事例では,申請者がアクションメニューから明示的に申請してほしいので「アクションメニュー」を選択する. f:id:a-mochan:20200202112226p:plain

次に,アクションメニュー一覧に表示されるワークフローの名前の設定と作成するワークフローをどのチャンネルに設定するかを聞かれるので以下のように設定する. f:id:a-mochan:20200202112302p:plain

ここまでで以下のようなベースができるので,ここからは1つずつステップを作成していく. f:id:a-mochan:20200202112323p:plain

まずはAチャンネルで申請内容を入力してもらうフォームを表示したいので,ステップの追加で「フォームを作成する」を選択し,以下のようなフォームを作成する.入力したフォームの内容をAチャンネルにも流しておきたいので,「提出された回答をチャンネルまたはDMで他のメンバーに送信する」にチェックをつけてAチャンネルを指定しておく. f:id:a-mochan:20200202112440p:plain

次に,Bチャンネルにフォームで提出された内容を流したいので,ステップの追加で「メッセージを送信」を選択し,以下のように設定する.Bチャンネルに流れるメッセージに「完了」ボタンをつけて,作業者が作業を終えたタイミングでそのボタンを押し,次のステップに進むようにする.
メッセージの送信では,当該ステップより前に作成されたステップに関連する要素を変数としてテキストに埋め込むことができる.また,下部には作成したテキストのレビューが表示されているので確認が容易だ. f:id:a-mochan:20200202112457p:plain

完了ボタンが押されたあと,再びAチャンネルに完了が通知されるように以下のようにステップを追加する. f:id:a-mochan:20200219075201p:plain

全体像は以下のようになる.右上に「公開する」ボタンがあると思うのでそれを押すとAチャンネルで使えるようになる. f:id:a-mochan:20200219075417p:plain

では,実際にAチャンネルの右上に表示されている⚡️マークから「個人用AWSアカウント申請」を押してみる.すると先ほど作成したフォームが表示されると思うので「申請者」「申請者のメールアドレス」を入力して「送信」をクリック.その内容がAチャンネルに流れる. f:id:a-mochan:20200219075440p:plain

それと同時にBチャンネルにも流れている.作業者は作業を行なったあと,「完了」ボタンを押す. f:id:a-mochan:20200219075451p:plain

するとAチャンネルの方に完了通知が届く. f:id:a-mochan:20200219075503p:plain

以上が個人用AWSアカウント申請を例にした紹介である.

感想

使ってみてワークフロービルダーは良いところといまいちなところが見えた.

  • 良いところ
    • ワークフローの作成自体がとても容易
    • 作成した人や使う人がワークフロービルダーが出力する内容を削除できないので,変に消されたり修正されたりしない
  • いまいちなところ
    • フローの分岐や前のステータスに戻ることができない
    • 良いところの裏返しであるが,間違って出してしまっても取り消すことができない
    • 複数のチャンネルでワークフローの共有ができないので,1つ作って他で使い回すことができない

まとめ

  • Slackのワークフロービルダーを使ってみた
  • とても簡単にワークフローを作れる反面,機能はまだ少ないので簡単なワークフローを作成する際に使う感じになりそう

シリコンバレーでのキャリアを考えている人必読「エンジニアとして世界の最前線で働く選択肢」を読んだ

私は大学院生の時、大学を通じてロサンゼルスへ行き、そこでインターンをしたり、シリコンバレーのスタートアップで話を聞いたりした経験があります。その時から、いつかまたシリコンバレーで働いてみたいなぁと思っていました。そんななかつい先日、「エンジニアとして世界の最前線で働く選択肢」という本を知って読んでみたらとても面白かったので、内容の紹介や感想を書いていきたいと思います。

  • 1章:あなたはアメリカに合っているのか
  • 2章:どうやったら渡米できるか
  • 3章:アメリカ企業に就職・転職する
  • 4章:ホワイトボードコーディング面接を突破する
  • 5章:アメリカで働くと何が違うのか
  • 6章:転職を通してキャリアアップする
  • 7章:解雇に備える

ビザの取得

今日本で働いている日本人がアメリカで働きたいと思った時、まず一番最初にぶち当たる大きい壁がビザの取得です。当たり前ですが、アメリカで日本人が働くには、入国して働くためのビザが必要となります。この本を読むと、アメリカで働くためのビザにはいくつか種類があり、それぞれのビザを取得するには労力や難易度が違うことが分かります。本では4つの方法が紹介されていたので簡単に説明します。ただし、ビザの取得方法や種類は変わることがあるのでその時の最新情報はみておいた方がよいです。

留学後に現地就職

これは一番の王道パターンです。経済的・時間的問題がないのであればこれが確実にアメリカでの就職に繋がります。ただし、会社を辞めて留学するパターンでは、アメリカでの就職に失敗した場合、日本に戻っても年齢の問題で就職が難しくなるリスクはあります。これに関しては、@noralifeさんが以下のポッドキャストで実例をお話されていたので聞いてみるといいかと思います。

fukabori.fm

日本から直接雇用

これは一番ハードルが高く、運も必要な方法です。難しい理由としては2つあります。1つは面接の労力が大きい点です。アメリカ国内にたくさんの優秀なエンジニアがいるのに、わざわざ海外のエンジニアを面接する理由はあまりありません。オンサイト面接で飛行機代やその他のお金がかかったり、採用した人が文化に馴染めなかった時のリスクなどもあります。
もう1つは、採用した後のビザの問題です。H1-Bビザの枠に余裕がなければ4月にビザを申請して10月に発給されるまで半年待たなければなりません。「このチームの人員が足りないから雇いたい」という場合はまず採用されません。

ただし、それでも海外のエンジニアを雇いたい理由はあります。まず思いつくのが、応募してきたのがとても優秀なエンジニアである場合です。オープンソースに多大に貢献していて、そのネットワークを使って紹介されるケースが考えられます。ビザの問題は別途あるのですが、例えば著名な論文誌や学会の掲載実績があるなどの理由で発行されるOビザを取得できるのであれば、ビザの問題はなくなり採用される可能性があがります。
次に考えられるのが、日本人を雇いたい場合です。アメリカにありながら日本を相手にしたビジネスをしている会社や、もともと日本人が作った会社で日本人を増やしたいときなど、日本人を直接雇う場合があります。

日本で就職後に移籍

これはアメリカに本社がある外資系かアメリカに支社がある日本の会社に入社して、海外へ社内移籍するという方法です。この方法のメリットはなんといっても簡単な点に尽きます。前述した留学の方法は社会人にとってはハードルが高いですし、直接雇用の方法もアメリカの会社の面接を突破し、ビザの問題もクリアしなければならないのでハードルが高いです。それよりは、日本で働いて仕事の実績を武器に移籍する方がずっと簡単ですし、社内移籍ではLビザ・Eビザ等を使用できます。
一方デメリットは、実現が運まかせなことです。どんなに仕事の実力があっても、その時の会社の方針や状況により移れないことがあります。著者は運良く入社後数年で駐在のチャンスをもらえたそうです。「アメリカで働けるといいなと思っているけど、日本でずっと働くのもそんなに悪くない」と思っている人は向いている方法だと書いていました。

その他の方法

他にも、抽選による永住権の取得アメリカ人との結婚による永住権の取得アメリカで生まれたことによる市民権の取得などのパターンもあるのですが、上記で紹介した方法が海外で働く現実的な路線だと思います。どの方法もトレードオフで本人の人生の選択によることが分かりました。ただ、この本を読んで色々と海外就職について調べていたらEビザを使った方法で、かつ私が知らなかった方法で海外就職した方がいたので紹介しておきます。

taiyakijp.com

エンジニアの面接

この本では、面接に関することについてかなり詳細に記載されています。著者が面接官としての経験から、面接前・面接中・面接後のさまざまなフェーズで気をつけるべきことを記しています。例としては、面接前のリクルータとのチャットにおいて、「希望給与額を言ってはいけないらしいです。これは将来の給料交渉が非常に難しくなるからです。「仕事の内容を詳しく理解したうえで考えたい」などと言っておけば大丈夫です。何も知らないとつい言ってしまいそうで、損をする可能性もありそうですね。
また、アメリカの面接も日本と同様で、応募する側も面接官を見極めるスタンスは一緒です。面接の最後では、たいていこちら側に質問があるか聞かれます。ここでする質問は自分の就職の軸や会社に求めることによって変わると思うのですが、本で紹介されていた1つの質問が日本では考えられないなと思ったので紹介しておきます。それは、「ほかにもいい会社はたくさんありますが、なぜ私はこの会社を選ぶべきなのでしょうか」です。日本では通常会社側がする質問ですが、アメリカの面接では応募する側がするのですね。この質問の背景には別のコンテキストがあるのかもしれませんが、日本の面接ではまずしない質問で驚きました。
さらに著者はソフトウェアエンジニアなので、面接で実施されるホワイトボードコーディングについても詳細に記されていました。ソフトウェアエンジニアの方は読んでみるとよいかもしれません。

人の流動性や解雇について

シリコンバレーでの1つの会社の平均勤続年数は2〜3年で、転職を繰り返しキャリアアップをするのが普通です。人の流動性が高く、みな「良い環境」「良い給料」「良い仕事内容」などさまざまな理由で転職します。そしてたいていの会社は、一度面接が失敗しても、半年から1年経てば再チャレンジを認めており、会社側も人を受け入れる体制があります。この本の第6章では、シリコンバレーでエンジニアキャリアを歩むために必要な知識や気をつけるべきことがまとめられていました。それらの中には日本でエンジニアキャリアを歩む人にもためになる内容もあります。例えば以下のような内容です。

  • 「できること」よりも「やりたいこと」
  • 転職のタイミングは自分よりも周りの状況がカギ
  • 迷ったら難しいポジションを選ぶ
  • 仕事の内容も環境も大事
  • 大企業とスタートアップでできること・できないこと
  • 日本人として働くことのメリット・デメリット
  • マネジメント系と技術系のキャリアトラックがある

日本のWeb系企業に勤めている私からみると、シリコンバレーにはエンジニアとして働く環境が整っていると感じざるを得ませんでした。ただ実際に働いていないので、働く環境なら日本のWeb系企業もあまりひけを取らないなという印象もいだきました。

人の流動性が高いというのは、自分の望み通りの転職ができるというわけではありません。会社に解雇されることも十分にあります。
解雇には大きく2種類あって、悪い解雇の「ファイア」と、必ずしも悪いとは言えない「レイオフ」があります。基本的にファイアは、違法行為や社内規則違反など「従業員側に非があった場合の解雇」です。ただし、パフォーマンス不足もファイア扱いになってしまうそうです。ファイア扱いになってしまうと次の転職活動が大変になるので、パフォーマンス不足の場合は自主退職という形で辞めさせてくれる会社もあるそうです。
一方、レイオフ「会社に原因がある場合の解雇」です。これは経済状況悪化や事業方針の転換などさまざまな理由で起こり得ます。またファイアとは違ってある日突然レイオフされることも特徴です。著者もレイオフにあったことがあるので、レイオフへの対策はたくさん書かれていました。ここはとても生々しいというかリアルな話なのでぜひ読んでみて欲しいです。

まとめ

  • 「エンジニアとして世界の最前線で働く選択肢」を読んだ
  • 実際にシリコンバレーで日本人エンジニアとして10年以上も働いている人が書いた本なので、内容がとても細かくて状況をイメージしやすかった
  • シリコンバレーでエンジニアとして働いてみたいとうっすらとでも思っている人には一読してほしい本でした