garbagetown

個人の日記です

App Mesh と ECS のサンプルを試したら CloudFormation とシェルスクリプトや jq の知見が詰まっていて X-Ray も付いてきた話

Medium 記事にもなっている AWS App Mesh のサンプルを試してみたらいい内容だったので、備忘も兼ねて一年半ぶりにブログを書いてみます。

TL; DR

  • App Mesh のサンプルに多い EKS ではなく ECS
  • App Mesh だけでなく CloudFormation やシェルスクリプト、jq の使い方も学べる
  • X-Ray も学べる

以下、サンプルの内容に沿って紹介します。

Prerequisites

サンプルを試す前提条件は以下の通りです。

  • AWS CLI 1.16.124 以上をインストールしている
  • AWS CLI を default または名前付きのプロファイルで適切に設定している
  • EC2 インスタンスにログインする SSH キーペアを作っている
  • github.com/aws/aws-app-mesh-examples リポジトリをクローンしている
  • jq をインストールしている

Create the VPC and other core Infrastructure

まず以下の環境変数を指定してシェルスクリプトを実行し CloudFormation で VPC とサブネットを作るところから始めます。

  • AWS_PROFILE: AWS CLI のプロファイル
  • AWS_DEFAULT_REGION: リージョン
  • ENVIRONMENT_NAME: デモに使う環境の名前

このシェルスクリプトは基本的に aws cloudformation deploy を実行しているだけで難しいことはしていません。

#!/bin/bash

set -ex

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

aws --profile "${AWS_PROFILE}" --region "${AWS_DEFAULT_REGION}" \
    cloudformation deploy \
    --stack-name "${ENVIRONMENT_NAME}-vpc" \
    --capabilities CAPABILITY_IAM \
    --template-file "${DIR}/vpc.yaml" \
    --parameter-overrides \
    EnvironmentName="${ENVIRONMENT_NAME}"

ここで使っている CloudFormation テンプレートには、知っている人には当たり前でも知らない人やどう書いたらいいか迷っている人の参考になる知見が詰まっています。

例えば !Select!GetAZsアベイラビリティゾーンを指定したり、!Join ではなく !Sub と変数で文字列を組み上げたり

  PublicSubnet1: 
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      CidrBlock: !Ref PublicSubnet1CIDR
      MapPublicIpOnLaunch: true
      Tags: 
        - Key: Name 
          Value: !Sub ${EnvironmentName} Public Subnet (AZ1)

!DependsOn で依存するリソースの作成順序を制御したり

  NatGateway1EIP:
    Type: AWS::EC2::EIP
    DependsOn: InternetGatewayAttachment
    Properties: 
      Domain: vpc

!GetAtt で作成したリソースの属性を参照する方法も、通常はトライアンドエラーで覚えるものなので、このようなサンプルでショートカットして学べるのはとてもいいと思います。

  NatGateway1: 
    Type: AWS::EC2::NatGateway
    Properties: 
      AllocationId: !GetAtt NatGateway1EIP.AllocationId
      SubnetId: !Ref PublicSubnet1

クロススタック参照する Outputs の名前の付け方も地味に悩むので参考になります。

Outputs: 

  VPC: 
    Description: A reference to the created VPC
    Value: !Ref VPC
    Export: 
      Name: !Sub "${EnvironmentName}:VPC"

Create an App Mesh

先ほどと同様に環境変数に App Mesh の名前を指定してシェルスクリプトを実行します。

  • MESH_NAME: App Mesh の名前

ここでは AWS::AppMesh::Mesh リソースを作っているだけです。

Create compute resources

続いて ECS クラスターを作ります。

サービスディスカバリで使う Route 53 プライベートホストゾーンもここで作るので環境変数に指定します。

コンテナインスタンスは AutoScaling グループでプライベートサブネットに作成されますが、パブリックサブネットに踏み台インスタンスも作成されるので SSH キーペアも指定します。

  • SERVICES_DOMAIN: プライベートホストゾーン名
  • KEY_PAIR_NAME: SSH キーペア名

シェルスクリプトはこれまでと同じで CloudFormation スタックを作るだけです。

ここで使う CloudFormation テンプレートも参考になります。

コンテナインスタンスと踏み台インスタンスに使う AMI ID はパラメータストアから取得することができます。

  ECSAmi:
    Description: ECS AMI ID
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: "/aws/service/ecs/optimized-ami/amazon-linux/recommended/image_id"

  EC2Ami:
    Description: EC2 AMI ID
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"

Fn::ImportValue!Sub でクロススタック参照したり

  ECSInstancesSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupDescription: "Security group for the instances"
      VpcId:
        'Fn::ImportValue': !Sub "${EnvironmentName}:VPC"
...

AutoScalingGroup の UpdatePolicy 属性 もちゃんと指定しています。

  ECSAutoScalingGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
...
    UpdatePolicy:
      AutoScalingRollingUpdate:
        MinInstancesInService: 1
        MaxBatchSize: 1
        PauseTime: PT15M
        SuspendProcesses:
          - HealthCheck
          - ReplaceUnhealthy
          - AZRebalance
          - AlarmNotification
          - ScheduledActions
      WaitOnResourceSignals: true

