CodeStarバンザイ!数クリックで始めるCI/CDパイプライン

CodeStarを使ってCI/CDパイプラインを構築してみたので、紹介します。

CodeStarとは?

AWSのマネージドサービスであるCodePipeline、CodeCommit、CodeBuild、CodeDeployを使ってCI/CDパイプライン+実行環境をさくっと構築してくれるサービスらしい。

https://aws.amazon.com/jp/codestar/

よしっ、動かしてみるぞ!!

1.プロジェクト作成

マネジメントコンソールからCodeStarを選び、「start a project」をポチッ。
するとプロジェクトのテンプレートを選択する画面が表示される。

カテゴリは、Web application、Web service、Alexa Skill、Static Websiteから、
言語は、Ruby、Node.js、Java、Python、PHP、HTML 5から、
実行環境は、Beanstalk、EC2、Lambdaから選択できる。
※もちろん存在しない組み合わせもあります。

今の時代っぽいWeb Application×Node.js×Lambdaなんてのも選択できるんですね。

うーん、ここはCodeBuildも使ってみたいし「Web Application×Java Spring×EC2」を選択。

使う1.png

そして、プロジェクト名を入力。インスタンスタイプを設定して。ポチッ、ポチッ。

使う2.png

。。。
はいっ、CI/CDパイプライン構築の作業はこれで終わり。

そして、待つこと10分。
CodePipeline、CodeCommit、CodeBuild、CodeDeployと、これを統合的に確認するためのダッシュボードがいい感じにできちゃいました。
もちろんjavaのwebアプリケーションも起動しています。

ダッシュボード

使う4修正.png

CodePipeline

使う8.png

CodeCommit

使う5.png

CodeBuild

使う6.png

CodeDeploy

使う7.png

デプロイされたjavaのwebアプリケーション

12.png

2.CI/CDパイプライン実行

ここからが本番。
gitへの接続情報をIAMで確認(ユーザ⇒認証情報⇒AWS CodeCommit の HTTPS Git 認証情報「生成」)し、code commit上のソースコードをcloneする。
するとこんなものが落ちてきます。

tree
.
├── README.md
├── appspec.yml
├── buildspec.yml
├── pom.xml
├── scripts
│   ├── install_dependencies
│   └── start_server
└── src
    └── main
        ├── java
        │   └── com
        │       └── aws
        │           └── codestar
        │               └── projecttemplates
        │                   ├── HelloWorldAppInitializer.java
        │                   ├── configuration
        │                   │   ├── ApplicationConfig.java
        │                   │   └── MvcConfig.java
        │                   └── controller
        │                       └── HelloWorldController.java
        ├── resources
        │   └── application.properties
        └── webapp
            ├── WEB-INF
            │   └── views
            │       └── index.jsp
            └── resources
                ├── gradients.css
                ├── set-background.js
                ├── styles.css
                └── tweet.svg

ふむふむ、なるほど。
ここは手っ取り早くCI/CDパイプラインを確認するため、index.jspをちょこっと修正。
そして、code commitにpush。
code commit上で、変更した内容も確認できます。

使う11.png
すると。。。

使う9.png

パイプラインが動き出したーーー
どうやら動きとしては、こんなことをやっているみたい。

  • Source : 新たしいコードがpushされると、code commitからソースコードを取得しS3に格納。
  • Build : S3からソースコードを取得しビルド。そしてビルドしたモジュールをS3に格納。
  • Application : S3に格納されたモジュールをEC2にデプロイ。

待つこと5分。デプロイまで成功。
そして、先程の画面を確認してみると。。。

使う10.png

変わった!
簡単!!

これを使えば

  • Java、Rubyなどメジャーな言語を利用したCI/CDパイプラインを爆速で構築できる。
  • Jenkinsから開放される。

がしかし。。

  • 東京リージョンにはまだ来ていない。
  • CodeStarというかcode commit側の問題になるが、pull requestが使えない。。

本番用のアプリケーション開発環境・実行環境として利用するのは、まだまだ難しいような気もしますが、
pocくらいであればこれで十分かもしれませんね。

続きを読む

AWS 認定ソリューションアーキテクト – アソシエイト 合格までに勉強したこと

概要

AWS 認定試験には「これを勉強すればいいよ!」という教科書があるわけではないので、何を勉強したらいいか分からず困っている人も多いと思います。
なので、私の勉強記録を共有します。

勉強前のスペック

AWSの初級者です。
EC2インスタンス起動やEBSのスナップショット取得の経験があるくらいでした。

勉強方法概要

AWS活用本を一冊読んで、
あとはAWS クラウドサービス活用資料集にある BlackBelt のスライド(PDF)を淡々と読みました。

その後、模擬試験を受けて本試験を受験しました。

勉強方法詳細

少し前に買っていた以下の本を読みました。分かりやすいです。

Amazon Web Services 定番業務システム12パターン設計ガイド

BlackBelt

自分が読んだ資料に○を付けました。
また、模擬試験と本試験を受けた経験から、各資料の重要度を評価しました。
※当たり前ですが、読んでいない資料の重要度は評価していません。また、重要度の正確性も保証しません。

コンピューティング

資料 読んだ  重要度 
[Amazon EC2] 
[Amazon EC2] Windows
[Amazon EC2] HPC
[Amazon EC2] リザーブドインスタンス
[Amazon EC2] スポットインスタンス
[Amazon EC2] Instance Store & Elastic Block Store
[Amazon EC2] VMImport/Export
[Elastic Load Balancing]
[Elastic Load Balancing] ロードバランサと Socket 接続を使用したイベント通知サーバの負荷分散
[Elastic Load Balancing] ELBを評価するためのベストプラクティス
[Auto Scaling]
[Amazon EC2 Container Service]
[AWS Elastic Beanstalk]
[AWS Lambda]
[AWS Lambda] update
[Amazon Lightsail]
[AWS Batch]

ストレージ & コンテンツ配信

資料 読んだ  重要度 
[Amazon EBS]
[Amazon S3] 
[Amazon CloudFront]
[Amazon CloudFront] Flash Media Server on AWS
[Amazon CloudFront] CloudFront 上限緩和申請 計算方法&申請手順
[Amazon CloudFront] まだ間に合う! Amazon CloudFront で ATS 対応
[Amazon Glacier]
[Amazon Glacier] 機能編
[AWS Storage Gateway]
[Amazon Elastic File System]

データベース

資料 読んだ  重要度 
[Amazon RDS]
[Amazon RDS] Aurora
[Amazon DynamoDB]
[Amazon ElastiCache]
[Amazon ElastiCache] Redis QA資料
[Amazon Redshift] 
[Amazon Database Migration Service]

ネットワーキング

資料 読んだ  重要度 
[Amazon VPC]
[Amazon VPC] VPN接続設定 参考資料
[AWS Direct Connect] 
[Amazon Route53]

開発者用ツール

