sitateru tech blog: AWS

sitateru tech blog

シタテルの技術やエンジニアの取り組みを紹介するテックブログです。

ラベル AWS の投稿を表示しています。 すべての投稿を表示
ラベル AWS の投稿を表示しています。 すべての投稿を表示

2019年2月21日木曜日

Alexaスキルを作ろう - 第2回

2月 21, 2019
こんにちは。シタテルでエンジニアをしている熊谷です。

SPECというサービスのバックエンド開発などを行っています。

今回は前回の続きで、Alexaスキルの作成について書いていきます。


今回は、前回作成したスキルから呼び出されるLambdaを作成します。

まずAWSコンソールにログインして、Lambda - 関数の作成に行きます。

そこから「一から作成」、「設計図」などが選べます。

「設計図」でalexaを検索すると、
それぞれのスキルタイプに合わせたsdkが用意されています。
使用したいタイプのsdkがある場合は、それを使用しましょう。

今回はとても単純なスキルを作成したので、「一から作成」を選択します。
いろいろな言語が選べますが、今回はNode.jsで作成しました。

関数を作成すると、シンプルなレスポンスを返す関数が書かれているので、その中身を変更します。

今回作成したスキルは、「言葉を逆さまにする」です。
シンプル...!

コードを記述します。

exports.handler = async (event) => {
  const word = event.request.intent.slots.word.value;
  const response = {
    "version": "1.0",
    "response": {
      "outputSpeech": {
        "type": "PlainText",
        "text": word.split('').reverse().join('')
      },
      "shouldEndSession": false
    },
    "sessionAttributes": {}
  };
  return response;
};

こんな感じになりました。

responseの形式について、詳しくは応答の形式を参考にしてください。
「intent.slots.word」の部分の「word」は前回設定した「スロット名」に対応します。

次にこのLambdaを呼び出すトリガーを設定します。

「トリガーの追加」から、「Alexa Skills Kit」を選択して、スキルID(alexa developer consoleを参照)を設定します。

alexa developer consoleでテストしてみましょう。

前回、スキルの呼び出し名とサンプル発話を設定しました。

テスト画面で、

「<スキルの呼び出し名>を開いて、<サンプル発話>おはよう」と入力すると‥


ちゃんと逆さまにして返してくれましたね!

シンプルなスキルですが動くと面白いと思います。


今回はここまでにします。

次回は実機でのテストとスキルの公開について書ければと思います。

ありがとうございました!

2018年12月25日火曜日

[第一回]SansanとHubSpotの連携

12月 25, 2018

こんにちは、シタテルエンジニアの工です!
今回は、SansanとHubSpotの連携の仕方について書いていきます 🚀

はじめに

シタテルでは、衣服生産をSCS、マーケティング・営業の部分をHubSpotを使って管理しています。

HubSpotを導入する際に、Sansanの情報をHubSpotに同期したいという要望があったので、SansanのAPIとHubSpotのAPIを組み合わせて同期処理を実装しました。

AWSLambdaを使って、定期的に同期処理を実行しています。

HubSpot公式にもSansanとハブスポットの連携の仕方という記事も公開されていますので参考にしてみてください。

Sansanの名刺情報をHubSpotにインポートする

使うもの

余談ですが実装したときAWSLambdaにはRubyの選択肢がなかったのですが、今は使用できるみたいですね。
普段はRubyを使うことが多いので、次にLambdaを使うときはRubyで実装してみたいです。

Sansanの情報を取得

公式ドキュメント Sansan Open API

handler.js

const axios = require('axios')
const moment = require('moment')
axios.defaults.headers.common['X-Sansan-Api-Key'] = process.env.SANSAN_API_KEY
axios.defaults.headers.get['Content-Type'] = 'application/json'

module.exports.importSansanData= async (event, context, callback) => {
  var updatedFrom = moment().subtract(2, 'hours').format("YYYY-MM-DDTHH:mm:ss")+"Z"
  var updatedTo = moment().format("YYYY-MM-DDTHH:mm:ss")+"Z"

  await axios.get(`https://api.sansan.com/v2.0/bizCards?updatedFrom=${updatedFrom}&updatedTo=${updatedTo}&range=all`)
      .then(function (response) {
        importHubspot(response)
        callback(null, response.data)
      })
      .catch(function (error) {
        callback(error)
      });
};