UserData で SSM エージェントをインストールしているので、コンテナインスタンスにセッションマネージャで接続することもできます。

  ECSLaunchConfiguration:
    Type: AWS::AutoScaling::LaunchConfiguration
...
      UserData:
        "Fn::Base64": !Sub |
          #!/bin/bash
          yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
          yum install -y aws-cfn-bootstrap hibagent
          /opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource ECSLaunchConfiguration
          /opt/aws/bin/cfn-signal -e $? --region ${AWS::Region} --stack ${AWS::StackName} --resource ECSAutoScalingGroup
          /usr/bin/enable-ec2-spot-hibernation

UserData で指定するには複雑過ぎる設定は AWS::CloudFormation::Init リソースを使って指定します。

    Metadata:
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              awslogs: []

          commands:
            01_add_instance_to_cluster:
              command: !Sub echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config
          files:
            "/etc/cfn/cfn-hup.conf":
              mode: 000400
              owner: root
              group: root
...

Configure App Mesh resources

いよいよ本命の App Mesh を作ります。

シェルスクリプトはこれまでと同様で、

CloudFormation テンプレートで VirtualNode, VirtualRouter, Route, VirtualService を作ります。

バーチャルバーチャル言ってて何のこっちゃ分からんという感情が先行しますが、雰囲気が掴めてくるとたしかに仮想的なノードと、それに対するルートを提供するサービスだなあという気もしてきます。

自分はブログ記事 "Learning AWS App Mesh" の "DJ App revisited" の辺りを読んで腑に落ちた感じがしたので、もし未読の方は一読されるといいかもしれません。

Deploy services to ECS

ここまででネットワークインフラを作って ECS クラスタを作って App Mesh を作ったので、最後に実際に ECS サービスをデプロイします。

Deploy images to ECR for your account

まず AWS CLI で ECR を作ってコンテナイメージを push します。

これまでのシェルスクリプトとは毛色が違いますが、基本的に docker build して作った ECR に push しているだけです。

#!/usr/bin/env bash
# vim:syn=sh:ts=4:sw=4:et:ai

set -ex

if [ -z $COLOR_GATEWAY_IMAGE ]; then
    echo "COLOR_GATEWAY_IMAGE environment variable is not set"
    exit 1
fi

# build
docker build -t $COLOR_GATEWAY_IMAGE .

# push
if [ -z $AWS_PROFILE  ]; then
    $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
else
    $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION --profile $AWS_PROFILE)
fi
docker push $COLOR_GATEWAY_IMAGE

Dockerfile では真面目にマルチステージビルドしています。

FROM golang:1.10 AS builder

# Download and install the latest release of dep
ADD https://github.com/golang/dep/releases/download/v0.4.1/dep-linux-amd64 /usr/bin/dep
RUN chmod +x /usr/bin/dep

# Copy the code from the host and compile it
WORKDIR $GOPATH/src/github.com/username/repo
COPY Gopkg.toml Gopkg.lock ./
RUN dep ensure --vendor-only
COPY . ./
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix nocgo -o /app .

FROM scratch
COPY --from=builder /app ./
ENTRYPOINT ["./app"]

バックエンドサービスを build して push するシェルスクリプト、Dockerfile も同じ内容です。

Deploy gateway and colorteller services

環境変数に最新の Envoy コンテナイメージと先ほど ECR に push したコンテナイメージを指定したら、シェルスクリプトを実行して ECS サービスをデプロイします。

  • ENVOY_IMAGE: 最新の Envoy コンテナイメージ。現時点では v1.9.1.0-prod が最新
  • COLOR_GATEWAY_IMAGE: ゲートウェイサービスのコンテナイメージ
  • COLOR_TELLER_IMAGE: バックエンドサービスのコンテナイメージ

シェルスクリプトは今まで変わり映えしないように見えますが、create-task-defs.sh を呼び出している点が異なります。

#!/bin/bash
...
# Creating Task Definitions
source ${DIR}/create-task-defs.sh

aws --profile "${AWS_PROFILE}" --region "${AWS_DEFAULT_REGION}" \
    cloudformation deploy \
    --stack-name "${ENVIRONMENT_NAME}-ecs-colorapp" \
...

このシェルスクリプトでは AWS CLI と jq をうまく使ってタスク定義を登録していました。

describe-stacks の結果を jq でパースして必要な値を取得したら

stack_output=$(aws --profile "${AWS_PROFILE}" --region "${AWS_DEFAULT_REGION}" \
    cloudformation describe-stacks --stack-name "${ENVIRONMENT_NAME}-ecs-cluster" \
    | jq '.Stacks[].Outputs[]')

task_role_arn=($(echo $stack_output \
    | jq -r 'select(.OutputKey == "TaskIamRoleArn") | .OutputValue'))

execution_role_arn=($(echo $stack_output \
    | jq -r 'select(.OutputKey == "TaskExecutionIamRoleArn") | .OutputValue'))
...

やはり jq の -f オプションで読み込んだテンプレートファイルに --arg--argjson オプションで変数の値を渡してタスク定義の入力となる JSON 文字列を組み上げ、AWS CLI でタスク定義を登録しています。