資料 読んだ  重要度 
[AWS CodeCommit]
[AWS CodeBuild]
[AWS CodeDeploy]
[AWS CodePipeline]
[AWS SDK]
[AWS SDK] Java & .NET
[AWS SDK] PHP & Ruby & Boto(Python) & Javascript in Node.js
[AWS SDK] AWS Client side SDK Android & iOS & Javascript
[AWS CLI]
[AWS AWS Tools for Windows Powershell]

管理ツール

資料 読んだ  重要度 
[Amazon CloudWatch]
[AWS CloudFormation]
[AWS CloudTrail]
[AWS Config]
[AWS OpsWorks] AWS OpsWorksのご紹介
[AWS OpsWorks]
[AWS OpsWorks] ハンズオン
[AWS Service Catalog]
[Trusted Advisor] AWS サポート & Trusted Advisor
[Amazon EC2 Systems Manager]

セキュリティ & アイデンティ

資料 読んだ  重要度 
[Identity and Access Management (IAM)] 
[AWS CloudHSM] CloudHSM & Key Management Service
[AWS Key Management Service]
[AWS Directory Service]
[Amazon Inspector]
[AWS WAF]
[AWS Certificate Manager]

分析

資料 読んだ  重要度 
[Amazon EMR(Elastic MapReduce)]
[AWS Data Pipeline]
[Amazon Elasticsearch Service] Amazon CloudSearch & Amazon Elasticsearch Service
[Amazon Kinesis]
[Amazon QuickSight]
[Amazon Athena]

AI

資料 読んだ  重要度 
[Amazon AI]]

IoT

資料 読んだ  重要度 
[AWS IoT]

ゲーム開発

資料 読んだ  重要度 
[Amazon Lumberyard]

モバイルサービス

資料 読んだ  重要度 
[Amazon Cognito]
[Amazon Cognito] Amazon Cognito update
[Amazon Cognito] Amazon Cognito / Amazon Mobile Analytics
[AWS Device Farm]
[Amazon Mobile Analytics] Amazon Cognito / Amazon Mobile Analytics
[Amazon SNS] Amazon SNS/SQS
[Amazon SNS] モバイルプッシュ通知
[Amazon Pinpoint]  

アプリケーションサービス

資料 読んだ  重要度 
[Amazon API Gateway] 
[Amazon AppStream]
[Amazon CloudSearch] Amazon CloudSearch & Amazon Elasticsearch Service
[Amazon Elastic Transcoder]
[Amazon SES]
[Amazon SES] Amazon SES-Easy DKIM 設定サポート資料
[Amazon SQS] Amazon SNS/SQS
[Amazon Simple Workflow Service (SWF)]

エンタープライズアプリケーション

資料 読んだ  重要度 
[Amazon WorkSpaces]
[Amazon WorkDocs]
[Amazon WorkMail]
[Amazon Chime]

その他

資料 読んだ  重要度 
[Cost Explorer]
[AWS Management Console]

補足

重要度の低い資料も読んだ方がいいです。
なぜなら、マネージドサービス自体がAWSの活用事例であり、それらを知ることでシステム設計の勘所が分かるようになるからです。
また、重要度の高い機能との連携についての記載があることもあり、理解が深まります。

続きを読む

SlackからAWS API Gatewayを通してLambdaを起動するまで

AWS LambdaとAPI Gatewayを使いこなすためにいい練習になるかなと思って
SlackからLambdaをキックしたり、起動したLambda functionのログとかをSlackに通知するような仕組みを作ってみる。

構成はこんな感じ
スクリーンショット 2017-06-11 23.57.06.png

この構成ができれば、いわゆるサーバレスアーキテクチャが出来るってことになるのでなかなかアツい。
Lambdaが出来てからサーバレスアプリケーションが最近注目を集めてますよね。
それにbotのためにサーバー(コンテナ)を立てる必要もなくなるのでエコな構成になるんじゃないだろうか。
それではさっそくチャレンジしてみる。

AWS Lambdaについて

Lambdaを触ったことがないって人にはこの記事がおすすめ。細かく丁寧に説明されています。
http://qiita.com/s_s_k/items/b584435120e99d63975b

Lambdaを準備する

まず初めにLambdaに処理を書いていきます。
Node.jsで書く必要があります。javaでも書けるそうですがNode.jsの方がレスポンス早そうなのでこちらを採用します。
内容は簡単で、いくつかのStringメッセージを json 形式に格納して、ランダムに返却するというもの。

index.js
exports.handler = (event, context, callback) => {

    var res = {};
    res.username = "outgoing-webhook-from-lambda";
    var array = [
        'わからないことは<https://api.slack.com/custom-integrations|こちら>を参照してください。',
        'こんにちは、私は'+ res.username +'です。nAWSのLambda functionで処理されています。n',
        'API Gatewayを使ってLambda functionを起動する良い練習になりますね。',
        'outgoing-webhookを使用すればLambda functionをAPI Gateway経由でキックすることができます。'
    ];
    res.text = array[Math.floor(Math.random() * array.length)];

    callback(null, res);
};

今回はSlackに返却するのでOutgoing WebHooksが受けられるような形式にしています。以下がその形式。


{
"username": "発言するbotのユーザ名";
"text": "表示されるテキスト";
}

API Gatewayの準備

Lambda functionを起動するためにAPI GatewayからAPI(POST)してみましょう。
testというメソッドを作成しています。統合リクエストには先ほど設定したLambdaを書いておきましょう。

スクリーンショット 2017-06-13 00.03.11.png

統合リクエストの詳細をみると以下のようになっています。
スクリーンショット 2017-06-13 00.06.03.png

注意しなければいけないのが「本文マッピングテンプレート」の部分。
Slackから飛んでくるPOSTは形式が jsonではなく、form-urlencodedで送られてくるらしい。
そこで「application/x-www-form-urlencoded」の時は json 型に変換するマッピングを定義します。
以下のようにしてあげれば良いと思います。

mapping_template.txt
## convert HTML POST data or HTTP GET query string to JSON

## get the raw post data from the AWS built-in variable and give it a nicer name
#if ($context.httpMethod == "POST")
 #set($rawAPIData = $input.path('$'))
#elseif ($context.httpMethod == "GET")
 #set($rawAPIData = $input.params().querystring)
 #set($rawAPIData = $rawAPIData.toString())
 #set($rawAPIDataLength = $rawAPIData.length() - 1)
 #set($rawAPIData = $rawAPIData.substring(1, $rawAPIDataLength))
 #set($rawAPIData = $rawAPIData.replace(", ", "&"))
#else
 #set($rawAPIData = "")
#end

## first we get the number of "&" in the string, this tells us if there is more than one key value pair
#set($countAmpersands = $rawAPIData.length() - $rawAPIData.replace("&", "").length())

## if there are no "&" at all then we have only one key value pair.
## we append an ampersand to the string so that we can tokenise it the same way as multiple kv pairs.
## the "empty" kv pair to the right of the ampersand will be ignored anyway.
#if ($countAmpersands == 0)
 #set($rawPostData = $rawAPIData + "&")
#end