詳しくはこのあたりを参考にしてください。
AWSLambdaとServerlessを使ってみる[第1回]
AWSLambdaとServerlessを使ってみる[第2回]

日時取得のところがとてもブサイクです... 😢
なぜかタイムゾーンZにしないとうまくいかなっかった 🤔
本当は+09:00に設定したい。

var updatedFrom = moment().subtract(2, 'hours').format("YYYY-MM-DDTHH:mm:ss")+"Z"
var updatedTo = moment().format("YYYY-MM-DDTHH:mm:ss")+"Z"

HubSpotにインポート

取得したSansanデータをインポート。
propertyは数が多いのでほとんど割愛して記載します。

公式ドキュメント HubSpot Developers

handler.js

function importHubspot (response) {
  response.data.data.forEach(createContact)
}

function createContact (value, index) {
  var properties = [
      {
        property: 'email',
        value: value.email
      },
      {
        property: 'firstname',
        value: value.firstName
      },
      {
        property: 'lastname',
        value: value.lastName
      }
    ]

  axios.post(`https://api.hubapi.com/contacts/v1/contact?hapikey=${process.env.HUBSPOT_API_KEY}`, {
    properties: properties,
  })
  .then(function (response) {
    console.log(response.data)
  })
  .catch(function (error) {
    console.error(error.response.data)
  });
}

上の例はひとつひとつPOSTしていますが、こちらのAPI使えば1回のPOSTでまとめてCreateできます。
Create or update a group of contacts | Contacts API

CloudWatchでスケジュールを設定

serverless.ymlにスケジュールを設定します。
2時間おきにインポート 🚀

serverless.yml

functions:
  importSansanData:
    handler: handler.importSansanData
    events:
      - schedule: cron(0 */2 * * ? *)

これで2時間おきに、Sansanの名刺情報がHubSpotのコンタクトに同期されます!👏

最後に、deploy 🚀

serverless deploy -v

まとめ

今回はSansanとHubSpotのAPIを使って、Sansanの名刺情報をHubSpotのコンタクトにインポートする方法について書きました。

SCSと外部サービスとの連携は今後もどんどん加速していくと思います!
マーケティング・営業 -> 衣服生産 -> 請求この流れがシステムでシームレスに実現できるように開発中です 💻

2018年12月21日金曜日

金沢で開催された IVS CTO Night & Day に参加してきました!

12月 21, 2018

こんにちは!
シタテル株式会社CTOの和泉です。

12月17〜19の3日間、金沢で開催された IVS CTO Night and Day 2018 Winter powered by AWS に参加してきました。

images/image1.jpg

どんな会なのか? 詳しくはこちら!
CTO Night and Day 2017
(リンク先は昨年のレポートです)

新旧大小さまざまな企業のCTOがずらり100人以上。

前夜祭に始まり、AWSの最新技術や文化紹介、選ばれた15社の技術やマネジメント紹介(登壇しました)、先輩CTOとの公開メンタリング、ダンスパーティーまで盛りだくさん。

「CTOがいなくなって8ヶ月がたった話」「CTOの休み方」など、CTOにまつわる、CTOならではの話題や悩み相談が随所で繰り広げられていました。

事業を進めていくのは本当にエネルギーが必要で、でも皆さん熱量高く真摯に取り組んでおられて本当に刺激になりました。

40名を超える方と名刺を交換して事業について意見交換させていただいて素晴らしい出会いがたくさんありました。

そして、本当にAWSの運営の方々のホスピタリティが半端ない!

私も事前に伝えていた事業内容に対してこの人が最適だろうという方を紹介いただいて、有意義なディスカッションが出来ました。

来年もできたら参加したい!頑張ろう!とめちゃくちゃテンションが上りました。

反省

話すのに忙しすぎて写真を全然撮っていませんでした、、、

2018年12月20日木曜日

プロジェクトごとに環境変数/クレデンシャルを管理する

12月 20, 2018

shell
unsplash-logoLauren Abrahall

sitateruでサービス・プロダクトを担当している北爪です。
インフラを見ることもあり、今日はShellでの環境変数の扱い方について書きます。

プロジェクトごとに環境変数/クレデンシャルを管理する

複数のプロジェクトに関わっているときに、プロジェクトごとの環境変数やAWSのkey/secretsなど環境変数に設定し管理する必要があることがあります。

Shellを使って管理する一つの方法を記述します。

準備