generate_color_teller_task_def() {
    color=$1
    task_def_json=$(jq -n \
    --arg NAME "$ENVIRONMENT_NAME-ColorTeller-${color}" \
    --arg STAGE "$APPMESH_STAGE" \
    --arg COLOR "${color}" \
    --arg APP_IMAGE $COLOR_TELLER_IMAGE \
    --arg AWS_REGION $AWS_DEFAULT_REGION \
    --arg ECS_SERVICE_LOG_GROUP $ecs_service_log_group \
    --arg AWS_LOG_STREAM_PREFIX_APP "colorteller-${color}-app" \
    --arg TASK_ROLE_ARN $task_role_arn \
    --arg EXECUTION_ROLE_ARN $execution_role_arn \
    --argjson ENVOY_CONTAINER_JSON "${envoy_container_json}" \
    --argjson XRAY_CONTAINER_JSON "${xray_container_json}" \
    -f "${DIR}/colorteller-base-task-def.json")
    task_def=$(aws --profile "${AWS_PROFILE}" --region "${AWS_DEFAULT_REGION}" \
    ecs register-task-definition \
    --cli-input-json "$task_def_json")
}

CloudFormation テンプレートでは登録したタスク定義を使用するサービスおよびサービスディスカバリレコード、そしてゲートウェイサービスにリクエストをフォワードする ALB を作ります。

その他にテスト用と思われるサービスやサービスディスカバリレコードも作っていますが本質ではないので割愛。

作成した ALB のエンドポイントに curl でリクエストを送ると App Mesh によってルーティングされたいずれかの ECS サービスから応答が得られます。

$ colorapp=$(aws cloudformation describe-stacks --stack-name=$ENVIRONMENT_NAME-ecs-colorapp --query="Stacks[0
].Outputs[?OutputKey=='ColorAppEndpoint'].OutputValue" --output=text); echo $colorapp
http://DEMO-Publi-M7WJ5RU13M0T-553915040.us-west-2.elb.amazonaws.com

$ curl $colorapp/color
{"color":"red", "stats": {"red":1}}

Shape traffic

Apply traffic rules

作成した CloudFormation スタックに含まれる AWS::AppMesh::Route リソースの WeightedTargets を変更して CloudFormation スタックを更新することで、App Mesh のルーティング情報を変更できます。

また、App Mesh コンソールで対象の Virtual routes を Edit して Virtual nodes の Weight を変更することでもルーティング情報を変更できます。

Monitor with AWS X-Ray

Envoy コンテナで X-Ray 統合が有効に設定されていて、かつ各サービス内で稼働する Go アプリケーションにも X-Ray SDK が設定されているので、X-Ray サービスマップからVirtualNode を経由して各アプリケーションにアクセスしている様子を確認できます。

各トレースをドリルダウンすることで詳細な内訳を確認できます。

まとめ

ちょっと App Mesh やってみようかなと軽い気持ちで手を出したサンプルから予想を大きく上回る収穫が得られて満足です。気になった方は是非お試しください。

15 年勤めた SIer を辞めて外資系企業に転職した話

この記事は 退職者その2 Advent Calendar 2017 の二日目です。

adventar.org

おことわり

現職に就いて間もない試用期間中の身であるため、現職に関しては表面的な内容しか書けません。

そのため、「なぜ現職に就いたのか」というポジティブな側面よりも「なぜ前職を辞めたのか」というネガティブな側面を強く感じられる方がいらっしゃるかもしれませんが、いわゆる一身上の都合であり、前職や SIer というビジネスを否定するものではありません。

予めご了承ください。

前職について

大手と言って差し支えない規模の SIer に新卒として入社して 15 年と 1 ヶ月間、システムエンジニアとして勤めました。

Java 言語を使った Web アプリケショーン開発を多く担当し、直近の数年間は Hadoop, Azure, AWS なども経験できました。中国やタイへの出張、社内勉強会の開催など、システム開発以外にも多くの経験を積ませて頂きました。

大規模企業としての安定感は抜群で、業界平均以上の待遇に加えて技術職への理解と手当てもある良い企業でした。

お世話になった方々にこの場を借りて改めて御礼を申し上げます。本当にありがとうございました。

転職の動機

瑣末な理由も当然いくつかあったものの、次の二点が大きな理由でした。

  • 家族が増えた
  • 組織に広く貢献したくなった

それぞれ微妙に関連しますが、以下、個別に詳述します。

家族が増えた

今年で五歳になる娘が家族に加わってから、生活が一変しました。

個人という観点では見るもの聞くものすべてが新鮮で、目まぐるしくも充実した日々ですが、会社員という観点では単純に労働時間が減りました。

前職では準委任契約という形態でお客様先に常駐してお仕事させて頂く機会が多くありましたが、この契約は大雑把に言うと労働時間に対して対価を頂く内容であり、労働時間の減少は売上に影響します。

個人の事情を相互にフォローするのが組織ですし、お客様も含め現場の方々は理解を示してくださいましたが、ビジネスモデルとライフスタイルのミスマッチが根本的に解消されるわけではありませんでした。

組織に広く貢献したくなった

会社員として経験を積むにつれて、関心の対象が個人からチーム、組織へと移っていきました。

最初の五年間は個人として技術を身に付けることに夢中で、チームや組織のことは考えもしませんでした。

次の五年間はチームリーダーとして案件を成功させるために躍起になっていましたが、リーダー以前に個人としてあまりにも未熟で、メンバーに迷惑をかけてばかりでした。