## now we tokenise using the ampersand(s)
#set($tokenisedAmpersand = $rawAPIData.split("&"))

## we set up a variable to hold the valid key value pairs
#set($tokenisedEquals = [])

## now we set up a loop to find the valid key value pairs, which must contain only one "="
#foreach( $kvPair in $tokenisedAmpersand )
 #set($countEquals = $kvPair.length() - $kvPair.replace("=", "").length())
 #if ($countEquals == 1)
  #set($kvTokenised = $kvPair.split("="))
  #if ($kvTokenised[0].length() > 0)
   ## we found a valid key value pair. add it to the list.
   #set($devNull = $tokenisedEquals.add($kvPair))
  #end
 #end
#end

## next we set up our loop inside the output structure "{" and "}"
{
#foreach( $kvPair in $tokenisedEquals )
  ## finally we output the JSON for this pair and append a comma if this isn't the last pair
  #set($kvTokenised = $kvPair.split("="))
 "$util.urlDecode($kvTokenised[0])" : #if($kvTokenised[1].length() > 0)"$util.urlDecode($kvTokenised[1])"#{else}""#end#if( $foreach.hasNext ),#end
#end
}

スクリーンショット 2017-06-13 00.13.00.png
この部分ですね。

ここまでできればAPIをデプロイしてやって、URLを作成しましょう。

Slack側の設定

Slack Outgoing WebHooks

integrationメニューから Outgoing WebHooks を検索してください。

image.png

流れにしたがって設定していってください。
ここに先ほどAPI Gatewayで作成したURLを貼り付けるだけでOK

image.png

動かして見ましょう。
いい感じにできました。

image.png

次回はLambdaをDBに繋ぐ or Cognito の UserPool を使って認証を簡単に作成したりしてみようと思います。

続きを読む

AWS Summit Tokyo 2017 メモ -「全部教えます!サーバレスアプリのアンチパターンとチューニング」

はじめに

先日行われた AWS Summit Tokyo 2017 の「全部教えます!サーバレスアプリのアンチパターンとチューニング」メモです。

AWS Lmbdaを中心としたサーバレスアプリケーションで発生しがちな問題とその対応策について」のセッションでした。

Lambdaが遅い理由

考えられるポイント

  • プログラム
  • コンピューティングリソース
  • アーキテクチャ

プログラム → 各言語のベストプラクティスに従う
コンピューティングリソース → メモリ設定を行うメモリサイズと比例して割り当てられるCPUリソースも割り当てられる。つまり、メモリを倍にするとCPUも倍。

Lambda設定の最適値設定方法

メモリを増やした際に処理時間が大きく短くなる場合がある。
その場合は処理時間が短くならなくなったところが最適値と考えてOK。

Lambdaファンクション実行時に起きていること。

  1. (ENIの作成)
  2. コンテナの作成
  3. デプロイパッケージのロード
  4. デプロイパッケージの展開
  5. ランタイム起動・初期化
  6. 関数/メソッドの実行

1〜6を実行するのがコールドスタート
1〜5は基本的に毎回同じ内容が実行される → 再利用することで省略して効率化(ウォームスタート)。

コールドスタートが起こる条件

利用可能なコンテナがない場合に発生

  • 1つもコンテナがない状態
  • 利用可能な数以上に同時に処理すべきリクエストが来た
  • コード、設定を変更した
    安定的にリクエストが来てたらコードや設定を変更しない限りコールドスタートはほとんど発生しない

コールドスタートは回避できるの?

コールドスタートは利用者側でどうにかできる領域ではない。なので基本的に回避はできない。
つまり、コールドスタートを0にすることは難しいため、それが許容できないのであればAWS Lambdaは使うべきでない。

実行を早くするには?

  • *コンピューティングリソースを増やす
    →コンピューティングリソースの割り当てを増やすことで初期化処理が早くなる

  • *ランタイムを変える
    →AWS Lambdaに限らずJVMの起動は遅い、ただし、一度温まるとコンパイル言語の方が速い傾向。

  • パッケージサイズを小さくする
    →サイズが大きくなるとコードのロード及びZip展開に時間がかかる(不要なコードは減らす, 依存関係を減らす, 不要なモジュールは含めない(特にJava))
     →JavaだとProGuardなどのコード最適化ツールを使って減らすという方法もある。

  • *VPCは必要でない限り使用しない。
    →使うのはVPC内のリソースにどうしてもアクセスする必要があるときだけ。
    →VPCを有効にしているとコールドスタート時に10秒から30秒程度余計に必要になる。
    →同期実行が必要な箇所やコールドスタートを許容できない箇所ではなるべく使わない。
    →VPC内のリソースとの通信が必要なのであれば非同期にする。

  • 初期化処理をハンドラの外に書くとコールドスタートが遅くなる。

アーキテクチャの問題

  • 同期でInvokeすると同時実行数の制限に引っかかって詰まりがち。
  • できるだけ非同期でInvokeするのがスケーラビリティの観点ではオススメ。
  • Think Parallel:並列処理を行う。
  • 1つあたりのイベントを小さくして同時に並列で動かせるようなアーキテクチャにする。

同時実行数

  • 関数の平均実行時間:3s/exec
  • 同時実行数=”同時”に実行されているタイミング
  • 秒間リクエスト:10req/sec
  • ストリームベースの場合はシャード単位

Limit Increase(上限緩和)について

標準では1000、実績がない状態でいきなり数千とか数万を申請しても通らない。
もし実績がない状態でどうしても緩和したい場合はサポートへ直接相談。

気をつけよう

  • Lambda + RDBMS → Amazon DynamoDBを使う方が良いのでは?
  • IP固定したがり問題 → 署名や証明書などで担保すべき。
  • サーバレスであれば全く運用が必要ない、インフラ費用が10分の1になる → サーバの管理は不要だが運用は必要。
  • Serverless != Monitorless

Lambda使う際の注意

ちゃんとエラー検知などは入れましょう。

  • CloudWathcのメトリクス、Errors,Throttles
  • CloudWatchのカスタムメトリクス

おわりに

セッションの講演資料がちゃんと共有されているので詳しく知りたい方はそちらを参照願います。

関連書籍

実践AWS Lambda」はセッション登壇者の西谷さんが書かれた本です。

 

続きを読む

AWS Summit Tokyo 2017 参加レポート Day4 (6/2)

会社の外部研修として『AWS Summit Tokyo 2017』に6月1日(木)~2日(金)の計2日間参加して来ました。

当エントリでは6月2日(Day4)に聴講した内容をレポートします。(Day3のレポートはこちら
※注)記事には個人的なメモや感想が含まれています。予めご承知ください。


展示ブース見学1 (9:00 ~ 10:00)

基調講演開始までの待ち時間、Pavilion 展示ブースを見て回りました。