プロジェクトごとにクレデンシャルフェイルを作る

クレデンシャルファイル置き場を作ります

$ mkdir ~/.crds/

プロジェクトごとにプロジェクトファイルを作ったディレクトリ以下に置きます。
ディレクトリはinvisibleファイルにしておきます。

$ touch ~/.crds/pj-1

ファイルに必要なクレデンシャルを記述します

export AWS_ACCESS_KEY_ID==XXXXX
export AWS_SECRET_ACCESS_KEY==XXXXX
export AWS_DEFAULT_REGION=ap-northeast-1
export TF_VAR_secret_key=XXXXX
export TF_VAR_rds_password=XXXXX

読み込みと切り替え

設定した環境変数群を以下の方法でプロジェクトごとに読み込みます。
リセットはされないので、別プロジェクトに変える際は、あらたにshellを立ち上げるようにします。

プロジェクトのクレデンシャルを読み込む

source コマンドをつかってシェルに読み込めば(dot operatorでもOK)

$ source ~/.crds/pj-1

or

$ . .~/.crds/pj-1

別のプロジェクトのクレデンシャルを読み込む

複数のプロジェクトファイルを作ることで、クレデンシャルを別で読み込むことができます。

$ source ~/.crds/pj-2

Tips

初期読み込みが必要な場合は、 bashrcやzshrcなどに、読み込みコマンドを記述しておけます

まとめ

クレデンシャルファイルを特定のディレクトリに作り、基本コマンドで呼び出すだけです。一覧性も高く、管理しやすくなります。

2018年12月13日木曜日

ec2のインスタンスログインを簡単に管理する ~EC2 with Peco ~

12月 13, 2018

sitateruでサービス・プロダクトを担当している北爪です。
インフラを見ることもあり、ec2サーバーのアドレス管理についてCLIで行う方法を紹介します。

目的

ec2のインスタンスはアドレスが構築するたびに変わり、負荷や新しいプロジェクトが立ち上がると増えたり減ったりします。
そのため、動的にサーバーアドレスを取得する必要があります。

AWS consoleに入ることなく、awsコマンドからサーバーリストを取得し、CLI filterのpecoを使って、SSHまでおこないます。

使い方

peco
Command+\ でpecoを起動

filtered
やじるしの ↑↓ か、キーワードで絞る
SSHするサーバーを選んでEnterを押す

ssh
SSHコマンドがはかれる

準備

zshを使っているのを前提に説明します。

必要ソフトのインストール

  • peco をインストールする
  • aws cli をインストールする
  • AWSのクレデンシャルを用意する

Shellの設定

ec2 コマンドを作る

AWS CLIから、ec2をリスト化するコマンドを作成し、shellに設定します。(zshrc)

alias ec2="aws ec2 describe-instances --query 'Reservations[].Instances[].{PublicDnsName:PublicDnsName,InstanceId:InstanceId,Tags:Tags[?Key==\`Name\`].Value|[0],InstanceType:InstanceType,State:State.Name}' --output table"

peco-ec2コマンドを作る

  • zshrcpeco-ec2 をつくります
  • ログインユーザーをdeployにしています
function peco-ec2 () {
  local selected=$(ec2 | peco --query "$LBUFFER")
  if [ -n "$selected" ]; then
    BUFFER="ssh deploy@$(echo $selected | awk 'match($0, /ec2.*\.amazonaws\.com/) {print substr($0, RSTART, RLENGTH)}')"
    zle accept-line
  fi
  zle clear-screen
}
  • さらに、好きなキーにバインドします。
  • ここでは、Command-\ につけています
zle -N peco-ec2
bindkey '^\' peco-ec2

まとめ

ec2をリスト化し、すぐにそこからsshを選べるようにしました。

2018年12月12日水曜日

Alexaスキルを作ろう

12月 12, 2018

こんにちは。シタテルでエンジニアをしている熊谷です。

主にSPECというサービスのバックエンド開発(Rails)を行っています。

少し前にAlexaスキルの作成を試したので、その流れを簡単に説明していきます。

手順

1.Amazonアカウントを用意する

  • すでにamazon.co.jpの開発者アカウントがある場合は、それを使います。

  • お買い物用のAmazonアカウントを使用して、開発を開始できます。

  • Amazon Developerから、サインインして、情報を入力すると、開発用アカウントが登録されます。

    Amazon Developer

    ※ 画像のページで、ログインをして進みます。[Amazon Developerアカウントを作成]から進むと、amazon.com用のアカウントになってしまい、US向けのスキルになってしまうようです。