そして、チームリーダーとして少しずつ上手く立ち回れるようになった最後の五年間は、自分が身に付けたことを他のチームや部署にも展開したい、自分の価値をスケールしたいと考えるようになりました。

そこで R&D 等を担当する部署への異動を希望しましたが、(ありがたいことに) 自分を必要としてくれる現場もあってなかなか認められず、仕方なく社内 SNS に技術情報を展開したり、社内勉強会を開催したりなど試みるものの、組織に広く貢献できているという実感を強く得ることはできませんでした。

転職の契機

今年の三月に念願が叶って R&D 等を担当する部署へ異動した数ヶ月後、現職よりスカウトのメールを頂きました。

登壇資料やブログを見てお声掛け頂いたとのことで、拙いながらも情報発信を続けていてよかったと思います。また LinkedIn もご覧になったとのことで、外資系企業らしいとも思いました。

当初は異動したばかりということもあり転職するつもりはありませんでしたが、他の企業がどのようにビジネスをしているのか、エンジニアがその中でどのように活躍しているのかなど、お話を聞きたいと思って面接を受けることにしました。

その面接で、現職には以下のような特徴があることを理解しました。

  • エンジニアが能力を発揮して短時間で問題を解決することが組織への貢献となること
  • 常に新しい技術を学び続けることが求められること

本質的ではありませんが、日常的に英語に触れる機会があることにも魅力を感じ、この企業で働きたいと思うようになりました。

転職した感想

前述の通り試用期間中であるため表面的ではありますが、実際に転職した感想を以下に列挙します。

エンジニアの質が高い

技術力が高いのはもちろんですが、強い言葉やネガティブな言葉を使うエンジニアがいません。みなさんコミュニケーション能力が高く、ポジティブで親切です。

企業文化がきちんと浸透していて、人間的にとても洗練されています。

オフィスが快適

広いデスクにラップトップとサブディスプレイを二枚貸与して頂いています。ラップトップは Win/Mac, JIS/US キーボードから選べて、自分は JIS キーボードの MacBook Pro を使っています。

服装規定は一切ありません。コーヒーなどの簡易な飲み物は無料です。人によって好みがあるかと思いますが、オフィスがとても静かなのも個人的には快適です。

なお、自宅で働いている人も多いです。

トレーニングが充実

入社してから一ヶ月経ちますが、ひたすらトレーニングしています。e ラーニングとエキスパートによるラボトレーニングの予定がびっしりで、トレーニングにここまでコストをかけてくれるのかと驚きました。

トレーニングした内容よりも更に深く知りたい場合は、社内 Wiki に大量の情報が蓄積されています。

英語が身近

会話は日本語ですが、上記トレーニング教材や Wiki はほとんど英語です。

今はまだ読むだけですが、トレーニングを終えて実務に移ると海外のエンジニアとメールでやり取りする機会もあるそうですし、エキスパートは海外出張の機会も多いようです。海外へ転籍していく方も多いです。

最後に

転職して本当によかったと思います。

単純に環境や待遇が改善されたこともありますが、仕事のこと、家族のこと、自分のことを改めて考え直して行動したこと、また実際にまったく違う世界を目の当たりにしたことで、視野が広がり、人間的に幅が出たように感じます。

今はまだ組織にぶら下がっているだけの新人ですが、一日でも早く成長して組織に貢献していきたいと思います。

JJUG CCC 2017 Fall に登壇しました #jjug_ccc #ccc_a1

JJUG CCC でお話ししてきました!

www.java-users.jp

2017 Spring に続いて二回目。前回よりはリラックスできたかなー。

発表資料はこちら。

p キーを押すとスピーカーノートが表示されます。当日はピンマイクでうろうろしながらスピーカーノートを見ずにお話ししたので、お伝えし忘れたことがぽろぽろありました。反省。

資料中で紹介している gradle プロジェクトも以下にアップロードしました。

github.com

登壇の経緯

業務ドキュメントの作成について、以下のような課題を感じていました。

  • バイナリフォーマットとバージョン管理ツールの相性が悪い
  • いつ、なにを、どのように書けばよいのか、いまいちよく分からない
  • レビューがうまく機能していない気がする

いつ、なにを書くべきなのかについては、システムエンジニア Advent Calendar 2016 に書きました。

この頃は Markdown でドキュメントを書けないかと考えていたのですが、その後に参画した案件で採用した AsciiDoc と PlantUML に手応えを感じたので、この成果を共有したいと考え、関係各位の了承を得た上で CfP に応募しました。

KPT

以下、振り返り。

Ask the Speaker

以下、登壇後に頂いたご質問など。

日本語でセクションタイトルを書いても自動生成される id は問題ないか

実際の案件でも日本語でセクションタイトルを書きましたが、特にハマったことはないです。自動生成 id でハマったのは以下の二件。

  • 予期しない記号がアンダースコアに置き換えられた
  • セクションタイトルが重複して連番が付与された

いずれもビルド後の HTML ソースから自動生成された id を確認して解決しました。事前にカスタム id の付与ルールを検討するのもよいと思います。

Table セルを改行して記述した場合、列数はどのように判定されるのか