立ち寄ったブース

  • IoT.kyoto

  • Sony Global Education:KOOV

    • 子供向けIoT学習キット
    • レゴブロックのようなパーツを自由に組み合わせ
    • アプリで日本語による論理パズルのようなものを使いビジュアルプログラミング
  • tv asahi:MP360LIVE
  • レコチョク:RECOLab
  • PIXELA:パノミル
    • VRコンテンツ配信プラットフォーム
  • AUCNET:Andy ニコパス
    • 来店客などの顔認識⇒LINEやSlackなどで通知&顧客管理
    • オフィスなどの入退室管理にも
    • 感情なども判別
      • 顧客満足度のデータ化
      • 従業員のストレスチェック

基調講演(Key Note) (10:00 ~ 11:30)

スピーカー:茂木 健一郎 氏 (脳科学者)

>人工知能、”Innovation” をテーマにトーク

もはやAIと人間の脳を比較すること自体がナンセンス

 人間の意識:128bit/sec 説
  チェス等⇒チャンピオンの一生分を機械なら~1か月?
  人間=並列処理 限界ある:AI並列化し放題
 e.g. 雪道走行経験欲しい ⇒自動運転=雪国からデータを持ってくればいい

人間の脳ってみじめじゃないですか?

 ギブソン:アフォーダンス理論
  >「脳は情報処理不要」「情報は環境の中にある」

Amazon Echo早く日本で出ない?遅れてますよね

 MIT 子供の過去三年間の会話データを全て記録した話
  >BigData、機械学習で出来ること、可能性は計り知れない

人間の脳なんてもう気にしなくていい

 人工知能と人間の恋の映画
  >AI:「今2万人と同時に会話してる」「数百人と恋に落ちてる」

なんだかAIに申し訳ないなって思いました

重要なのは個性

人間の感情・パーソナリティのデータモデルはまだない
 パーソナリティ5大要素⇒人工知能にインプリメンテーションまだ無理
  ⇒ソース:由来がわからない(⇔脳の情報処理の動きは比較的判明している)

人工知能が目指すものは人間の脳とはおそらく違う

 SNSなど今のシステム⇒人間のアテンションによりすぎ

 近代平均IQは上がり続けてる
  ⇒情報処理が増えたからと言われる
   ⇒それで人間は幸せになっている?

 現代はリアルとサイバースペースの二重生活
  ⇒リアルを整理するコスト=わずらわしい(Amazon robotics Home欲しい)
   ⇒メールなど=まだ人間のアテンションが必要

 Amazonでショッピング(本、靴、ズボンなど)
 ⇒勝手に買っておいてほしい(サイズ、好みなどの把握)
   心地よさのスクリーン

 子供の脳が最高(ルーティンがない、大人がやってくれているから)
  大人はつまらない
 AIが仕事を奪う⇒歓迎、ルーティンワークは任せるべき
  ⇒遊んでいるだけの人間が一番クリエイティブ
  天才の遺伝子はない(突然変異?)
  アメリカの功績は遊ぶように働くスタイルを確立したこと

 未来の義務教育の内容
  ⇒ほぼAIがやってくれる
   ⇒小学から論文など始めるのもあり

 人間の最終目標⇒幸せになること

子供のころ無邪気に遊んでた頃が幸せじゃありませんでした?

エンジニアへ

これからのイノベーションの主役はあなた方
人間の脳、キャパシティなんて気にせず
 個性を大事に
新しいものを産み出していってほしい

スピーカー:Kris Davies 氏 (Amazon Dashサービス シニア・プロダクトマネージャー)

IoTはあらゆるレベルの変革を可能に

ショッピングのイノベーション

 (昔)店舗⇒PC⇒スマホ⇒IoT:Dashボタン(今ここ)⇒ゼロクリック(Next!)

 店でよくあること=買うものを忘れる
 ・メモを忘れる
 ・消耗品のストックを忘れる
 ・既に買ったものを忘れる

 Dash Replenishment Service(DRS)
 スマート家電
  e.g. 掃除機>ゴミパックの状態を把握⇒クラウドに
      ⇒満タンになりそう⇒自動検出して替えを発注

  • 家庭には多くのデバイス(=変革の種?)がある

    • 「もし」ではなく「いつ」が検討すべきポイント
  • カスタマーからのフィードバックが大切
  • 全てのネット接続されたデバイスが役に立つわけではない
    • 本当に役立つ「モノのインターネット」を

スピーカー:Jeff Blankenburg 氏 (Amazon Alexa Evangelist)

Alexa
 スマートホーム
 デバイスに話しかける

ALEXA エコシステム
 スキル(ASK):デベロッパーが作成可能

音声⇒テキスト⇒自然言語解析⇒意図からスキルを探す⇒処理⇒レスポンス

ボイスエクスペリエンスのデザイン⇒開発⇒テストと認証

意思の解析が難しい
 e.g. 天気予報の取得⇒言い方がいろいろある
 e.g. テレビのリモコン⇒ボタン単位でコード化を考える

スピーカー:Andy Pollock 氏 (Amazon Robotics Software Development Manager)

Amazon Robotics

 e.g. 大図書館から本を探す状況
  ⇒手をかざしたら本が降ってくる を想像/創造した

Amazon 倉庫内で起きていること

 商品入荷⇒Podに収納⇒棚ごと移動⇒保管場所へ
  注文⇒担当者のもとに棚自身が来る⇒梱包、出荷

効率化アルゴリズム

数え切れないほどの商品の種類・数万単位の同じ商品
 ⇒どれを取りに行くか?
 動かす棚、ロボットの判定
  ⇒商品自身の位置だけじゃなく、間の障害物、作業員、一度に運べる個数など
   ⇒複雑な演算が必要
    ⇒AWS使用

次のイノベーションへ

「Its stil day one」(我々はまだ”1日目”である)

クロージング

Amazon

「どうか一つでも多く、イノベーションの種をお持ち帰りください」


展示ブース見学2 (12:00 ~ 14:00)

続いてDay3では回れなかったEXPO 展示ブースを見て回りました。
ついでに認定者ラウンジに立ち寄って昼食と、前日貰い損ねた折り畳み傘をGET。

立ち寄ったブース

  • Datadog Inc.

    • サーバ運用監視・モニタリングツール
    • AWS以外も対応サービスの数がスゴイ
  • 日商エレクトロニクス株式会社:New Relic
    • サーバ運用監視・モニタリングツール
    • 上記Datadogと競合
  • ソニーネットワークコミュニケーションズ株式会社:Cloud Portal
    • AWSサービスの構成管理ツール
    • 実際の設定から構成図などのドキュメントを生成可能、PDF出力も可(←この機能欲しかった)
  • 株式会社インターナショナルシステムリサーチ:CloudGate KeyManager
    • サーバ接続するユーザとSSH鍵を一括管理するツール

      • 有効期限付きのSSH Key発行・管理
      • 鍵の受渡し⇒指紋認証・2要素認証・ワンタイムパスワードなど選択可
  • パロアルトネットワークス株式会社
  • 富士ソフト株式会社
    • ストレスの度合?をリアルタイムで測定するIoTデバイスのデモを見せて頂いた
    • モニタリングした心拍数に数学的な処理・フィルタリングを施しグラフにして可視化?
      • 詳しく説明して頂いたが正確に理解出来たか怪しい
  • クラスメソッド株式会社

    • 日本のAWSユーザでこちらの会社のブログ記事を読んだ事が無い人はいないと思う
    • AWSおみくじを引かせて頂いた(結果はELBとt2.nanoでした;)