2.Alexa Developer Consoleにアクセス

3.[スキルの作成]をクリックし、スキル名などを入力する

スキルページ

4.スキルのページで、[呼び出し名]を設定する

5.エンドポイントを設定する

  • AWS Lambdaが推奨されているので、Lambdaでエンドポイントを作成するのが良いと思います。
  • リクエスト、レスポンスはJSON形式で送信します。
  • 作成したLambdaのARNを指定します。

6.インテントを作成する

  • [インテントを追加]をクリックし、カスタムインテントを作成します。

7.作成したインテントのページで、スキルの発話時に使用する、スロット(変数のようなもの)を設定する

  • スロットには、日付、数値、検索クエリー(文字列)などの型を指定できます

8.インテントを設定する

  • 作成したインテントの設定で、サンプル発話を登録します。
  • サンプル発話には上で作成したスロットを{スロット名}のような形で使用できます。

これで簡単なスキルを作成できました!

今回はざっくりした流れの紹介なので、ここまでにしたいと思います。

次回はLambdaの内容や、作成したスキルの公開、テストなどを説明していこうと思います。

2018年12月7日金曜日

CircleCIでAWS ECSに自動デプロイする(おまけで環境面の切り替えも)

12月 07, 2018

こんにちは、シタテルの茨木です。

今回はCircleCIでDockerをビルドし、そのままAWS ECR/ECSにデプロイする為の設定例を紹介します。

Nuxt.jsアプリ用に作ったものですが、言語やAPサーバが違っても共通の部分がほとんどです。

PRマージからの自動デプロイ、いいですよね。

https://circleci.com/docs/2.0/ecs-ecr/
https://github.com/CircleCI-Public/circleci-demo-aws-ecs-ecr

基本的にはCircleCI公式ガイドの上記リンクを参考にしていますが、元ネタはterraform前提だったりでなかなか大仰です。(下記に説明漏れがあったら原典を見てください…)

今回紹介するのはリンク先のスクリプト類を簡素化し、少し機能を追加(リポジトリ名からデプロイ先の環境面を切り替えできるように)したものです。

以下で省略しているけれど必要なモノ

  • ECS/ECRの設定

これだけで別の記事が書けてしまうので割愛します

ecsTaskExecutionRoleの割り当てとか忘れがちですかね

  • githubリポジトリ

言わずもがな。CircleCIとの接続設定はされているものとします

  • Dockerfile

リポジトリのルートに。Dockerfileの書き方は解説しません

  • requirements.txt

リポジトリのルートに。awscliを使えるようにします

https://github.com/CircleCI-Public/circleci-demo-aws-ecs-ecr/blob/master/requirements.txt

  • CircleCIの環境変数設定

github上にaccess_keyを晒さなくていいように、入れておきます

https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-project

この手順で設定した環境変数はCircleCIのジョブから参照できます

.circleci/config.yml:build

version: 2
jobs:
~省略~
  build:
    docker:
      - image: circleci/node:10-stretch
    steps:
      - checkout
      - setup_remote_docker
      - run:
          name: Setup common environment variables
          command: |
            echo 'export ECR_REPOSITORY_NAME="YOUR-ECR-REPO-NAME"' >> $BASH_ENV
            echo 'export FULL_IMAGE_NAME="${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/${ECR=REPOSITORY_NAME}:${CIRCLE_SHA1}"' >> $BASH_ENV
      - run:
          name: Build image
          command: |
            docker build -t $FULL_IMAGE_NAME .
      - run:
          name: Save image to an archive
          command: |
            mkdir docker-image
            docker save -o docker-image/image.tar $FULL_IMAGE_NAME
      - persist_to_workspace:
          root: .
          paths:
            - docker-image
~省略~

さっそくですがビルドジョブです。

  • YOUR-HOGEHOGE箇所はご自身のECS/ECRの設定に合わせて置き換えてください
  • - image: circleci/node:10-stretchnode:10を使っていますが、これはビルドする対象がNuxt.jsアプリだからですね。Dockerビルド時に必要なモノに合わせて修正してください

.circleci/config.yml:deploy