|A |B |C |D と書けば 1 行 4 列であることは明白ですが、B や C の後に改行すると列数が分からなくなるのでは?という鋭いご質問ですね。

[cols="xx,yy,zz"] のように明示しない場合、一行目の列数で判定されるようです。

実際の案件では以下のルールで記述しました。

  • [cols="xx,yy,zz", options="header"] の指定必須
  • 列ごとに改行
  • 行ごとに空行を挿入

GitLab CI を使えば Jenkins は不要では?

GitLab CI が登場するより前から利用している docker-compose を再利用したため、GitLab と Jenkins を組み合わせて利用しています。

新規に構築する場合は GitLab CI でもよいと思います。

まとめ

今回も登壇駆動勉強が捗りました...

また、資料を書き進めていくにつれて「あのときこういう言い方をしたからみんな受け入れてくれたんだなー」という気付きを得られたのが個人的に大きな収穫でした。

拝聴した各セッションや全体の感想は別途投稿します。

朝一番のセッションにも関わらずお越しいただいた方々、スタッフの方々、某案件でお世話になった方々、お忙しい中レビューしてくださったくらもとパイセン、本当にありがとうございました!

babun に awscli をインストールする

お仕事で AWS を使い始めたので、コマンドラインから AWS のサービスを操作する AWS Command Line Interface (AWS CLI) をインストールしてみた。

OS ネイティブなターミナルを使っている場合は AWS Command Line Interface のインストール やネットに手順が載っているので、それらを参照すればよいですが、自分は大人の事情で Windows7 上で Babun を使っており、ここに AWS CLI をインストールしたので手順をメモっておきます。

pip のインストー

AWS CLIPython 製のようで、Pyhon のパッケージ管理システムである pip を使ってインストールできるとのこと。

Babun にはデフォルトで Python は入っているものの、pip は入っていないので、まず pip をインストールする必要がある。

$ which pip
pip not found

で、pip は python-setuptools に含まれる easy_install でインストールするらしく、この python-setuptools は Babun のパッケージ管理システムである pact でインストールできる。

$ pact find python-setuptools
(snip)
Searching for installed packages matching python-setuptools:

Searching for installable packages matching python-setuptools:
python-setuptools

$ pact install python-setuptools
(snip)
Package python-setuptools installed

自分の環境では末尾に Python のバージョン番号が付与された状態で easy_install がインストールされた。

$ which easy_install-2.7
/usr/bin/easy_install-2.7

このままでは扱いづらいのでエイリアスを設定する。

$ echo "alias easy_install='easy_install-2.7'" >> ~/.zshrc

$ tail -5 ~/.zshrc
#
# Example aliases
# alias zshconfig="mate ~/.zshrc"
# alias ohmyzsh="mate ~/.oh-my-zsh"
alias easy_install='easy_install-2.7'

$ source ~/.zshrc

$ which easy_install
easy_install: aliased to easy_install-2.7

$ easy_install --version
setuptools 34.3.2 from /usr/lib/python2.7/site-packages (Python 2.7)

easy_install で pip をインストールする。

$ easy_install pip
(snip)
Installed /usr/lib/python2.7/site-packages/pip-9.0.1-py2.7.egg
Processing dependencies for pip
Finished processing dependencies for pip

$ pip --version
pip 9.0.1 from /usr/lib/python2.7/site-packages/pip-9.0.1-py2.7.egg (python 2.7)

awscli のインストー

これでようやくお目当ての AWS CLI をインストールできる。

$ pip install awscli
(snip)
Successfully installed PyYAML-3.12 awscli-1.11.123 botocore-1.5.86 colorama-0.3.7 docutils-0.13.1 futures-3.1.1 jmespath-0.9.3 pyasn1-0.2.3 python-dateutil-2.6.1 rsa-3.4.2 s3transfer-0.1.10

$ aws --version
aws-cli/1.11.123 Python/2.7.13 CYGWIN_NT-6.1-WOW/2.8.0(0.309/5/3) botocore/1.5.86

AWS クレデンシャルの設定

AWS に接続するためのクレデンシャル情報を以下のように設定する。

$ cat ~/.aws/credentials
[default]
aws_access_key_id = XXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXX

AWS CLI を使う

とりあえず S3 の中を見てみる。

$ aws s3 ls
2017-02-10 19:22:15 XXXXXXXXXXXXXXXXXXXX
2017-01-25 13:40:08 XXXXXXXXXXXXXXXXXXXX
2016-11-30 14:46:51 XXXXXXXXXXXXXXXXXXXX

hadoop fs ls のように結果が返ってくるまで突っかかる感じはあるものの、無事に S3 の中身が見られた。

Developers.IO 2017 に参加しました #cmdevio2017

クラスメソッドさんのカンファレンスイベント Developers.IO 2017 に行ってきました。

まったく関係ないけど、会場近辺は一昨年のビッグデータ案件で終電を逃しては缶ビール飲みながらタクシーを拾ったりしていた場所なので懐かしかったw

K-1History of AWS, Still Halfway through

基調講演は AWS 事業部部長の佐々木大輔 (@smokeymonkey) さん。

早速スライドとブログ (と言うかスクリプトと思われるw) が惜し気もなく公開されているので、そちらを参照。

個人的に自己紹介スライドが印象的でした。

  • AWS 事業部長
  • 北海道在住
  • AWS 認定資格・ダブルプロ
  • JFA 公認 C 級コーチ