AWS Dev Dayの会場へ移動

Session:サーバレスで王道 Web フレームワークを使う方法 (14:20 ~ 15:00)

スピーカー:塚田 朗弘 氏 (AWSジャパン 技術統括本部 ソリューションアーキテクト)

セッション概要(タイトルリンク先より引用)

サーバレスアーキテクチャでアプリケーションを開発するとき、いつも使っているフレームワークをそのまま使うことができたら嬉しいと思ったことはないでしょうか。AWS Lambda では Node.js、Python、Java、C# といったプログラミング言語をサポートしています。このセッションでは、AWS のサーバレスアーキテクチャ上で代表的な Web アプリケーションフレームワークを使う実践的な方法をご紹介します。

Express.js on serverless

aws-serverless-express使用

npm install aws-serverless-express

app.js ⇒ lambda.js に変更

Spring Framework on serverless

aws-serverless-java-container使用

コードサンプル

どちらも Code Star にプロジェクトテンプレートあり
 ⇒手軽に始められるので是非


Session:[タワーズ・クエスト]Serverless 時代のテスト戦略(仮) (15:20 ~ 16:00)

スピーカー:和田 卓人 氏 (タワーズ・クエスト株式会社 取締役社長)

セッション概要(タイトルリンク先より引用)

Serverless 時代においても、自分のコードにテストは書きたいものです。まだベストプラクティスが確立されていない Serverless 時代のテストを考えていきます。

レガシーコードのテストをかいてみる

お題:lamdbaの公式チュートリアルにテストをつける

このコードはtestableだろうか?
デプロイなし、ローカルでテストしたい!

サイズとピラミッドとループ

テスト自動化ピラミッドとアンチパターン

“Test Sizes” at Google
https://testing.googleblog.com/2010/12/test-sizes.html

small:ネットワーク、データベース、ファイル、全てのI/Oなしの独立したテスト
medium:ネットワークはlocalhostのみ、外部サービスは非推奨
large:外部サービスも含め、本番と同じ条件のテスト

テスト数:small > medium > large

small:例外系テスト

medium:ローカルテストするには ⇒FakeObjectが鍵

  • Test Double(テストの為の”代用品”)

    • Test Stub
    • Test Spy
    • Mock Object
    • Fake Object
    • Dummy Object

 https://github.com/atlassian/localstack を活用
  ⇒各種AWSサービスのローカルテスト用Fake実装

レガシーコードのジレンマ
 多くの場合、テストを描くにはコードを変更する必要がある

教訓:テストしてないコードは動かない

large:運用監視とは継続的なテスト
 品質の良いシステム
 ・バグが少ない
 ・すぐになおる

本番環境の不具合をテストに写し取る
不具合が出たら再現テストコードを書いて、落ちることを確認してから修正コードを書く

サービス間(E2E)テスト

= XLarge Test (largeの上)

マイクロサービス間テストの課題
 >モックのリクエストやレスポンスが本番と異なる為、テストは通るが本番で落ちてしまう可能性。
 ⇒Consumer-Driven Contracts testing (CDCテスト)

pactを使ったCDCテストをCIで回す
 >Consumer側をMock/Stub感覚で書く


メイン会場へ移動

Session:[ソニーモバイルコミュニケーションズ] スマートホームシステムの開発 〜AWS を活用した新規サービスの立ち上げ〜 (16:20 ~ 17:00)

スピーカー:井宮 大輔 氏 (ソニーモバイルコミュニケーションズ株式会社)

セッション概要(タイトルリンク先より引用)

新規サービスは受容性が分からないため契約者数の予測が難しく、初期開発投資をなるべく抑え素早く市場に投入することが要求されます。上記を実現すべく、スマートホームシステム開発では AWS を最大限に活用しました。本セッションでは、システム開発において直面した課題と、それを AWS IoT などのサービスを用いていかに解決したかについてご紹介します。

スマートホームシステム

コンセプト
 家庭内デバイスをネット接続
  ⇒データ収集
   ⇒適切な制御

“スマートホームHub”を通してデバイスを制御

最大の課題=セキュリティ
 ・家族(ユーザ)の認証
 ・デバイス認証

 アカウント管理・認証
  ・ユーザ管理
  ・トークンアクセス
  ・パス、Email変更

1.ユーザ認証
 ⇒Cognito User Pool使用
  ・自前のユーザアカウント可
  ・SMS、MFAが実現可能
  ・カスタム属性で独自のデータ追加可能

2.デバイス認証
 ⇒AWS IoT使用
  デバイス数万台分のThingを作成
  ⇒工場でクライアント証明書・暗号鍵埋め込み
   ⇒一台ずつポリシーを作成(他のデバイスの機能にアクセス不可)

3.メッセージ 双方向通信
 ⇒IoT Topic・ルール使用

4.データ同期
 IoT Thing Shadow
  課題:最大8KB
   ⇒一つのデバイスに複数のThingを対応させて解決


Session:AWS マネージドサービスで実現する CI/CD パイプライン (17:20 ~ 18:00)

スピーカー:千葉 悠貴 氏 (AWSジャパン株式会社 技術統括本部 ソリューションアーキテクト)

セッション概要(タイトルリンク先より引用)

CI/CD ツールは DevOps の実践に不可欠なものですが、ツール自体の構築・運用は不可価値を生まない重労働です。AWS のマネージドサービスを使うことで、開発者は自社ビジネスに価値を与える開発に集中できます。本セッションでは、AWS CodePipeline や AWS CodeBuild といった DevOps サービスの概要と、その他の AWS マネージドサービスを組み合わせた CI/CD の実践方法をご紹介します。

CI/CDを実現する”ツールとしての”AWSサービス

CI:継続的インテグレーション

フロー
1.Source>2.Build>3.Test>4.Production

必要なもの

・ソースコードのVer管理:CodeCommit
・ビルド自動化:CodeBuild
・デプロイ自動化:CodeDeploy/Beanstalk/Formation
・ワークフロー管理:CodePipeline

全て東京リージョンで使用可

⇒4つを統合したサービス:CodeStar(現在USのみ)
 ほぼ2ステップで完了
 ・Step1.プロジェクトテンプレート選択
 ・Step2.開発ツールセットアップ
  ⇒パイプライン作成
  ⇒ダッシュボード作成(JIRA統合メニュー)

CD:継続的デリバリー

安全に本番環境にデプロイ
 リリース判断/タイミング

本番環境の継続的監視・デプロイ判断

1.シンセティックトラフィックでの常時監視
  CloudWatch+Lambdaで定期実行

2.デプロイメントヘルスチェック・ロールバック
  CodeDeployの機能を使う
   ・ValidateServiceフック
   ・Minimum Healthy Hosts
   ⇒失敗と判断⇒自動でロールバック