~省略~
  deploy:  
    docker:
      - image: circleci/python:3.6.1
    environment:
      AWS_DEFAULT_OUTPUT: json
    steps:
      - checkout
      - setup_remote_docker
      - attach_workspace:
          at: workspace
      - restore_cache:
          key: v1-{{ checksum "requirements.txt" }}
      - run:
          name: Install awscli
          command: |
            python3 -m venv venv
            . venv/bin/activate
            pip install -r requirements.txt
      - save_cache:
          key: v1-{{ checksum "requirements.txt" }}
          paths:
            - "venv"
      - run:
          name: Load image
          command: |
            docker load --input workspace/docker-image/image.tar
      - run:
          name: Setup target environment variables
          command: |
            echo 'export TARGET=`echo $CIRCLE_BRANCH | sed -e s/develop.*/dev/ -e s/release.*/stg/ -e s/master/prd/`' >> $BASH_ENV
            source $BASH_ENV
      - run:
          name: Setup common environment variables
          command: |
            echo 'export ECR_REPOSITORY_NAME="YOUR-ECR-REPO-NAME"' >> $BASH_ENV
            echo 'export ECS_CLUSTER_NAME="YOUR-ECS-CULSTER-NAME-PREFIX${TARGET}"' >> $BASH_ENV
            echo 'export ECS_SERVICE_NAME="YOUR-ECS-SERVICE-NAME-PREFIX${TARGET}"' >> $BASH_ENV
      - run:
          name: Push image
          command: |
            . venv/bin/activate
            eval $(aws ecr get-login --region ap-northeast-1 --no-include-email)
            docker push $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/$ECR_REPOSITORY_NAME:$CIRCLE_SHA1
      - run:
          name: Deploy
          command: |
            . venv/bin/activate
            export AWS_DEFAULT_REGION="ap-northeast-1"
            export ECS_TASK_FAMILY_NAME="YOUR-ECS-TASK-NAME-PREFIX${TARGET}"
            export ECS_CONTAINER_DEFINITION_NAME="YOUR-ECS-CONTAINER-DEF-NAME-PREFIX${TARGET}"
            export EXECUTION_ROLE_ARN="arn:aws:iam::$AWS_ACCOUNT_ID:role/ecsTaskExecutionRole"
            bash ./deploy.sh
~省略~

デプロイジョブです。

  • ブランチ名から環境名へ

echo 'export TARGET=`echo $CIRCLE_BRANCH | sed -e s/develop.*/dev/ -e s/release.*/stg/ -e s/master/prd/`' >> $BASH_ENV

ブランチ名に応じた値(developブランチなら"dev")を環境変数に入れています。これをsuffixとして使い、デプロイ先のクラスタ名等に反映しています

  • YOUR-HOGEHOGE箇所はご自身のECS/ECRの設定に合わせて置き換えてください

余談ですが、ECSはクラスタ・サービス・タスク・タスク定義といろいろ設定しないといけないのですが、なかなか直感的にわかりにくくてイマイチな印象です

.circleci/config.yml:workflows

~省略~
workflows:
  version: 2
  build-deploy:
    jobs:
      - build:
          filters:
            branches:
              only:
                - develop
                - /release\/.*/
                - master
      - deploy:
          requires:
            - build
          filters:
            branches:
              only:
                - develop
                - /release\/.*/
                - master

この辺はよしなに

deploy.sh

#!/usr/bin/env bash
set -eo pipefail
# more bash-friendly output for jq
JQ="jq --raw-output --exit-status"

deploy_cluster() {
  make_task_def   
  register_definition

  if [[ $(aws ecs update-service --cluster $ECS_CLUSTER_NAME --service $ECS_SERVICE_NAME --task-definition $revision | \
      $JQ '.service.taskDefinition') != $revision ]]; then
    echo "Error updating service."
    return 1
  fi

  # wait for older revisions to disappear
  # not really necessary, but nice for demos
  for attempt in {1..30}; do
    if stale=$(aws ecs describe-services --cluster $ECS_CLUSTER_NAME --services $ECS_SERVICE_NAME | \
        $JQ ".services[0].deployments | .[] | select(.taskDefinition != \"$revision\") | .taskDefinition"); then
      echo "Waiting for stale deployment(s):"
      echo "$stale"
      sleep 30
    else
      echo "Deployed!"
      return 0
    fi
  done
  echo "Service update took too long - please check the status of the deployment on the AWS ECS console"
  return 1
}