と、技術力があり、しかし場所には縛られず、ワークライフバランスの充実度が感じられるクラスメソッドさんらしい一枚。

基調講演らしく力強い想いが溢れつつも、しっかりと市場を見定め、かつ確かな技術に裏付けされたすばらしいセッションでした。

ランチセッション

続いてお弁当を頂きながらランチセッション。

クラスメソッド代表の横田 (@sato_shi) さん。

いろいろとリアルな数字の載ったスライドだったので、さすがに公開されないのかな。

前半はこの 2〜3 年でクラスメソッドさんが急成長されていることがはっきりと見て取れる各種数字や、ワークライフバランスを重視した社風などについて、後半はこれからクラスメソッドさんが取り組まれていく VUI についてのお話でした。

佐々木さんの基調講演と同様、ビジョンとビジネスとテクノロジーのバランスがすばらしいなあと感じました。

全体的に非常にリラックスした雰囲気で、「このペースで話すと終わらないね」と時間を気にしつつも、しばしば司会進行役のマーケティング部長嵩原さんとの息の合ったノリツッコミや、いらすとやの話に脱線するのが印象的でしたw

【A-1】 クラメソの請求を支える技術(サーバーレス編)〜40歳中年エンジニアの生存戦略

午後イチは植木 (@czkuk) さん。サブタイトルに惹かれて拝聴w

現時点でスライドは公開されていないようですが、いずれ公開されると思いますので気になる方は http://dev.classmethod.jp/ をしつこくチェックしましょう。

タイトルの通り、急成長するクラスメソッドさんの請求システムを AWS Lambda で短期間に刷新したお話と、中堅エンジニアならでの視点についてのお話。

サーバレスというキーワードだけ切り取るとテクノロジー的にホットな内容を想像しますが、以前は半月掛かっていた請求処理コストをわずか数日にまで削減し、これによって浮いたコストで事務作業に付きっきりだった社員がエンジニアに転向することができたという、地に足の付いた内容でした。

クラウドネイティブな世代にとっては当たり前のことかもしれませんが、以前は自分たちで手を動かして構築・設定していたハードウェアやミドルウェアはどんどんサービスとして提供されており、これらを API でつなぎ合わせるだけでシステムが作れる時代になっているんだなあと再確認させられるセッションでした。

最後に「半径 5 メートルを幸せにする」ことが自分の生存政略とお話されており、不惑ならではの堂々たる安定感を感じました。

【A-2】 基礎からの OAuth 2.0 〜 認証と認可の概念、認可コードとアクセストークンの意味 〜

続いてなぜか変換できませんが、みやもと (@daisuke_m) さん。

スライドはこちら。

技術的な内容の分かりやすさはもちろんのこと、現実世界のメタファの使い方と話の組み立て方が抜群でした。

誰しもストーリーのしっかりした映画や小説、漫画などで「あそこで張った伏線がここで回収されるのか!」と膝を打った経験があるかと思いますが、あれと同じ感じです。とても勉強になりました。

あと、なんかスポットライトみたいにできるポインターが超かっこよかった。

↑これ。ほしい。けど高い。

あまり多用されていませんでしたが、リダイレクトが大量で超むずかしいインプリシットフロー、認可コードフローを説明するときこそスポットライトの機能を使うべきなんじゃ、って思いましたw

【F-3】 今さら聞けないAWSによる監視の世界

ここで 3 階に降りて菅野さん。ツイッタアカウントは非公開もしくは存在しない?

スライドは下記ブログから参照できます。

恥ずかしながら AWS のことはほとんど分からないド素人なので、とても分かり易かったです。

必ず失敗すると言われているデモもしっかりと成功されていました。デモ用 EC2 に cmdevio2017!!!!! というリクエストを送って 404 アラートメール飛ばさせたのは自分です。すみませんwww

【A-4】 Amazon Elasticsearch Service の使いドコロ

最後のセッションは 11 階に戻って藤本 (@a04316) さん。

スライドはこちら。渾身の 108 枚w

内容が盛り沢山で、タイトルには出てこない RDBMS による全文検索転置インデックス形態素解析などにも触れられており、肝心の Amazon Elasticsearch Service については駆け足な印象でした。

個人的には MySQL全文検索ができることや、Elasticsearch の内部構造などは知らなかったので、興味深く拝聴できましたが、この辺りはすっかりご存知で AWS ならではのお話を期待した方には物足りなかったかもしれないですね。

後ほど駆け抜けたスライドをゆっくり拝見しますw

【F-1】 Festivals.IO

参加者全員で会場設営に協力して懇親会。

飲み切れないほど大量のビール (プレミアムモルツ!) と、食べ切れないほどの食事、そしてなぜか光る棒が振る舞われました。

ぽきっと折ると光るようです。ツイッタで教えてくれた @opengl-8080 さん、ありがとうございました!

スポンサー各位の LT を拝聴しながらクラスメソッド社員数名の方とお話させて頂くことができました。お話しさせて頂いた方々、ありがとうございました!もっとたくさんの方とお話したかったですが、またの機会の楽しみにしたいと思います :-)

とても楽しかったです。クラスメソッドの皆さま、ありがとうございました!