3.デプロイ単位のセグメンテーション
  カナリアデプロイ:部分的に適用⇒運用してみてから範囲を広げていく手法
  CodeDeploy
   ・デプロイメントグループ(セグメント分割)
  CodePipeline
   ・Approvalアクション:管理者にSNSで通知する機能(Lambdaに渡せば完全自動化可能)

4.プロダクション昇格の無効化
  デプロイ先ホストの健全性を確認してからデプロイする
   ⇒本番環境の一部に問題があればリソースを無効化
  CodePipeline
   ・トランジションの無効化

5.BlackDayゲート
  ビジネス的にセンシティブな時期/時間を考慮
   パイプラインにデプロイ停止日のカレンダーを導入
    ⇒e.g. LambdaでDynamoDB上のカレンダーを参照など

「CodePipeline をカスタマイズすることでビジネスに最適な CI/CD パイプラインが作れる」


所感・備忘録

  • 基調講演待ってる間に周れるとこは周るべし
  • 基調講演は情報・刺激の宝庫
  • 講演者についてもっと事前に調べておく
  • AWSの方のセッションはそろそろ上級向けに絞ってもいいかもしれない
    • 初級~中級はググればすぐ出てくる内容がそこそこ
  • Dev Dayはコアな内容(コードとか)まで突っ込んでくれるので実入り多し
  • 夜イベントは早めに行く(公演優先して後から行ったら料理が既になかった;)
  • Twitter情報は重要、なるべくチェック
  • 会場のWifiは時々繋がらなくなる(キャパのせい?)
  • やはりAWSサミットは楽しい
    • 来年も、出来れば全日参加したい

続きを読む

CloudFront配下のアクセス制限付き動画(HLS形式)を、署名付きCookieを使ってVideo.jsで再生する

相変わらずタイトルが長いですが(Googleで検索するとタイトルの途中でぶった切られてます…と思ったら誰かが登録したはてブでした)、
AWS SDK for Javaを使ってカスタムポリシーを使用した署名付きCookie(CloudFront用)を設定する
で設定した環境に、HLS形式の動画(.m3u8ファイル+複数に分割された.tsファイル)を配置して、外部のアプリケーションから読み込ませるものです。

なお、Video.jsでのHLS形式の動画再生については、(Video.jsのバージョンが少し古いですが)以下の記事が参考になります。
Video.js を使って HLS形式の動画をストリーミング再生する(akiyoko blog)

6/5追記:CloudFrontのBehavior設定変更手順を書き漏らしていたので修正しました。

0. 前提

まず、
AWS SDK for Javaを使ってカスタムポリシーを使用した署名付きCookie(CloudFront用)を設定する
の通りに、CloudFrontとS3が設定されているものとします。
また、テスト用のアプリケーションはローカル開発環境にSpring Bootを使って実装するものとします(要hostsファイル変更)。

アプリケーションやコンテンツを公開するドメインは、↑の記事に合わせます。
アプリケーション : https://hmatsu47.site/
https://hmatsu47.site/set-cookieにアクセスするとhttps://hmatsu47.site/index.htmlに遷移し、動画プレイヤーが表示されます。
動画コンテンツ  : https://www.hmatsu47.site/
→S3バケット「testmatsusignedcookie」直下に「sample.m3u8」ファイルと、同ファイルに記述した分割動画ファイル(XXXXX.ts)を保存します。

いずれも、自身の環境に合わせて読み替え/書き替えてください。

1. CloudFrontのBehaviorの設定を変更する

CloudFrontで、対象ディストリビューションのBehavior設定を変更し、S3バケットにフォワードされるHTTPリクエストで、要求ヘッダ中の「Origin」が除外されないようにして保存します。
cf_whitelist.jpg
※上図ではHTTPメソッドとして「GET」「HEAD」に加えて「OPTIONS」を受け入れるよう設定していますが、preflight requestが飛ぶ場合などでうまくいかないときは、「OPTIONS」メソッドの受け入れも試してみてください。

2. S3バケット設定(CORS)を変更する

S3バケットのアクセス権限で、CORS構成エディターを使って設定を変更し、クロスオリジンのScriptアクセスを許可します。
※先の記事の1-3. S3バケットのアクセス権限を設定する⑥・⑦の画面にある[CORS の設定]をクリックし、構成エディタで内容を変更して保存します。

CORS設定
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>http://hmatsu47.site</AllowedOrigin>
    <AllowedOrigin>https://hmatsu47.site</AllowedOrigin>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3600</MaxAgeSeconds>
    <ExposeHeader>ETag</ExposeHeader>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

<MaxAgeSeconds>には適切な有効期間を指定します。

3. アプリケーションを変更する

先の記事の2. アプリケーションに署名付きCookieをセットするコードを実装する「SetCookieController.java」末尾のコメント行(「// リダイレクトで遷移」)以降を変更して、P3Pコンパクトポリシーを応答ヘッダに付与するとともに(IE11用)、ローカル側のindex.htmlに遷移する形に書き換えます。

SetCookieController.java(変更部分=末尾のみ)
        res.setHeader("P3P", "CP=\"【P3Pコンパクトポリシー】\"");
        // リダイレクトで遷移
        res.sendRedirect("index.html");
    }
}

P3Pコンパクトポリシーは、IE11で別オリジン(別FQDN or 別プロトコル/ポート番号のサイト)にScriptからCookieを送信できるようにするために指定します。
正しい内容でなくても任意の文字列がセットされていれば動作してしまうようです。
なお、IE以外のブラウザでは、すでに機能していないため、指定がなくても別オリジンへの(Scriptによる)Cookie送信は可能です。

4. 動画再生に必要なファイルを配置する

Video.jsおよび必要な.jsファイル等と、それらを呼び出すindex.htmlを用意します。

以下、Spring Boot環境では、「src/main/resources」の下に「static」フォルダを作成して配置します。Video.js関連のファイルはダウンロードするなどして用意してください。

  • video-js.5.19.2 (フォルダ)
  • video-js.5.19.2/video-js.min.css
  • video-js.5.19.2/video.min.js
  • video-js.5.19.2/videojs-contrib-media-sources.min.js
  • video-js.5.19.2/videojs-contrib-hls.min.js
  • video-js.5.19.2/video-js.swf
  • index.html
index.html
<html>
  <head>
    <title>HLS test</title>
    <link href="/video-js.5.19.2/video-js.min.css" rel="stylesheet">
    <script src="/video-js.5.19.2/video.min.js"></script>
    <script src="/video-js.5.19.2/videojs-contrib-media-sources.min.js"></script>
    <script src="/video-js.5.19.2/videojs-contrib-hls.min.js"></script>
    <script>
      videojs.options.flash.swf = "/video-js.5.19.2/video-js.swf"
    </script>
  </head>
  <body>
    <video id="test" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" width="【動画プレイヤー横幅】" height="【同・高さ】">
    </video>
    <script>
      var player = videojs('test', {techOrder: ['flash', 'html5']});

      player.src({
        src: 'https://www.hmatsu47.site/sample.m3u8',
        type: 'application/x-mpegURL',
        withCredentials: true
      });
    </script>    
  </body>