make_task_def() {
  task_template='[
    {
      "name": "%s",
      "image": "%s.dkr.ecr.%s.amazonaws.com/%s:%s",
      "essential": true,
      "portMappings": [
        {
          "containerPort": 80
        }
      ],
      "environment": [
        {
          "name": "TARGET",
          "value": "%s"
        }
      ]
    }
  ]'

  task_def=$(printf "$task_template" $ECS_CONTAINER_DEFINITION_NAME $AWS_ACCOUNT_ID $AWS_DEFAULT_REGION $ECR_REPOSITORY_NAME $CIRCLE_SHA1 $TARGET)
}

register_definition() {
  if revision=$(aws ecs register-task-definition --requires-compatibilities FARGATE --cpu 256 --memory 1024 --network-mode awsvpc --execution-role-arn $EXECUTION_ROLE_ARN --container-definitions "$task_def" --family $ECS_TASK_FAMILY_NAME | $JQ '.taskDefinition.taskDefinitionArn'); then
    echo "New deployment: $revision"
  else
    echo "Failed to register task definition"
    return 1
  fi
}

deploy_cluster

デプロイジョブから呼び出すスクリプトです。

task_templateの内容を色々弄るとカスタマイズできます

設定可能な項目はこちら

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/create-task-definition.html

ここでは、environmentで環境変数TARGETを設定しています

ECSがdocker runする際に引数として付与され、docker内のアプリから環境変数として参照可能になります

実際には、nuxt.config.js内でTARGETを参照し、APIサーバの向け先を切り替えたり等しています

以上、ご参考になれば幸いです。

2018年11月30日金曜日

AWSLambdaとServerlessを使ってみる[第2回]

11月 30, 2018

こんにちは、シタテルエンジニアの工です!

AWSLambdaとServerless第2回に入っていきます!
前回は、AWSLambdaとserverlessについてさらっと確認して
serverlessでServiceをcreateするところまでをやってきました。
AWSLambdaとServerlessを使ってみる[第1回]|sitateru tech blog

今回は実際にSansan OpenAPIを利用して名刺情報を取得してみます 🚀

SansanAPI


公式ドキュメント Sansan Open API

名刺API 名刺Set取得(期間指定)を使ってみます。
SansanAPIを利用するにはAPI Keyが必要です。
取得方法はこちらを参考にしてください。

作る

前回createしたServiceを利用して作っていきます。
現在この2ファイルが作成されている状態です。

  • serverless.yml
    • 各種設定を書いていきます
  • handler.js
    • 処理を書いていきます

axiosインストール

今回は、httpリクエストにaxiosを使用します。

$ npm install axios

インストールされました

.
├── handler.js
├── node_modules
│  ├── axios
├── package-lock.json
└── serverless.yml

serverless.yml

環境変数の設定

lambdaには環境変数を設定することができます。
SansanAPIKeyを環境変数として設定してみます。
serverless.yml

# you can define service wide environment variables here
  environment:
    SANSAN_API_KEY: xxx

環境変数を利用する場合は、このように取得できます。

process.env.SANSAN_API_KEY

handler.js

それでは処理を書いていきます。
lambdaの非同期処理とcallbackについてはこちらを参考にしてください。

名刺情報はお見せできないので、取得した件数を出力してみます。

'use strict';

const axios = require('axios')
axios.defaults.headers.common['X-Sansan-Api-Key'] = process.env.SANSAN_API_KEY
axios.defaults.headers.get['Content-Type'] = 'application/json'

module.exports.hello = async (event, context, callback) => {
  var updatedFrom = "2018-11-26T01:00:00Z"
  var updatedTo = "2018-11-27T21:00:00Z"

  await axios.get(`https://api.sansan.com/v2.0/bizCards?updatedTo=${updatedTo}&range=all&entryStatus=completed`)
      .then(function (response) {
        callback(null, response.data.data.length)
      })
      .catch(function (error) {
        callback(error)
      });
};

deploy

cliでdeployします。
serverlessを使わない場合、serviceを手動でzipにしてawsにdeployする必要があるのでとても面倒です...

$ serverless deploy -v

deployが完了したら情報が出力されます。

...
Serverless: Stack update finished...
Service Information
service: hello-sansan
stage: dev
region: us-east-1
stack: hello-sansan-dev
api keys:
  None
endpoints:
  None
functions:
  hello: hello-sansan-dev-hello

lambdaの関数のところにも表示されています。