#WEBエンジニア勉強会01 で発表しました

WEBエンジニア勉強会 #01 (東京都, 新橋) でお話してきました!

connpass.com

発表資料はこちら。

経緯

4 月中頃に知人の濱野 (@engineer_osca) さんから勉強会を開催するので時間があれば協力してほしいと連絡頂きました。開催は 6 月とのことだったので、5 月 20 日の JJUG CCC までは動けないけど、そのあとでよければ協力するよー、登壇でも LT でもなんでもやるよー、と安請け合いしてしまいました。懲りない人ですね。

資料は CCC のリプレイでいいかなーなんて思っていたのですが、開催趣旨をよくよく聞くと特定言語やフレームワークに依らない方が望ましい、枠も 30 分とのこと。スプリングブートの 50 分ものじゃだめですね。

運良く(悪く?) OAuth 2 についていろいろ調べながら四苦八苦していて、「OAuth 2 ってむずかしい…自分ならこう説明するのになあ」という想いが溜まっていたので、それを吐き出すことにしました。

目的

なかなか抽象度の高い勉強会タイトルだったので少々悩みましたが、以下を目的に設定しました。

  1. JJUG CCC の反省を活かすこと
  2. 聴講してくださった方が OAuth 2 を学ぶ際に自分と同じ遠回りをせずに済むようになること
  3. 新しい知り合いを増やすこと

1.については後述の KPT で。2.についてはアンケートがないので詳細は不明ですが、この辺りのツイートから察するにまずまず達成できたと思っていいのかな。

3.については、イベント後の懇親会などで数名と名刺交換してお話できたので良かったです。

KPT

以下、簡単に振り返り。

  • Keep
    • CCC でまとめたマスタースライドを使い回して作業を効率化できた。今後もマイナーチェンジはあると思うけど、飽きるまでは継続
    • CCC よりもまとめをしっかり書いたら締まりが良くなった。継続
    • 付録に参考資料を多数掲載したところ好評だった。継続
  • Problem
  • Try
    • 聴講者からもっと質問を引き出してみたい。Slido を使ってみる?

Ask the Speaker

以下、登壇後やアンケートなどで頂いたご意見に対する回答。って言っても 1 件のみですが。

悪意あるクライアントにアクセストークンを渡してしまったらどうなるの?

当然、認可された範囲内でリソースオーナーの意図しない操作を実行される可能性があります。トークンは合鍵のようなものなので、信頼できないクライアントに預けてはなりません。

とは言え、下記のとおり ID/パスワード を預けるよりは遥かに安全ですね。

  • くり返しだけど、クライアントは認可された範囲内の操作しか実行できない
    • ID/パスワードを預けた場合、クライアントはやりたい放題
    • クライアントにパスワードを変更された場合、リソースオーナーはどうすることもできない
  • 認可サーバに連絡して当該クライアントに発行したアクセストークンを無効化できる
    • Twitter で言えば、アプリ連携を解除する
    • リソースオーナーが特定のクライアントのトークンを無効化する仕様は RFC 化されていない (と思う)
    • クライアントが特定のリソースオーナーのトークンを無効化する仕様は RFC 7009 で定められている
  • (認可サーバがアクセストークンのリフレッシュを自動処理しない場合) トークンの有効期限が切れれば使えなくなる

トークンのリフレッシュや無効化は時間の関係上、説明できなかったので、とても良い質問だなと思いました。

感想

今回の感想はこれに尽きます。

なんとなく分かった気になってスライドを書いて、RFC を読み返して間違いに気付いてスライドを直して、のくり返しでした。

発表の機会がなかったらここまでしつこく RFC を読み直さなかったと思います。貴重な機会をくださった濱野さん、ありがとうございました!

あとは、これですね…

16GB MacBook ProIntelliJ IDEA Ultimate をご用意頂ける企業様からのお声掛けをお待ちしております…

JJUG CCC 2017 Spring に参加しました #jjug_ccc

ずいぶん日が経ってしまいましたが拝聴したセッションの感想を書き留めておきます。

Vue.js + Spring Bootで楽しくフルスタック開発やってみた

うらがみさん。

フロントエンドの知識が皆無なので、後日検索するキーワードを拾い集めるくらいの低い意識で拝聴。あとで調べようと思った (けどまだ調べてない…) キーワードは

  • Cordova
  • vue-router 2
  • Vuex
  • axios

など。webpack もなんとなくしか分かってない。で、こんなこと思った。

Gradle, Doma2, Vue はマイナーだったり開発リソースの弱さが気になって距離を置いていたんだけど、尊敬するエンジニアの皆さんが声を揃えて推すのでちょっと考え方を改めようかと。イミュータブル、バリューオブジェクトを多用するのも興味あり。

最後にデザパタの話。むかし Swing をいじっていたこともあって Observer パターンが超重要なのは納得だったけど、Visitor パターンと型とパターンマッチングの話に付いていけなくて “???” と思っていたら、うらがみさんがすでにブログに書いていた。Brian Goetz の Java にパターンマッチ入れるとしたらこんな感じ?という記事にも同じことが書いてあって、すごく勉強になった。

データ履歴管理のためのテンポラルデータモデルとReladomoの紹介

FOLIO の伊藤さん。転職おめでとうございます!ドラム関連のツイートにいつも fav くださってありがとうございますw