</html>

署名付きCookieをScriptからCloudFrontに送信するために、「withCredentials」「true」にしています。

IE11ではVideo.js+HTML5によるHLS形式の動画再生に不具合があるため、Flashを使った再生となります。
因みに、ローカルの「video-js.swf」を読み込む指定をしていますが、IE11だけこの指定は無視され、CDNからダウンロードされてしまいます…。結果として、IE以外のブラウザで外部のファイルをわざわざ読みにいかないようにするためだけにこの指定がある、ということになってしまっています。

5. 動画ファイルをS3バケットにアップロードする

「sample.m3u8」ファイルおよび分割動画ファイルについても、S3バケットにアップロードしておきます。

6. 動画再生をテストする

以上の作業で、署名付きCookieで保護された動画を再生することができる環境ができあがります。

ローカルのブラウザで、https://hmatsu47.site/set-cookieを開くと動画再生画面が表示され、再生ボタンをクリックすると動画の再生が始まります。

※index.htmlから読み込むファイルとコンテンツタイプの指定を適切に変更することで、HLS形式でない動画を再生することも可能です。

なお、IE11でFlashを使う再生の場合、HTML5で再生するよりも分割動画の読み込みタイミングが遅いため、再生機器や回線の速度によっては動画がギクシャクしやすくなります。ご注意ください。

7. 補足/CookieとCORSについて

ややこしいのですが、Cookieの有効範囲とCORSによる「オリジン間のアクセス制御」は別物です。

■Cookieの有効範囲:Domain属性、Secure属性、Path属性、HttpOnly属性で指定

  • Domain属性を指定しなければSet-Cookieしたサーバと同じFQDN、指定していれば指定ドメインおよびそのサブドメイン。今回のケースでは「hmatsu47.site」を指定しているため、「hmatsu47.site」および「www.hmatsu47.site」のどちらでも有効(テストには使っていないが「app.hmatsu47.site」「video.hmatsu47.site」などでも有効)。なお、Set-Cookieしたサーバと関係のないドメインをDomain属性で指定しても無効(ブラウザで破棄される)。
  • Secure属性を指定しなければHTTP/HTTPSの両方で、指定すればHTTPSのみで有効。ポート番号の区別なし。
  • Path属性を指定すれば指定のパス以下で有効(Path属性には色々問題はあるが、説明は省略)。
  • HttpOnly属性を指定すればScriptから利用不可。
  • サードパーティーCookie(ブラウザが読み込んだHTML本体とは別のドメインのサーバから画像や.jsなどを読み込むことによりセットされるCookie)については、ブラウザの設定によって有効/無効が決まる。

■CORS:オリジン(FQDNとプロトコル・ポート番号の組み合わせ)をまたぐアクセスを制御

  • 同一オリジンにあたるのは、「FQDNとプロトコル(HTTP/HTTPS)およびポート番号(80/81、443/8443など)の組み合わせが同じ」。つまり、https://hmatsu47.sitehttps://www.hmatsu47.siteは別オリジン。http://www.hmatsu47.sitehttps://www.hmatsu47.sitehttp://hmatsu47.sitehttp://hmatsu47.site:81も別オリジン。
  • (ブラウザが処理中の)別オリジンのサーバのScriptからアクセスを受けるようなケースで、アクセス制御に使用される。https://hmatsu47.site からの読み込みアクセスは、リクエストを受けてから○○秒の範囲で有効にするよ」というようなイメージ。アクセスを受けたサーバがアクセス元オリジンを区別できるように、ブラウザからのリクエストの要求ヘッダにはオリジンの情報(Origin)を付与する。
  • デフォルトでは、たとえブラウザが(アクセス先の別ドメインに対して有効な)Cookieを持っていたとしても、Scriptからのリクエストでは送信しない。JavaScriptでは、XMLHttpRequestでwithCredentials属性を有効にすることで(リクエストを送信するとき一緒に)送信される。なお、CORSとは別に、IE11の場合はP3Pコンパクトポリシーも必要になる。
  • Cookieを受け付けるかどうかは、リクエストを受けるサーバのCORSでも指定できる。

つまり、

  • いくらwithCredentials属性を有効にしてXMLHttpRequestでリクエストを送信しても、相手先のドメインで有効なCookieを持っていないとCookieは送信されない。
  • サードパーティーCookieがブラウザに受け入れられるかどうかとCORSの設定は別問題であるため、分けて考える必要がある。

ということです。

なお、今回のサンプルでは、Javaのコードで署名付きCookieを生成する際に「HttpOnly」属性を付けています。
これは、アクセス元のJavaScriptの中ではこのCookieを参照する必要がないからです。結果、「HttpOnly」属性を付けていても問題なく動作します。

続きを読む

AmazonS3上のMavenリポジトリを使った、Gradleでの依存関係管理

概要

タイトルの通り、AmazonS3にMavenリポジトリを作成し、Gradleで使う方法を記載しています。

社内のモジュールに依存するモジュールを開発する際に、サーバー上で依存関係を解決しビルドするために使ったりします。

本記事のゴール

本記事のゴールは、下記の1,2です。

  1. S3上にMavenリポジトリにライブラリをアップロードする
  2. 上記ライブラリを別のGradleプロジェクトからダウンロードする

2については、具体的には以下のようなbuild.gradleの設定で「gradle build」コマンドを実行した際にライブラリをダウンロードできるようにします。

build.gradle
dependencies {
    compile 'jp.co.goalist:library:1.0.0'
}

以下の内容については本記事では扱いません。いつかまた。

  • Jenkinsなどビルドサーバー側での設定
  • S3上のリポジトリへのアクセス管理

前提

  • Gradleをインストールしている(3.3で検証済み)
  • S3のバケットにファイルをアップロードできるAWS IAMユーザーを作成している
  • 上記IAMユーザーのアクセスキーIDとシークレットアクセスキーを持っている

Mavenリポジトリへのアップロード

Gradleプロジェクト作成

以下のコマンドを実行します。

mkdir gradle-upload-s3repo
cd gradle-upload-s3repo/
gradle init --type=java-library

生成されたファイルはこんな感じです。

.
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
    │   └── java
    │       └── Library.java
    └── test
        └── java
            └── LibraryTest.java

この時点で build.gradle の内容は以下の通りです。(不要なコメントと依存ライブラリの設定は削除しています)

build.gradle
apply plugin: 'java'

//依存ライブラリが未定義のため、
//現時点ではrepositoriesとdependenciesは不要ですが、
//後ほど使うので残しておきます。
repositories {
    jcenter()
}

dependencies {
}

確認のため、プロジェクトルートで「gradle build」と打ってあげると、build/libsに「gradle-upload-s3repo.jar 」が生成されます。ここまではjavaプラグインのデフォルト機能です。

確認後、「gradle clean」してビルド結果を削除してあげましょう。