環境変数も設定されています。

実行

こちらもcliで実行します。

$ sls invoke -f hello
16

件数が取得できました。

おわりに

今回はlambdaからSansanOpenAPIを利用して名刺情報をゲットしてみました!
lambdaはサーバーのこと気にせずに処理だけ書けば良く、serverlessはcliでごにょごにょできるし、とても便利です!
sitateruではlambdaを使って、SansanとHubSpotの同期を自動化しています。
どこかのタイミング第3回としてserverless-offlineを使用したlambdaの開発についても書こうと思います。

2018年11月22日木曜日

AWSLambdaとServerlessを使ってみる[第1回]

11月 22, 2018

こんにちは、シタテルエンジニアの工です!
AWS Lambdaを触る機会がありましたので、ServerlessFrameworkと一緒にいじいじしてみました!
シリーズで、
Serverlessをインストール
AWSLambdaでSansanの名刺データを取得してみる
serverless-offlineでAWSLambdaをローカルで実行
なんかを書いていこうと思います!

さらっとAWSLamdaとServerlessFrameworkについて

AWS Lambdaとは


AWS Lambda とは - AWS Lambda

AWS Lambda はサーバーをプロビジョニングしたり管理しなくてもコードを実行できるコンピューティングサービスです。

つまり、流行りのサーバーレスてやつで、サーバーを準備しなくてよいので、ちょっとした処理の実行など大変助かります。
しかも、LambdaはNode.js (JavaScript)、Python、Java (Java 8 互換)、C# (.NET Core)、 Goに対応しています!
様々な言語に対応しているので学習コストもかからないのがいいですね。

シタテルでは、HubSpotとSansanのデータ同期や、SlackCommandでリリースPRを作るなどで使っています。

Serverlessとは


Serverless Framework

The Serverless Framework is an open-source CLI for building and deploying serverless applications.

つまり、サーバーレスアプリケーションの開発を手助けをしてくれるやつです!
AWS Lambda単体で開発してみるとわかるのですが、ローカルでの開発やビルド、デバッグやらが面倒です。
このServerless Frameworkを使えばそのあたりのもやもやを解消してくれます!

作ってみる

Serverless Framework - AWS Lambda Guide - Introduction こちらがAWS用のServerlessFramework公式ドキュメントです。 基本的にこちらの内容に沿って進めていきます、

今回は、Sansanの名刺データを取得してみます。

まずはServerlessFrameworkをインストール

$ npm install -g serverless
$ serverless -v
1.33.2

正しくバージョンが表示されていたら、インストール完了です!

Serviceを作る

Serviceはプロジェクトのようなもの。
今回は、nodejsで作っていきますので、aws-nodejsを指定。
その他の言語を使いたい方はこちらを参考に。

$ serverless create --template aws-nodejs --path hello-sansan

実行すると

Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/Users/mogura/work/sitateru/lambda/hello-sansan"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.33.2
 -------'

Serverless: Successfully generated boilerplate for template: "aws-nodejs"

このような構成で、Serviceができました!

hello-sansan
   ├── handler.js
   └── serverless.yml

次は、実際に処理を書いていきます。
が、長くなりそうなので今回はここまでに。

おわりに

今回は、ServerlessFrameworkでserviceを作るところまでをやってみました。
次回は、実際にAWSLamdaでSansanから名刺データを取得するとことまでをやっていきます! 🚀

2018年11月14日水曜日

リリース作業を少し楽にした開発(Slack+Lambda+Golang)

11月 14, 2018

こんにちは、シタテルの鶴巻です。

devops&インフラ担当です。

シタテルのプロダクトのリリース作業を少し楽にするために、
Slack+Lambda+Golangを用いて開発した話をします。

リリースの流れ

シタテルでは、GitフローやGitHubフローを採用しています。

また、本番環境へのデプロイは、以下の流れで実施しています。

  1. developブランチからreleaseブランチを作成
  2. ステージング環境でreleaseブランチをデプロイ&動作確認
  3. 本番環境にデプロイ

ちなみに、1.でreleaseブランチを作成すると、CircleCIによって2.のステージング環境へのデプロイは自動で行われます。

地味に面倒なリリース作業

ステージング環境へのデプロイは自動化されているとはいえ、小さな手作業が合間に発生し、地味に面倒でした。