履歴データのモデリングについて、よくあるパターンを丁寧に説明してくださって、とても分かり易かった。パターンに名前を付けるの重要ですね。

で、バイテンポラルデータモデルをネイティブにサポートする Reladomo (レラドモ) の紹介。XML によるエンティティ定義、ジェネレーションギャップパターンを考慮したコード生成という説明に会場がざわついていた (ように感じた)w

分かり易さと発表時間の関係だと思うけど、導入部分のみの説明だったので、この辺を疑問に感じた。

Q&A や懇親会で聞いた話では表の結合も考慮されているとのこと。シャーディングもサポートしているようなので、履歴をシャードに追い出せば性能も出るのかな。

Eclipse Collection と同様、Kata があるのでやってみようと思った (まだやってない…)。

ヤフーの広告レポートシステムをSpring Cloud Stream化するまで

塩野さんと橋本さん。懇親会でたくさんお話しさせて頂いてありがとうございました!共通の知り合いがいることも判明したので、いつかご一緒できるといいですねー。

各世代のアーキテクチャと問題点、それを次世代のアーキテクチャでどのように解決していったのか、という歴史の紹介が興味深かった。

歴史と言っても第一世代は 2014 年の話で、わずか 3 年で規模もアーキテクチャもこんなに変わるのか・・・と唖然とするばかり。ビジネスがちゃんと成長して、成長に伴って解決しなければいけない課題が発生して、その課題をエンジニアリングで解決して、って理想的な環境だなーと思ったり、夜中に叩き起こされる毎日もつらいなーと思ったり ^^;

MQ を挟んだストリーム処理は MQ を死守しなきゃいけないんだけど、その辺どうしているのか説明がなかったのでセッション後に質問。

ちょっとやそっとでは落ちないことが分かったのが大収穫。こういう実績のお話を聴けるのがカンファレンスの醍醐味ですね :-)

Javaで実装して学ぶOAuth 2.0!

多田さん。連続登壇記録を伸ばし続けていて本当にすごい。

Spring で実装するとセッションが Spring だらけになるので意地で Java EE で実装したという漢気には誰もが惚れたと思う。あと、合間に挟んでくる CM の面白さとデモ失敗のほうがみんなの記憶に残ってしまったようなw

個人的に OAuth 2 をそこそこ勉強した状態で拝聴したので、とくに OLTU による実装の部分はとても面白かったんだけど、ほぼ無知、あるいは OAuth 2 ってトークン使って認可するアレだよねーくらいの知識だと、ちょっと厳しかったんじゃないかなーと思った。

ここでの経験が後日の自分の発表につながるのですが、それはまた別ポストで。

Java8プログラミング ベストプラクティス & きしだが働いてるかどうかIDEのメモリ使用状況から機械学習で判定する

きしださん。メガネかけているの初めて拝見したような気がする。かっこいい!

離散ウェーブレット変換とか循環ニューラルネットワークとか何も分からないんだけど、きしださん独特の声と話し方で説明して頂くとまったく怖くなくて、むしろ面白いのがきしださんのすごいところだと思う。挙句、オチがロマンだったり、ちゃんと働けだったりw

コーディングプラクティスは Java 8 オンリーかと思いきや Java 7 以前のものもそれなりに。ラムダで例外処理はあきらめていいんだ、って割り切れたのが収穫。

この辺りから体力の限界が迫っており当日のツイートも少なめ・・・

あと斜め前の席でやんくさんがばりばりスライドを書いているのが気になったw

VMの歩む道。Dalvik、ART、そしてJava VM

最後はやんくさん。

体力の限界と VM 知識の不足で聞いているだけになってしまったけど、そもそもなぜ Android は独自に VM を作ったのか、Oracle JVM とは何が違うのか、など分かり易く説明していただいて面白かった!こういう完全に専門外の話が聴けるのもカンファレンスの面白いところですね :-)

裏番組でおそらくここと同じくらい分からんセッションをされていた @tan_go238 さんがバイナリに足を踏み込んだ経緯は以前に伺ったことがあるんだけど、やんくさんはなぜこの道に踏み込んだんだろう?と思った (けど訊いてないので今度いつか機会があったら訊いてみよう) ←訊かないパターン

懇親会

で、懇親会。LINE 寿司がめちゃくちゃおいしかった。LINE さん、ありがとうございました!

登壇効果もあったのか、初めての方とも沢山お話しすることができてこれまでの懇親会で一番楽しかったと思います。ご挨拶させて頂いたみなさん、本当にありがとうございました!

自分は人のお名前とお顔を覚えるのが苦手で、頂いた名刺にはどなただったかメモった付箋を貼ったりしているのですが、せめてお相手にはそんな苦労をかけたくないと思ってツイッターアイコンのシールを用意してみたところ、なかなか好評だった。今後も続けよう。

今回は PRINTAIL というサービスを使ってみました。1,000 円前後とお手軽なので、気になった方は試してみてください。

二次会

で、二次会。バイナリ部屋に押し込められたこざけさんがしょんぼりしていたのが面白かったw

あときの子さんがヒーローの存在に気付いてなかったりw

と言うわけで登壇から二次会までとても楽しい一日でした。また次回もよろしくお願いします!