groupId、artifactId、version を定義する

Mavenでは、groupIdとartifactIdとversionの組み合わせでライブラリを一意に定義します。

今回作成するライブラリは慣習にならい、

キー
groupId jp.co.goalist
artifactId library
version 1.0.0

にしましょう。

build.gradleに以下の設定を追加します。

build.gradle
group = "jp.co.goalist"
version = "1.0.0" 

settings.gradleを以下のように変更します。

settings.gradle
rootProject.name = 'library'

S3上にリポジトリ用のバケットを作成する

手順は省略しますが、リポジトリとして使用するバケットを作成します。

今回は「s3://repository.hoge/maven/」を作成します。

開発環境からS3へのアクセス情報を設定する

~/.gradle/gradle.propertiesにリポジトリのURLとIAMユーザーのアクセスキーIDとシークレットアクセスキーを設定します。

これをプロジェクト側が参照することで、プロジェクトに含めないですむのでセキュリティ的に安全になります。(普通のこと言ってます)
あと個々のプロジェクトでアクセスキーID等で設定しないですみます。

gradle.properties
goalistRepoUrl=s3://repository.hoge/maven/
awsAccessKeyId = AKIAJWORQEXXXXXXXXXX
awsSecretAccessKey = waTa0aakgK2e5hXXXXXXXXXXXXXXXXXXXXXXXXXX

mavenプラグインのuploadArchivesタスクを設定する

MavenリポジトリへのアップロードにはmavenプラグインのuploadArchivesを使います。

先程設定したリポジトリのURL、IAMユーザーのアクセスキーID、シークレットアクセスキーを参照するように設定を追加します。

build.gradle
apply plugin: 'maven'
build.gradle
uploadArchives {
    repositories {
        mavenDeployer {
            configuration = configurations.deployerJars
            repository(url: goalistRepoUrl) {
              authentication(userName: awsAccessKeyId, password: awsSecretAccessKey)
            }
        }
    }
}

S3へのアクセスには org.springframework.build:aws-maven を使いますので、dependenciesに設定を追加します。

今回は最新版の5.0.0.RELEASEを使います。

http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.springframework.build%22%20AND%20a%3A%22aws-maven%22

build.gradle
configurations {
    deployerJars
}

dependencies {
    deployerJars 'org.springframework.build:aws-maven:5.0.0.RELEASE'//追加
}

これで設定は完了。最終的には以下のようになります。

build.gradle
apply plugin: 'java'
apply plugin: 'maven'

group = "jp.co.goalist"
version = "1.0.0" 

repositories {
    jcenter()
}

configurations {
    deployerJars
}

uploadArchives {
    repositories {
        mavenDeployer {
            configuration = configurations.deployerJars
            repository(url: goalistRepoUrl) {
              authentication(userName: awsAccessKeyId, password: awsSecretAccessKey)
            }
        }
    }
}

dependencies {
    deployerJars 'org.springframework.build:aws-maven:5.0.0.RELEASE'
}
settings.gradle
rootProject.name = 'library'

uploadArchivesタスクを実行

以下のコマンドを実行し、BUILD SUCCESSFULL と表示されたら成功です。

gradle uploadArchives

S3を確認すると

s3://repository.hoge/maven/以下にライブラリがアップロードされていると思います。

Mavenリポジトリからダウンロード

今回アップロードしたライブラリに依存するGradleプロジェクトを作成します。

mkdir gradle-upload-s3repo-child
cd gradle-upload-s3repo-child/
gradle init --type=java-library

build.gradleを変更し、S3のリポジトリを参照するための設定と、依存関係の設定をします。

build.gradle
apply plugin: 'java'

repositories {
    jcenter()
    maven {
        url goalistRepoUrl
        credentials(AwsCredentials) {
            accessKey awsAccessKeyId
            secretKey awsSecretAccessKey
        }
    }
}

dependencies {
    compile 'jp.co.goalist:library:1.0.0'
}

以下のコマンドを実行し、BUILD SUCCESSFULなことを確認できたら完了です。

gradle build

さいごに

実運用ではビルドサーバーからしかアップロードできないようにして、開発者は参照のみ出来るようにすればいい感じに運用できると思います。
モジュールを再利用していきましょう。

続きを読む

AmazonSNSのSMS送信をLaravelでやってみた

基盤にAWSを使っているところでSMS送信をしなきゃいけなくなったのでやってみました。
AmazonSNS自体初でめちゃめちゃ時間かかったんですが、実装自体はすごく楽でした。。

前提

Laravel5.4

やってみる

  1. AWS SDKのサービスプロバイダーを仕込む
    やっぱりありますね。
    https://github.com/aws/aws-sdk-php-laravel

    インストールはREADME通りにやれば大丈夫なので割愛します。

    私が一番悩んだのはアクセスキーとシークレットアクセスキーって何?!ってところでした笑
    そもそもAWSもコンソールに入ってからGUIでちょこちょこと作業することはあったんですが、細かいこと全然わかってなかったもので。。

  2. 実装する

    今回はPoC的なところだけ私の担当で、本実装は他の人だったので、コンソールコマンドで実装しました。

    Console/Commands/SendSms.php
    namespace AppConsoleCommands;
    
    use IlluminateConsoleCommand;
    use AWS;
    
    class SendSms extends Command
    {
        /**
         * The name and signature of the console command.
         *
         * @var string
         */
        protected $signature = 'command:send:sms';
    
        /**
         * The console command description.
         *
         * @var string
         */
        protected $description = 'Send SMS';
    
        /**
         * Execute the console command.
         *
         * @return mixed
         */
        public function handle()
        {
            $sms = AWS::createClient('Sns');
            // 細かい設定はpublishする前にsetSMSAttributesで設定する
            // $sms->setSMSAttributes([
            //     'DefaultSMSType' => 'Transactional',
            //     ...
            //     ..
            //     .
            // ]);
            $sms->publish([
                'Message' => 'send sms test',
                'PhoneNumber' => '+819000001234'
            ]);
        }
    }
    

    一番注意しなければいけなのは SMSClient ではなく SNSClient を使うってとこですね笑
    最初aws-sdkのサンプルでS3Client使ってるのをみて勝手に SMSClient 使おうって思ったんですが、中身が何もなく、他の方から そのSMS、ショートメッセージサービスじゃなくてAWS Server Migration Serviceじゃん とご指摘を頂きようやく気付きました。。。:sweat_smile:

    ここにJavaのサンプルがあって、ちゃんと SNSClient 使ってるのにちゃんと見なかった私が悪かったです。。。

    なかなかドキュメントの場所がわからなかったんですが、ここにあります。

  3. 確認する
    CLIから php artisan command:send:sms を実行したら無事PhoneNumberにある電話番号にSMSが送信されました!

さいごに

まずはしっかりドキュメント読め ってのは重々承知してたつもりなのに思い込みで突っ走ったのがいけなかったです。。
ただ、SMSClientって名前はちょっとなぁ。。。(言い訳)

続きを読む