具体的には以下のような作業です。

  • developブランチからreleaseブランチの作成
    • ローカルPCでdevelopブランチを最新の状態にpullして、releaseブランチ作成してGitHubにpush
  • releaseブランチのプルリクエスト作成
    • GitHubのUIをポチポチ
  • リリースタグの作成
    • 前回のリリース以降でマージされたプルリクエストを見て、リリース内容を記述

手作業はSlackからコマンドを叩くだけにしました

Slackから以下のコマンドを叩くだけで、地味に面倒くさかった作業を自動で行うようにしました。

/release <repository> <release branch>

実際には、以下の内容を実施するGolangプログラムをLambdaで実行しています。

  • 対象のリポジトリをクローンし、developブランチからreleaseブランチを作成し、GitHubにpush
  • releaseブランチのプルリクエストを作成
  • 前回のリリース以降にマージされたプルリクエストのタイトルのリストを記述したリリースタグのドラフトを作成

構成

Slack -> API Gateway -> Lambda01(同期) -> Lambda02(非同期) -> GitHub
  1. Slackからコマンドを叩くと、Lambda01にリクエストを送信します。
  2. Lambda01は、Lambda02に対象レポジトリとブランチ名を付与してリクエストを送信します。
  3. Lambda02で作業を実行します。

Lambdaを2つ使用している理由

Slackはリクエスト送信後3秒でタイムアウトするためです。

実行したいプログラムは3秒以上かかるため、実際の作業は非同期で実施する必要がありました。

そのため、Lambda01はLambda02に処理を投げて、Slackに200を返し、実際の処理はLambda02で実施します。

Lambda01はLambda02を非同期実行で呼び出すので、リクエストをキューに入れた後は、Lambda01は関数を終了することができます。

Lambdaの呼び出しタイプ(同期・非同期)

Lambdaは、呼び出しタイプ(InvocationType)を指定することで、同期実行や非同期実行を選択することができます。

例:InvocationTypeで"Event"を指定することで、非同期実行でLambdaを呼び出せます。

input := &lambda.InvokeInput{
FunctionName: aws.String("xxxx"),
Payload: jsonBytes,
InvocationType: aws.String("Event"),
}

※同期実行は"RequestResponse"を指定します

今回使用したGitHub操作のためのGoライブラリ

その他ハマったポイント

  • APIGatewayの統合リクエストのマッピングテンプレートを使いこなせず。デバッグのやり方もわからず、使うのを諦めました。

まとめ

  • 少しの手間が自動化されるだけで、すごく楽になります。これからももっとやっていきたいです。
  • GitHub操作のライブラリはとても便利でした。
  • シタテルのサービスはRails + vue.jsが主ですが、自分の好きなGo言語を使えたので楽しかったです。

参考

slack slash-command

Lambda 呼び出しタイプ

2018年10月31日水曜日

s3の操作はaws-cliよりs3cmd使うほうが便利

10月 31, 2018

こんにちは!

シタテルで エンジニアをしている建山です。

主に工場向けのマイオペというシステムの開発を行っています。

シタテルではファイルをawsのs3でホスティングしています。
直接s3のファイルを操作することは少ないのですが、やはり時々は発生します。

そんなときにはaws-cliを使うこともできるのですが、s3cmdを使うとより簡単なコマンドでS3を操作できます。

いくつかよく使うコマンドをまとめました。

ディレクトリのファイル権限を操作

s3cmd setacl -r --acl-private s3://バケット名/ディレクトリ名/

-r は再帰的に配下すべてやってくれる

--acl-privateはprivate権限にする

--acl-publicはpublic権限にする

※バケットも指定できる

ディレクトリの中身を参照

s3cmd ls s3://バケット名/ディレクトリ名/

バケットの情報をみる

s3cmd info s3://バケット名

これ以外にもファイル/ディレクトリアップロードや削除などいろいろなことができます。

全てのコマンドリストはこちら

コマンドのインストール

インストールはmacの場合、

brew install s3cmd

でできます。

コマンドを使う前に、AWSのアクセスキー等を設定 する必要があります。

s3cmd --configure

ぜひ、お試ししてみてください。

2018年10月30日火曜日

AWS Loft Tokyoに行ってきました

10月 30, 2018

こんにちは!
シタテルで エンジニアをしている熊谷です。

主にSPECというサービスのバックエンド開発(Rails)を行ってます。

今回は、話題のAWS Loft Tokyoに行って来たのでレポートします。