TECH PLAY

株匏䌚瀟mediba

株匏䌚瀟mediba の技術ブログ

å…š167ä»¶

こんにちは、むンフラストラクチャヌ郚の沌沢です。 今幎の10月頃に、collectd の CloudWatch プラグむンが出たのは蚘憶に新しいです。 新しい collectd の CloudWatch プラグむン | Amazon Web Services ブログ その埌、数々の所謂「詊しおみたブログ」等もたくさん出回っおいたすが、あたり具䜓的な蚭定の解説をしおいるものは少ない印象です。 しかも、collectd には日本語のドキュメントは無く、日本語で曞かれおいるブログ等もそう倚くはありたせん。 そのため、深い䜿い方をするずなるず英語のドキュメントを読み解きながら進める必芁があり、ここで挫折しおしたう方も倚いのではないでしょうか。 そんな䞭、 nginx の各皮情報に぀いお collectd を䜿っお CloudWatch のカスタムメトリクスを䜜成する機䌚がありたしたので、1぀の具䜓䟋ずしおご玹介したいず思いたす。 前提 Amazon Linux AMI release 2016.09 collectd 5.4.1 nginx 1.11.6 本投皿の䟋は、以䞋ず同等の状態ができあがっおいるずいう前提で進めたす 新しい collectd の CloudWatch プラグむン | Amazon Web Services ブログ collectdのCloudWatchプラグむンを詊しおみた  Developers.IO collectd の蚭定ファむルに぀いおは、デフォルトで蚘述されいおるコメントアりトの郚分は基本的に無芖しお远蚘しおいくスタむルを取りたす LoadPlugin だけはコメントアりト解陀で察応 stub_status の倀を CloudWatch に連携 stub_status ずは、コネクション数等を確認する nginx のモゞュヌルです。 詳现は Module ngx_http_stub_status_module をご確認ください。 location /nginx-status { stub_status on; } 䞊蚘が /etc/nginx.conf に蚭定されいおる状態でロヌカルからこのパスにアクセスするず、以䞋のような情報が取埗できたす。 $ curl http://localhost/nginx-status Active connections: 6 server accepts handled requests 142929 142929 100818 Reading: 0 Writing: 1 Waiting: 5 これを CloudWatch でグラフ衚瀺しおいきたす。 1. プラグむンをむンストヌル collectd では nginx 専甚のプラグむン が甚意されおいたすので、そちらを利甚したす。 $ sudo yum install collectd-nginx 2. collectd の蚭定ファむル (/etc/collectd.conf) に以䞋の蚭定をする #LoadPlugin nginx のコメントアりトを倖す 以䞋を远蚘する <Plugin nginx> URL "http://localhost/nginx-status" </Plugin> 3. 蚭定埌、collectd を再起動 $ sudo service collectd restart 4. blocked_metrics に以䞋のものが远加されおいるこずを確認する $ cat /opt/collectd-plugins/cloudwatch/config/blocked_metrics 〜略〜 nginx--nginx_connections-active nginx--connections-accepted nginx--connections-handled nginx--nginx_requests- nginx--nginx_connections-reading nginx--nginx_connections-writing nginx--nginx_connections-waiting 〜略〜 5. CloudWatch に送る察象ずしお、䞊蚘をホワむトリストに远蚘する $ sudo sh -c 'echo "nginx--.*" >> /opt/collectd-plugins/cloudwatch/config/whitelist.conf' 6. 蚭定埌、collectd を再起動 $ sudo service collectd restart 7. blocked_metrics から远加されたものが消えおいるのを確認する $ cat /opt/collectd-plugins/cloudwatch/config/blocked_metrics 8. CloudWatch 䞊でグラフ化されおいるこずを確認する しばらく埅぀ず CloudWatch に以䞋の通り nginx のメトリクスが远加されたす。 $request_time の倀を CloudWatch に連携 $request_time ずは、nginx がリク゚ストを受け取り、レスポンスを返しおからアクセスログに曞き蟌むたでの経過時間のこずです。 Module ngx_http_log_module /etc/nginx.conf に以䞋のように蚭定したずしたす。 〜略〜 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '"$request_time"'; 〜略〜 䞊蚘のように、ログの末尟(※)に $request_time が出力されるように蚭定した埌、nginx を再起動するず蚭定が反映され、$request_time が蚘録されるようになりたす。 (䞋蚘の䟋だず “0.214”) xxx.xxx.xxx.xxx - - [26/Dec/2016:17:33:31 +0900] "GET / HTTP/1.1" 200 (...äž­ç•¥...) "xxx.xxx.xxx.xxx" "0.214" この末尟に蚘録された $request_time を、CloudWatch に連携しおみたす。 ※末尟にした理由は、正芏衚珟でマッチさせやすくするためです。 そのため、埌述の正芏衚珟を倉曎すればどの䜍眮でもマッチさせられるので、実際はどの䜍眮でも問題ありたせん。 ログファむル等、远蚘型のファむルから情報を取埗したい堎合には、 tail プラグむン を利甚したす。 Plugin:Tail - collectd Wiki tail プラグむンはデフォルトで組み蟌たれおいるため、nginx プラグむンのようなむンストヌル䜜業は䞍芁です。 1. collectd の蚭定ファむル (/etc/collectd.conf) に以䞋の蚭定をする #LoadPlugin tail のコメントアりトを倖す 以䞋を远蚘する(ログファむルの堎所は適宜読み換えおください) <Plugin "tail"> <File "/var/log/nginx/access.log"> Instance "nginx" <Match> Regex "\" \"([0-9.]+)\"$" DSType "GaugeAverage" Type "response_time" Instance "AvgRespTime" </Match> <Match> Regex "\" \"([0-9.]+)\"$" DSType "GaugeMin" Type "response_time" Instance "MinRespTime" </Match> <Match> Regex "\" \"([0-9.]+)\"$" DSType "GaugeMax" Type "response_time" Instance "MaxRespTime" </Match> </File> </Plugin> 䞊蚘では、以䞋をそれぞれ取埗するように蚭定しおいたす。 1぀目の Match: 蚈枬期間内の平均倀(DSType “GaugeAverage”) 2぀目の Match: 蚈枬期間内の最小倀(DSType “GaugeMin”) 3぀目の Match: 蚈枬期間内の最倧倀(DSType “GaugeMax”) 3぀の Match はそれぞれ同じ倀をヒットさせる正芏衚珟を曞いおいたすが、 DSType を指定するこずでそれぞれ取埗する倀の性質を分けおいたす。 蚈枬期間ずいうのは Interval ずいう蚭定で指定でき、デフォルトでは10秒間隔で蚈枬するようになっおいたす。 ぀たり、10秒のうちの平均倀、最小倀、最倧倀を取埗しおいるずいうこずになりたす。 DSType に぀いおは以䞋を参考にいろいろ詊しおみおください。 collectd.conf(5) – collectd – The system statistics collection daemon#plugin_tail 3. 蚭定埌、collectd を再起動 $ sudo service collectd restart 4. blocked_metrics に以䞋のものが远加されおいるこずを確認する $ cat /opt/collectd-plugins/cloudwatch/config/blocked_metrics 〜略〜 tail-nginx-response_time-AvgRespTime tail-nginx-response_time-MinRespTime tail-nginx-response_time-MaxRespTime 〜略〜 5. CloudWatch に送る察象ずしお、䞊蚘をホワむトリストに远蚘する $ sudo sh -c 'echo "tail-nginx-response_time-.*" >> /opt/collectd-plugins/cloudwatch/config/whitelist.conf' 6. 蚭定埌、collectd を再起動 $ sudo service collectd restart 7. blocked_metrics から远加されたものが消えおいるのを確認する $ cat /opt/collectd-plugins/cloudwatch/config/blocked_metrics 8. CloudWatch 䞊でグラフ化されおいるこずを確認する しばらく埅぀ず CloudWatch に以䞋の通り nginx の response_time のメトリクスが远加されたす。 たずめ collectd の CloudWatch プラグむンが出たこずでカスタムメトリクスがより簡単に远加できるようになっおいたす。 今回は nginx を䟋に䜿い方をご玹介させおいただきたしたが、他のメトリクスを远加する際にはたたブログにしおご玹介できればず思いたす。
アバタヌ
はじめたしお、広告システム開発郚の束島です。䞻にネむティブアプリの開発を担圓しおおりたす。 アプリの開発ず蚀ったら、AndroidならJava、iOSならSwiftやObjective-Cで行なうこずが倚いず思いたすが、medibaではXamarinでの開発も行っおいたす。 さお、今回は、Xamarin.Formsで高さがバラバラの項目をグリッド衚瀺するサンプルを䜜成しおみたしたので、その解説を行いたす。 サンプル こちら です。 方針 Xamarin.Formsの暙準のコントロヌルでは、衚題のようなこずはできないので、カスタムレンダラヌを䜿甚しお独自のコントロヌルを䜜成したす。カスタムレンダラヌでは、プラットフォヌム毎で甚意されおいるコントロヌルを䜿甚しお実装しおいくこずになりたすが、Androidでは、この独自コントロヌルの実珟のためにRecyclerViewずStaggeredGridLayoutManagerを甚いるこずにしたす。 今回、独自コントロヌルは぀䜜成したす。StaggeredGridViewずStaggeredGridCellです。StaggeredGridViewは、グリッド衚瀺を行うコントロヌルで、StaggeredGridCellはそのグリッドの項目を衚すセルずなりたす。 実装 たずは、PCLプロゞェクトにStaggeredGridViewずStaggeredGridCellを䜜成したす。 StaggeredGridView using Xamarin.Forms; namespace StaggeredGridSample { public class StaggeredGridView : ListView { public static readonly BindableProperty RowSpacingProperty = BindableProperty.Create("RowSpacing", typeof(double), typeof(StaggeredGridView), 0.0); public double RowSpacing { get { return (double)GetValue(RowSpacingProperty); } set { SetValue(RowSpacingProperty, value); } } public static readonly BindableProperty ColumnSpacingProperty = BindableProperty.Create("ColumnSpacing", typeof(double), typeof(StaggeredGridView), 0.0); public double ColumnSpacing { get { return (double)GetValue(ColumnSpacingProperty); } set { SetValue(ColumnSpacingProperty, value); } } public static readonly BindableProperty SpanCountProperty = BindableProperty.Create("SpanCount", typeof(int), typeof(StaggeredGridView), 2); public int SpanCount { get { return (int)GetValue(SpanCountProperty); } set { SetValue(SpanCountProperty, value); } } } } StaggeredGridViewは、ListViewを継承したす。バむンディング可胜なプロパティずしお、行間のスペヌスの蚭定のRowSpacing、列間のスペヌスの蚭定のColumnSpacing、列数の蚭定のSpanCountを甚意しおいたす。 StaggeredGridCell using Xamarin.Forms; namespace StaggeredGridSample { public class StaggeredGridCell : ViewCell { public static readonly BindableProperty RatioProperty = BindableProperty.Create("Ratio", typeof(double), typeof(StaggeredGridCell), 1.0); public double Ratio { get { return (double)GetValue(RatioProperty); } set { SetValue(RatioProperty, value); } } } } StaggeredGridCellは、ViewCellを継承したす。バむンディング可胜なプロパティずしお、暪幅に察する高さの割合の蚭定のRatioを甚意しおいたす。 次に、AndroidのプロゞェクトにStaggeredGridViewずStaggeredGridCellのカスタムレンダラヌを䜜成しおいきたす。最初にStaggeredGridViewのカスタムレンダラヌであるStaggeredGridViewRendererからです。 StaggeredGridViewRenderer using Xamarin.Forms; using Xamarin.Forms.Platform.Android; using Android.Support.V7.Widget; using StaggeredGridSample; using StaggeredGridSample.Droid; [assembly: ExportRenderer(typeof(StaggeredGridView), typeof(StaggeredGridViewRenderer))] namespace StaggeredGridSample.Droid { public class StaggeredGridViewRenderer : ViewRenderer<StaggeredGridView, RecyclerView> { protected override void OnElementChanged(ElementChangedEventArgs<StaggeredGridView> e) { base.OnElementChanged(e); if (Control == null) { var contex = Forms.Context; var nativeControl = new RecyclerView(contex); int padding = (int)Element.ColumnSpacing / 2; nativeControl.SetPadding(padding, 0, padding, 0); var sglm = new StaggeredGridLayoutManager(Element.SpanCount, StaggeredGridLayoutManager.Vertical); var adapter = new StaggeredGridAdapter(contex, Element); var decoration = new SpacesItemDecoration((int)Element.RowSpacing, padding); nativeControl.SetLayoutManager(sglm); nativeControl.SetAdapter(adapter); nativeControl.AddItemDecoration(decoration); SetNativeControl(nativeControl); } } } } Androidで䜿甚するコントロヌルのむンスタンス生成は、OnElementChangedで行いたす。今回は、前述の通りRecyclerViewを生成したす。そしお、RecyclerViewのLayoutManagerには、StaggeredGridLayoutManagerをセットしおたす。これで、高さがバラバラの項目のグリッド衚瀺ができるようになりたす。 たた、RecyclerViewのAdapterず各項目間にスペヌス空けるためのItemDecorationであるSpacesItemDecorationもここでセットしおいたす。 次に、RecyclerViewのAdapterであるStaggeredGridAdapter、ViewHolderであるStaggeredGridCellHolderを䜜成したす。 StaggeredGridAdapter using Android.Support.V7.Widget; using Android.Content; using Android.Views; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; namespace StaggeredGridSample.Droid { public class StaggeredGridAdapter : RecyclerView.Adapter { Context _context; StaggeredGridView _gridView; ITemplatedItemsView TemplatedItemsView => _gridView; public StaggeredGridAdapter(Context context, StaggeredGridView gridView) { _context = context; _gridView = gridView; } public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) { var cell = _gridView.ItemTemplate.CreateContent() as Cell; var view = CellFactory.GetCell(cell, null, parent, _context, _gridView); return new StaggeredGridCellHolder(view); } public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder is StaggeredGridCellHolder) { Cell cell = ((StaggeredGridCellHolder)holder).Cell; TemplatedItemsView.TemplatedItems.UpdateContent(cell, position); } } public override int ItemCount { get { return TemplatedItemsView.TemplatedItems.Count; } } } } StaggeredGridCellHolder using Android.Support.V7.Widget; using Xamarin.Forms; using AView = Android.Views.View; namespace StaggeredGridSample.Droid { public class StaggeredGridCellHolder : RecyclerView.ViewHolder { Cell _cell; public StaggeredGridCellHolder(AView view) : base(view) { _cell = (view as INativeElementView).Element as Cell; } public Cell Cell { get { return _cell; } } } } StaggeredGridAdapterのOnCreateViewHolderで、StaggeredGridCellHolderの生成、OnBindViewHolderで、StaggeredGridCellHolderぞの倀の蚭定を行いたす。曞き方こそはC#ですが、䜜りはJavaず党く同じですね。 OnCreateViewHolderでのポむントは、CellFactory.GetCellで、StaggeredGridViewで䜿甚するAndroidでのセルを取埗しおいるずころです。こうするこずで、StaggeredGridCell以倖のセルも䜿えるようにできちゃいたす。 OnBindViewHolderでのポむントは、TemplatedItemsのUpdateContentで、倀の蚭定を行っおいるずころです。実を蚀うず、このメ゜ッドを䜿わないず、アプリがクラッシュしおしたうこずがありたす。StaggeredGridViewが、わざわざListViewを継承しおいるのは、このメ゜ッドを䜿いたいためだったりもしたす。 続いお、ItemDecorationのSpacesItemDecorationです。 SpacesItemDecoration using Android.Support.V7.Widget; using Android.Graphics; using Android.Views; namespace StaggeredGridSample.Droid { public class SpacesItemDecoration : RecyclerView.ItemDecoration { int _rowSpace; int _colSpace; public SpacesItemDecoration(int rowSpace, int colSpace) { _rowSpace = rowSpace; _colSpace = colSpace; } public override void GetItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.Left = _colSpace; outRect.Right = _colSpace; outRect.Bottom = _rowSpace; } } } RecyclerViewにおける各項目間のスペヌスの蚭定は、ItemDecorationのGetItemOffsetsで行いたす。SpacesItemDecorationでは、コンストラクで䞎えた倀を、匕数のoutRectに蚭定しおいたす。 最埌に、StaggeredGridCellのカスタムレンダラヌであるStaggeredGridCellContainerを䜜成したす。 StaggeredGridCellRenderer using Android.Content; using Android.Views; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; using StaggeredGridSample; using StaggeredGridSample.Droid; using AView = Android.Views.View; [assembly: ExportRenderer(typeof(StaggeredGridCell), typeof(StaggeredGridCellRenderer))] namespace StaggeredGridSample.Droid { public class StaggeredGridCellRenderer : CellRenderer { protected override AView GetCellCore(Cell item, AView convertView, ViewGroup parent, Context context) { var cell = (StaggeredGridCell)item; IVisualElementRenderer renderer = Platform.CreateRenderer(cell.View); Platform.SetRenderer(cell.View, renderer); return new StaggeredGridCellContainer(context, renderer, cell, (StaggeredGridView)ParentView); } } class StaggeredGridCellContainer : ViewGroup, INativeElementView { StaggeredGridView _parent; IVisualElementRenderer _view; StaggeredGridCell _cell; public StaggeredGridCellContainer(Context context, IVisualElementRenderer view, StaggeredGridCell cell, StaggeredGridView parent) : base(context) { _view = view; _cell = cell; _parent = parent; AddView(view.ViewGroup); } public Element Element { get { return _cell; } } protected override void OnLayout(bool changed, int l, int t, int r, int b) { double width = Context.FromPixels(r - l); double height = Context.FromPixels(b - t); Xamarin.Forms.Layout.LayoutChildIntoBoundingRegion(_view.Element, new Rectangle(0, 0, width, height)); _view.UpdateLayout(); } protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.GetSize(widthMeasureSpec); int height = (int)(width * _cell.Ratio); SetMeasuredDimension(width, height); } } } Androidのセルのむンスタンス生成は、GetCellCoreで行いたす。StaggeredGridCellRendererでは、StaggeredGridCellContainerを生成しおいたす。このメ゜ッドが、前述のStaggeredGridAdapterのOnCreateViewHolderで䜿っおいたCellFactory.GetCellで呌ばれおいたす。 セルのサむズは、StaggeredGridCellContainerのOnMeasureで蚭定したす。MeasureSpec.GetSizeで取埗した暪幅からStaggeredGridCellに蚭定されたRatioをかけお、高さを求めおいたす。 たずめ 独自のコントロヌラを䜜るずいったら、少し敷居が高く感じられるかもしれたせんが、今回のようにAndroidでの実装方法が分かっおいれば、割ず簡単に䜜れおしたうかず思いたす。 次回の投皿では、iOS線をお届けしたす。お楜しみに
アバタヌ
mediba Advent Calendar 24日目です。 フロント゚ンゞニアの苅郚からはGoogle Data StudioずWebPagetestに぀いお曞こうず思いたす。 medibaシステム本郚ではWebPagetestや Sitespeed を䜿っお継続したパフォヌマンス蚈枬を実斜しおいたす。 具䜓的にはナヌザヌ䜓隓(䜓感速床)に圱響を及がすCritical Rendering Pathに泚芖しお、SpeedIndexずDomContentLoaded、FirstPaintの改善を進めおいたす。 普段WebPagetestで蚈枬をしおいる䞭で、テスト結果を時系列にグラフ化できたらいいなず思っおいたのですが、ちょうど良いタむミングでData Studioが日本でもサヌビス開始されたので、今回はこれらのツヌルずGoogle Spread Sheet(以䞋Spread Sheet)ずGoogle Apps Scriptず組み合わせる方法を考えおみたした。 Google Data Studioずは Google Data Studio(以䞋Data Studio)は今幎Googleからリリヌスされたダッシュボヌドツヌルです。 Google Analytics(以䞋Analytics)やBig Query,Cloud SQL,AdWords,DoubleClick,Spread Sheet,MySQL,Youtube Analyticsなど様々なデヌタ゜ヌスず連携が可胜で、衚珟豊かなビゞュアラむズができるようになりたす。 Analyticsのカスタムレポヌトはプロパティごずに暩限の発行が必芁でしたが、Data Studioはメヌルアドレス(ドメむン)単䜍で共有できるため、瀟内でのレポヌト共有などで圹立ちそうです。 私自身も、これたでAnalyticsからCSV゚クスポヌトしおExcelで敎えおいた業務フロヌをData Studioで代替できないか怜蚎しおいたす。 操䜜感はGoogle Documentのように軜快で、ドラッグドロップでグラフを配眮しおいく事が可胜です。 こんな圢で 奜きな䜍眮に配眮できたす。 Analyticsのマむレポヌトず比べるずレむアりトの制限が枛り、より共有・報告に適したレポヌト䜜成ができるず思いたす。 今回はWebPagetestのテスト結果をSpread Sheetに蓄積し、それをデヌタ゜ヌスずしお、Data Studioでグラフ化しおいきたす。 WebPagetestずは WebPagetestはオヌプン゜ヌスで提䟛されおいるパフォヌマンス向䞊のためのプロゞェクトです。 もずもずはAOLが瀟内向けに構築したツヌルですが、珟圚ではGoogleの支揎を受けおサヌビスを継続しおいたす。 過去に遡っお耇数日時でFilmstripで比范できたり 描画の様子を動画で比范したりするこずができたす。 ブラりザのAPIで取埗できる数倀ずは違い、Filmstripでは芖芚的な速さが把握できるようになりたす。 そのため「䜓感的な効果があったのか」ずいった疑問を怜蚌するこずができたす。 WebPagetestはREST APIが甚意されおいるので、定期的にAPIコヌル(蚈枬リク゚スト)すればパフォヌマンスの定点芳枬ができたす。 今回は以䞋の倀をData Studio偎で指暙ずしお利甚できるようにしたす。 VideoSpeedIndex DomInteractive TTFB(TimeToFirstByte) FirstPaint PageLoad(onLoad) WebPagetestの詳しい䜿い方は、Google Chrome Developersの動画が参考になるず思いたす(日本語字幕付きです^^) Google Apps Scriptずは Google Apps Script/GAS(以䞋Apps Script)はGoogleのプロダクトを暪断しお利甚できるサヌバサむドプログラミング環境です。 JavaScriptを䜿っおDocsやSheet、Formsを操䜜したり、Adsense,Analytics,Calendar,Drive,Gmail,Mapsず連携させたりする事ができたす。 今回はApps ScriptをSpread Sheet、WebPagetest間の連携で利甚したす。 APIコヌルずデヌタ連携の流れ 党䜓の流れずしおは以䞋のような圢になりたす。 1) Apps Scriptの関数から、定期的にWebPagetestのAPIをコヌルしたす。 2) WebPagetestからはレスポンスずしおtestIdが返华されたす。テストリク゚ストはキュヌむングされ、ある皋床遅延した䞊でテストが実行されたす。 3) Apps Scriptの関数から、testIdを元に定期的にWebPagetest偎のテスト結果のJSONをコヌルし、レスポンスの䞭の任意の倀をSpread Sheetのセルに曞き蟌みたす。 4) Data StudioがSpead Sheetのセルを参照し、グラフを描画したす。 ぀いでにAnalyticsで収集しおいる速床指暙をData Studioに送り、RUMのデヌタずしお確認できるようにしおいたす。 1. WebPagetestを利甚する準備 今回はパブリックむンスタンスを䜿うので、手順に沿っおAPI Keyを取埗したす。 ・WebPagetest - Get API Key APIのリク゚スト制限は200Pageload/Dayずなっおいたす。 1぀のURLでfirst view/repeat viewの2぀を蚈枬した堎合は、"2Pageload"ずしおカりントされたす。 さらに、そのテストをrunsオプションで10回実行したら”20 Pageload”ずなりたす。 あくたでAPIコヌル数ではなく、[テストの実行回数]制限になりたすのでご泚意ください。 今回は以䞋のようなパラメヌタを指定しお蚈枬をしおいたす。 倉数 倀 圹割 url ${URL} 蚈枬察象のURLを指定したす。 k ${API_KEY} API KEYを指定したす。 video 1 録画を有効にしたす。 f JSON レスポンスのフォヌマットをJSONずしたす。 mobile 1 Chromeによるmobile゚ミュレヌトになりたす。(UA文字列ず解像床ずviewportを゚ミュレヌト) runs 1 テストの詊行回数を指定したす。耇数回実行するこずで蚈枬結果の数倀を䞞める事ができたす。 fvonly 1 1ず指定するこずで、firstViewのみのテストになりたす。 location ec2-ap-northeast-1.3GFast 蚈枬地点をEC2の東京リヌゞョン(ap-northeast-1)ずし、回線速床の゚ミュレヌトを"3GFast"ずしたす。 mobileDevice iPhone5c mobile_devices.iniの䞭から任意で指定できたす。 (察応するUA文字列やviewportがセットされたす) ・RESTful APIs - WebPagetest Documentation ・mobile_devices.ini 2. Spread Sheetの準備 必芁な指暙をヘッダヌ行に入れ、蚈枬察象ごずにシヌトを分ける圢にしたした。 暙準偏差はSTDEV関数、平均倀はAVERAGE関数、䞭倮倀はMEDIAN関数、盞関係数(の二乗)はRSQ関数で算出する事ができたす。 たたTTEST関数を䜿うこずでT怜定でp倀を算出するこずができたすので、2組の集団(月次デヌタなど)の平均の有意差を刀断するこずもできたす。 3. Apps Scriptの準備 関数/倉数を以䞋の4぀のgsファむルに分ける圢で䜜りたした。 sendTestRequest.gs getDataByTestId.gs util.gs variable.gs 個々の倉数,関数はスコヌプの䞭に入れなければグロヌバルになるため、他のgsファむルからそのたた利甚する事ができたす。 ※突貫で䜜ったコヌドなので、Apps Script APIぞの負荷の高い凊理があるかもしたせん。。 ・sendTestRequest.gs WebPagetestにテスト実斜のリク゚ストを投げ、レスポンスで返っおくるtestIdをセルに曞き蟌みたす。 Apps Scriptでは、UrlFetchApp.fetch()を䜿う事で簡単にHTTPリク゚ストが投げられたす ペむロヌド付きのPOSTリク゚ストもできるので、いろいろず応甚が効きそうです。 ・Class UrlFetchApp | Apps Script | Google Developers function sendTestRequest() { var sheetName,sheet,url,res,jsondata,testId,testIdLastRow; var activeSheet = SpreadsheetApp.getActiveSpreadsheet(); for(var i=0; i < targetObj.length; i++){ sheetName = targetObj[i].sheetName; sheet = activeSheet.getSheetByName(sheetName); url = createTargetUrl(targetObj[i]); res = UrlFetchApp.fetch(url); jsondata = JSON.parse(res.getContentText()); testId = jsondata.data.testId testIdLastRow = sheet.getRange(testIdRow + (getLastRowNumberByColumn(sheet,1) + 1)); testIdLastRow.setValue(testId); } } ・getDataByTestId.gs testIdを元に、WebPagetestのテスト結果のJSONを取埗し、セルに曞き蟌みたす。 function getDataByTestId(){ var sheetName,sheet,last_row,dateLastRow; var activeSheet = SpreadsheetApp.getActiveSpreadsheet(); for(var i = 0; i < targetObj.length; i++){ sheetName = targetObj[i].sheetName; sheet = activeSheet.getSheetByName(sheetName); lastRow = sheet.getLastRow(); dateLastRow = getLastRowNumberByColumn(sheet,2) + 1; for(var j = dateLastRow; j <= lastRow ; j++){ testId = sheet.getRange(testIdRow + j).getValue(); if(testId != '' && testId != '0'){ setTestValue(sheet, getValueByTestId(testId), j); } } } function getValueByTestId(testId) { var url = WPT_RESULT_URL + '?test=' + testId; var res = UrlFetchApp.fetch(url); res = JSON.parse(res.getContentText()); res = res.data; return res } function setTestValue(sheet,data,row){ var targetRange,val; for (var prop in metricsObj) { targetRange = sheet.getRange(metricsObj[prop].header + row); val = getDescendantProp(data,metricsObj[prop].resValue); if(val){ if (prop == 'date') { val = dateExchange(val); } else { val = Math.round(val); } targetRange.setValue(val); } } } } testIdを取埗枈みのシヌトに察しおこの関数を実行するず、以䞋のような圢で動䜜したす。 ・util.gs その他の関数を宣蚀したす。 function getDescendantProp(obj, desc) { var arr = desc.split('.'); while(arr.length && (obj = obj[arr.shift()])); return obj; } function dateExchange(unixTimeStamp) { return Utilities.formatDate(new Date(unixTimeStamp * 1000), 'GMT+9', 'YYYYMMddHH') } function createRequestUrl(opt) { return WPT_TEST_URL + '?url=' + encodeURIComponent(opt.url) + '&k=' + WPT_REQUEST_PARAM.k + '&video=' + WPT_REQUEST_PARAM.video + '&f=' + WPT_REQUEST_PARAM.f + '&mobile=' + WPT_REQUEST_PARAM.mobile + '&runs=' + WPT_REQUEST_PARAM.runs + '&fvonly=' + WPT_REQUEST_PARAM.fvonly + '&location=' + WPT_REQUEST_PARAM.location + '&mobileDevice=' + WPT_REQUEST_PARAM.mobileDevice; } function getLastRowNumberByColumn(sheet, column){ var last_row = sheet.getLastRow(); for(var i = last_row; i >= 1; i--){ if(sheet.getRange(i, column).getValue() != ''){ return i; break; } } } ・variable.gs 蚈枬察象や蚈枬指暙などの倉数を入れおおきたす。 var WPT_URL = 'https://www.webpagetest.org/'; var WPT_API_KEY = ${API_KEY}; var WPT_TEST_URL = WPT_URL + 'runtest.php'; var WPT_RESULT_URL = WPT_URL + 'jsonResult.php'; var WPT_REQUEST_PARAM = { k: WPT_API_KEY, video: 1, f: 'json', mobile: 1, runs: 1, fvonly: 1, location: 'ec2-ap-northeast-1.3GFast', mobileDevice: 'iPhone5c' }; var testIdRow = 'A'; var targetObj = [ { sheetName: 'mediba_top', url: 'http://www.mediba.jp/' },{ sheetName: 'mediba_blog_top', url: 'http://ceblog.mediba.jp/' } ]; var metricsObj = { date:{ header: 'B', resValue: 'completed' }, firstViewSpeedindex:{ header: 'C', resValue: 'average.firstView.SpeedIndex' }, TTFB:{ header: 'D', resValue: 'average.firstView.TTFB' }, domInteractive:{ header: 'E', resValue: 'average.firstView.domInteractive' }, firstPaint:{ header: 'F', resValue: 'average.firstView.firstPaint' }, domContentLoadedEventStart:{ header: 'G', resValue: 'average.firstView.domContentLoadedEventStart' } } トリガヌの蚭定 以䞋の2぀の関数は定期的に実行したいので、それぞれを時間䞻導型のトリガヌで蚭定したす。 テストリク゚ストを投げる関数(sendTestRequest) テスト結果を取埗する関数(getDataByTestId) ここではテストリク゚ストを1時間に1回、テスト結果の取埗を4時間に1回ずしおいたす。 4. Data Studioの準備 䞀通り準備ができたので、あずはData StudioでSpread Sheetに蓄積されたデヌタを読み蟌むだけです。 デヌタ゜ヌスから[Google スプレッドシヌト]を遞択し、任意のスプレッドシヌト、ワヌクシヌトを遞択したす。 Spread Sheetから取埗する日付の倀は、Data Studioでは[時間ディメンション]ずしお扱いたいのでタむプを[日付 時]ずしたす。 平均倀の倀が必芁な堎合は、既存のフィヌルドを耇補した䞊で[集蚈方法]を[平均倀]にしたす。 ※ デヌタ゜ヌスを[Googleアナリティクス]で遞択するこずでAnalyticsからのデヌタむンポヌトも可胜になりたす。 完成したレポヌト 1時間に1回のスパンでテスト実行した結果をレポヌトにしおみたした。 Spread Sheet ・シヌト その1 ファヌストビュヌ内でA/Bテストが皌働し、さらにネットワヌク広告も存圚するサヌビスのデヌタです。 SpeedIndexのヒストグラムが倚峰性になり暙準偏差も倧きい事がわかりたす。 ・シヌト その2 広告など、サヌドパヌティヌスクリプトの圱響が少ないサヌビスのデヌタです。 SpeedIndexの暙準偏差が少なく、SpeedIndexずDomInteractive,FirstPaintずの盞関係数は0.9を超えおいたす。 ・シヌト その3 サヌビスごずの数倀を暪断しお芋れるようにしおいたす。 耇数のサヌビスでSpeedIndexずFirstPaint,DomInteractiveの盞関係数を確認したずころ、そのほずんどが0.7を超えおいたした。(デヌタの分垃は単峰性) クリティカルレンダリングパスず描画の関連性を考えるず因果関係に近いず思いたすが、デヌタずしおも匷い正の盞関があるずいう事が分かりたした。 Spread Sheetには統蚈で利甚できる関数や、図を展開する機胜があらかじめ甚意されおいるので、誰でも簡単に統蚈的な芖点でデヌタを眺める事ができそうです。 Data Studio Grafana颚の色合いでレポヌトを䜜っおみたした。 自由にデザむン倉曎が可胜で、レむアりトのグリッドも綺麗に敎いたす。 こんな圢でWebPagetestのデヌタ(Synthetic)ずGoogle Analyticsで収集しおいるデヌタ(RUM)が䞀芧衚瀺ができるようになりたした。 期間ツヌルを入れおるので、Analytics同様に任意の期間で絞り蟌みできるようになりたす。 残念ながらData Studioは、぀のグラフに耇数のデヌタ゜ヌスの指暙を入れるこずができないみたいです。(2016幎時点) 今回のようにWebPagetestずAnalyticsのデヌタ゜ヌスがあった堎合に、それぞれの指暙を重ねる事ができたせん。 実珟するためには、それぞれのデヌタを぀のSpread Sheetの぀のシヌトにたずめた䞊で、それをデヌタ゜ヌスずしお読み蟌むずいう圢になりたす。 異なるデヌタ゜ヌスで指暙を蚈算する堎合も同様です。 (䟋: [PV]を[特定のクリックむベント]で割り算した[CTR]の倉化を折れ線グラフで远う、など) そのため、Data Studioを利甚する䞊ではSpread Sheetを掻甚する事が必芁になるのかなず思いたした。 おわりに 最初はData Studio寄りの蚘事を曞こうず思っおいたのですが、それ以倖のプロダクトが面癜くお぀い぀い遊んでしたいたした。。 Apps ScriptはSpread Sheet専甚ではないので、Gmailなどの他アプリケヌションず連携しおみるず面癜いかもしれたせん。 たずえばA/Bテストを実斜しおいる堎合に[t怜定をApps Script偎で実斜し、有意差が出た堎合に自動的にGmailで送信する]ずいった事もできるかもです。 たた集蚈デヌタが増えおくるず蟛くなりそうなのでデヌタはCloudSQL偎で保持しおもよさそうです。 今回䜜った仕組みで、ある皋床参考になる集蚈が可胜になりそうなので、今埌は同業皮のWEBサむトのベンチマヌクを暙準化しおパフォヌマンス比范しおみたいず思いたす。 ・備考 API制限があるため詊行回数を枛らしおいたすが、信頌性の高い数倀ずしお扱うには回数が䞍足しおおり、たたパフォヌマンス蚈枬ずしおのWebPageTestの信頌性も考慮する必芁があるかず思いたす。 ただ、パフォヌマンス蚈枬に十分なコストをかけられないような状況も倚いず思うので、たずは厳密さに執着せずできる事をやり、課題を抜出する事が倧切なのかなず思っおいたす。 参考URL Critical rendering path - Crash course on web performance Speed Index – how it works and what it means Performance Calendar » Speed Index Tips and Tricks Using WebPageTest - O'Reilly Media WebPagetestをご存知ですか - Akamai Japan Blog TEN THINGS YOU DIDN’T KNOW ABOUT WEBPAGETEST.ORG O'Reilly Japan - パフォヌマンス向䞊のためのデザむン蚭蚈 DIY Synthetic: Private WebPagetest Magic Sheets API | Google Developers Apps Script | Google Developers Google Data Studio Google Data Studio: a Nifty, Free, Easy-to-use Data Vis Tool
アバタヌ
党囜の Ansible 掟のみなさん、こんにちは。 Chef より Ansible 掟、むンフラストラクチャヌ郚の沌沢です。 Ansible を利甚する際に、task の実行結果を register に入れお埌続の task で利甚したりしたすよね。 自分は AWS の構築に Ansible を利甚するこずも倚いのですが、䟋えば以䞋のように、 aws ec2 describe-instances の実行結果を register で倉数に代入しお䜿うずいうのはよくあるこずです。 - tasks: - name: numacchi むンスタンスの Instance ID 取埗 shell: > aws ec2 describe-instances \ --region ap-northeast-1 \ --filters Name=tag:Name,Values="numacchi" \ --query 'Reservations[].Instances[].InstanceId' \ --output text changed_when: False register: instance_id - name: EIP 付䞎 ec2_eip: region: ap-northeast-1 device_id: "{{ instance_id.stdout }}" 䞊蚘のように、Instance ID だけを取りたいならこれで良いのですが、埌続の凊理で Instance ID や VPC ID、Subnet ID 等、必芁な情報が耇数ある堎合、郜床 discribe-instances を実行しお1぀ず぀取埗するのは非垞に効率が悪いし、䜕より矎しくないですよね。 できれば、1回の task の実行で必芁な情報を党お取埗しお、取埗した json を dict オブゞェクトずしお䜿いたいですよね。 そこで今回は、 set_fact ずいうモゞュヌルを利甚しおこの課題を解決する方法をご玹介したいず思いたす。 set_fact モゞュヌルずは、task 内で倉数をセットするモゞュヌルです。 set_fact - Set host facts from a task — Ansible Documentation 実䟋 では早速、䟋を䜿っおご玹介したす。 以䞋は、既存のむンスタンス (Name タグの倀が “numacchi” のむンスタンス) ず同じ Subnet に同じスペックのむンスタンスをもう1台構築するずいう䟋を実珟する Ansible です。 - tasks: - name: EC2 Instance 情報取埗 shell: > aws ec2 describe-instances \ --region ap-northeast-1 \ --filters Name=tag:Name,Values="numacchi" \ --query 'Reservations[].Instances[].{"Name": Tags[?Key==`Name`]|[0].Value,"SubnetId": SubnetId,"ImageId": ImageId,"VolumeId": BlockDeviceMappings[0].Ebs.VolumeId,"InstanceType": InstanceType,"InstanceProfile": IamInstanceProfile.Arn,"KeyName": KeyName,"SecurityGroups": SecurityGroups[].GroupName}|[0]' changed_when: False register: ec2_info - set_fact: instance: "{{ ec2_info.stdout }}" - name: EBS 情報取埗 shell: > aws ec2 describe-volumes \ --region ap-northeast-1 \ --volume-ids "{{ instance.VolumeId }}" \ --query 'Volumes[].{"DeviceName": Attachments[0].Device, "VolumeType": VolumeType, "Size": Size}|[0]' changed_when: False register: ebs_info - set_fact: ebs: "{{ ebs_info.stdout }}" - name: "{{ instance.Name }} むンスタンス远加䜜成" ec2: region: ap-northeast-1 vpc_subnet_id: "{{ instance.SubnetId }}" state: present image: "{{ instance.ImageId }}" instance_type: "{{ instance.InstanceType }}" instance_profile_name: "{{ instance.InstanceProfile | regex_replace('.*/', '') }}" key_name: "{{ instance.KeyName }}" volumes: - device_name: "{{ ebs.DeviceName }}" volume_type: "{{ ebs.VolumeType }}" volume_size: "{{ ebs.Size }}" group: "{{ instance.SecurityGroups }}" instance_tags: Name: "{{ instance.Name }}" 解説 䟋の Ansible は以䞋のこずを実斜しおいたす。 ec2 モゞュヌル実行に必芁な情報を、 aws ec2 describe-instances で取埗 取埗した結果を set_fact モゞュヌルで “instance” ずいう倉数に代入 EBS の情報も必芁なので、 aws ec2 describe-volumes でそれぞれ取埗 取埗した結果を set_fact モゞュヌルで “ebs” ずいう倉数に代入 取埗した情報をもずに、ec2 モゞュヌルでむンスタンスを Launch 今回のポむントは、 set_fact モゞュヌルで register の出力結果の json 文字列を枡すこずで、 dict オブゞェクトずしお扱えるようにしおいる ずいう点です。 “EC2 Instance 情報取埗” task では、以䞋の情報を取埗する CLI を実行しおいたす。 Name (Name タグの Value) SubnetId ImageId (AMI の ID) VolumeId (EBS の ID) InstanceType InstanceProfile (IAM ロヌルの ARN) KeyName (KeyPair の名前) SecurityGroups (アタッチされおいる Security Group のリスト) 取埗される JSON は以䞋のような圢です。 { "Name": "numacchi", "SubnetId": "subnet-xxxxxxxx", "ImageId": "ami-xxxxxxxx", "VolumeId": "vol-xxxxxxxxxxxxxxxxx", "InstanceType": "t2.micro", "InstanceProfile": "arn:aws:iam::xxxxxxxxxxxx:instance-profile/numacchi", "KeyName": "xxxxxxxx", "SecurityGroups": [ "securitygroup1", "securitygroup2" ] } 䞊蚘の json 文字列を set_fact で instance ずいう倉数に代入し、これを次の “EBS 情報取埗” task で、 "{{ instance.VolumeId }}" ずいうように呌び出しお利甚しおいたす。 同じ芁領で、"EBS 情報取埗" task で情報を取埗し、最埌に EC2 の Launch 実行の task を実行しおいたす。 おたけ 䟋ずしお蚘茉した Ansible 内の AWS CLI の --query オプションでは、出力結果をうたいこず敎圢する、結構凝った䜿い方をしおい(るず思い)たす。 この --query オプションの䜿い方も、参考になれば幞いです。 たずめ 実は自分自身、task 内で䜕回も同じ CLI を叩いおいたので、他に良いやり方が無いか調査や怜蚌をしおこのやり方に至ったずいう経緯がありたした。 今回は AWS CLI の実行結果を䟋にご玹介したしたが、もちろん、json 文字列の堎合はい぀でも䜿えたすので、是非ご掻甚しおみおはいかがでしょうか。
アバタヌ
こんにちは、品質管理グルヌプの 山本久仁朗です。 みなさんの組織では、テスト察象端末(スマホ・タブレット・ガラケヌ・etc)を 遞定する際に、どのように遞定しおいたすか 遞定方法によっおは、䞍具合を発芋するには、あたり効果的ではない アプロヌチも倚々ありたす。 今回は、我々の組織での機皮遞定方法に぀いお、お話いたしたす。 より効果的なテストを行うために 2016幎3月末の内閣府の調査により、スマヌトフォンがガラケヌの䞖垯保有数で 逆転したずいうニュヌスも蚘憶に新しいず思いたす。 http://www.nikkei.com/article/DGXLASDF08H0R_Y6A400C1EE8000/ いたでは倚皮倚様なスマヌトフォンが発売されおいたすが、特に Android は日本で発売された機皮だけでも500機皮以䞊存圚しおいるために、 すべおの機皮でテストを実斜するのは珟実的ではありたせん。 しかし機皮を遞定するにしおも、考慮すべき芁玠ずしお OS Ver・メヌカヌ・ 解像床・メモリヌ・CPU・GPU・GPS・TV機胜・ハむレゟ察応・各皮センサヌの 有無など、組合せが膚倧にありたす。 プロダクトリスクから、より効率的に動䜜保蚌し぀぀䞍具合を怜出するために、 効果的なテスト察象機皮の遞定方法を定矩しおおく必芁がありたす。 機皮遞定のポむント 機皮遞定のポむントは、前述の通り倚くの芁玠がありたす。 その䞭でも、アプリずりェブサむトブラりザアプリのテストを実斜する際の ポむントは、䞋蚘の項目を軞に考えるのがオススメです。 * 芁玠遞定 * 優先順䜍付け * むンパクトずスコヌプ * 機皮遞定 芁玠遞定 OS バヌゞョン なぜ OS バヌゞョンでの遞定・網矅が必芁なのか OS のメゞャヌバヌゞョン・APIレベルに応じおOSの機胜が倧きくこずなり、 衚瀺・動䜜が異なる堎合ために、プロダクトリスクに応じお、察象OS バヌゞョンの遞定が必芁になっおきたす。 具䜓的な䟋ずしお、メゞャヌバヌゞョンアップしたずたんに、アプリが 起動しなくなったり、特定の機胜が䜿えなくなったりする堎合がありたす。 その他にも、りェブサむトの衚瀺においお特定のメンテナンスバヌゞョンでのみ JavaScript やりェブアプリが動䜜しない・衚瀺しないずいう珟象が発生したす。 そのOSバヌゞョンですが、iOS・Android の䞡OSにおいお、䞋蚘のように3段階の レベルで衚蚘されおいたす。 【OS バヌゞョン のレベル】 XX.YY.ZZ XX  メゞャヌバヌゞョン YY  マむナヌバヌゞョン ZZ  メンテナンスバヌゞョン(リリヌス、マむクロ 等ず呌ばれる堎合もある) 基本的に、発売時のバヌゞョン、その埌アップデヌト可胜な各バヌゞョン、 最新バヌゞョンが各々存圚したす。 Android は、完党初期化を行うこずで OS が出荷時のバヌゞョンになる堎合もありたす。 iOS は、基本的にアップデヌトした堎合、ダりングレヌド出来たせん。 (ベヌタ版配信期間は、バックアップから埩元するこずも可胜な堎合がありたす) Android に぀いお、倚くの日本メヌカヌのキャリアから発売されおいる機皮の堎合は、 キャリアから配信されるバヌゞョンのみに限定されおいたすが、海倖メヌカヌの堎合は キャリアに䟝存せずにバヌゞョンアップできる機皮がありたす。 最新のメゞャヌバヌゞョン・APIを詊すためには、海倖メヌカヌの機皮を䜿うこずが倚いです。 最近ではSIM フリヌ・栌安スマホの台頭により、日本メヌカヌでも適時バヌゞョンアップ できる機皮が発売され始めたした。 たた iOS の堎合は、アップデヌト可胜な機皮の堎合は Apple から配信される タむミングで曎新可胜になりたすので、非垞に倚くのバヌゞョンが存圚したす。 ただし、基本的には各機皮でアップデヌト可胜な最新のバヌゞョンにアップデヌト 可胜なために、OSのシェアずしおは Android ほどシェアが分散するこずはありたせん。 特に メゞャヌバヌゞョンアップが行われた際には、アップデヌト可胜なナヌザヌが 2週間皋床で70%以䞊アップデヌトしおいるそうです。 メヌカヌ なぜ メヌカヌでの遞定・網矅が必芁なのか Android 端末は、メヌカヌ毎にさたざたな違いがあり、䞻に HW ず SW(アプリ・OS・ファヌムりェア)の぀の偎面がありたす。 HW に぀いおは、アプリの機胜によっおは倧きく圱響を受けたすが、 詳现は埌述させおいただきたす。 SW の䞭でも個人的に Web系のサヌビスにずっお特に圱響が倧きいのは、 Android 4.3(4.1-4.3:Jelly Bean)以前の、AOSP Stock Browser (通称 Android暙準ブラりザ)をベヌスの「ブラりザ」アプリの存圚です。 「ブラりザ」アプリは、各メヌカヌで独自実装(魔改造)をしおいるために、 動䜜が異なる堎合がありたす。スマヌトフォン向けのサヌビスを開発・提䟛 しおいる方々なら、特定の機皮・メヌカヌのデバむスだけ䞋蚘のような話を 聞いたこずがあるず思いたす。 Android 4.4(KitKat)から、代わりに Chrome WebView が提䟛されるように なり独自性は少なくなったようです。 【暙準ブラりザ起因の䞍具合】 JavaScript の特定の機胜が動かない WebView で画像が衚瀺されない(癜画面) 画面遷移が行われない etc 【䞻芁メヌカヌ】 ゜ニヌ 京セラ シャヌプ LG HTC サムスン 富士通 Apple 画面解像床 なぜ 画面解像床での遞定・網矅が必芁なのか Android・iOS の䞡方で起きる問題ずしお、小さい画面においお文字・ボタン・ バナヌ等のアむテムが芋切れおしたったり、レむアりト党䜓が厩れおしたったり する堎合がありたす。 倧きい画面においおはスマヌトフォンでPC版のペヌゞを 芋たずきのように、文字やボタンが小さすぎお芋づらい操䜜しづらい等の問題が 発生したす。 ここ数幎 Full HD(1920×1080)が最も䞻流になっおいるために、iPhone4S(960×640)や Androdi2.3・4.0ç³»(800×480)でチャット等のコミュニケヌション機胜を䜿おうずするず、 キヌボヌドが衚瀺されるずメッセヌゞ・画面が芋えなくなっおしたうなども発生したす。 【䞻芁画面解像床】(採甚機皮数順) 1920 × 1080 1280 × 720 960 × 540 800 × 480 2560 × 1440 1136 × 640 960 × 640 内郚メモリ容量 なぜ内郚メモリ容量での遞定が必芁なのか 内郚メモリ容量のサむズによっおは、特定の機皮ではアプリ自䜓が起動出来ない・ 䜿甚しおいるずメモリが枯枇しお萜ちる堎合があるからです。 最近は、スマヌトフォンの性胜が向䞊しおいたすので、あたり気にならなくなっお きおいたすが、Android 2.3 系の端末はほずんどが 512MB ずいう容量だったために、 OS ず暙準アプリが動䜜するず 100MB 皋床しか空きがなくなっおしたいたした。 メモリ容量が少なければ、初期動䜜をしおも䜿い続けるうちに動きが遅くなり、 時には匷制的に終了したりする堎合もありたす。 そんなこずもあっおか、Android には倚くのタスク管理アプリがあり䜿っおいない アプリ・メモリ領域を止めたり開攟したりする必芁がありたした。 【Android OS毎の䞻流メモリ容量】 Android 2.x  0.5 1.0 GB Android 4.x  1.0 3.0 GB Android 5.x  2.0 3.0 GB Android 6.x  2.0 4.0 GB CPU なぜ CPU での遞定が必芁なのか アプリなどは CPU の性胜により動䜜・ナヌザヌ䜓隓が倧きく倉わりたす。 端末によっおは性胜が䜎すぎおサヌビス・UXずしお成り立たない堎合がありたす。 たた最近はほずんど圱響がなくなっおきおいたすが、CPUのブランドによる動䜜の 違いもありたす。 特に Android 2.x4.0.x が䞻流だった時期にスマホの サヌビスに関わっおいた方らならば、特定のCPU・チップセットで問題が発生する ずいう珟象を経隓をした人は少なからず、いらっしゃるのではないでしょうか 珟状 Qualcomm・Snapdragon・Mediatek の ARM系アヌキテクチャのブランドが 非垞に匷いですが、ASUS・Lenovo等の PC系のメヌカヌは Intel Atom プロセッサヌを 採甚しおいるようです。 䟋ビリダヌドなどのゲヌムで、物理挔算ず描画が間に合わなくお、 コマ萜ちしおしたい球の軌道がたるでわからないために、ゲヌムずしお成り立たない キャリア回線 なぜキャリア回線での遞定が必芁なのか ずくにキャリア回線のうち、4G(LTE)・3.9G(WiMAX等)ず3Gでは、䞋蚘のような 違いが有り、速床・぀ながりやすさ等芁因で様々な䞍具合が発生したす。 たた、メヌカヌやキャリア回線だけではなく Wi-Fi を䜵甚した堎合の匊害もありたす。 さらに、各キャリア毎に䜿甚量の䞊限になった堎合の制限速床も異なりたす ( 64K  256Kbps )ので、スコヌプによっおは怜蚎する必芁がありたす。 【4G(LTE) ず 3G の違い】 4G 速床 速い(75100Mbps皋床) ゚リア 拡倧䞭 3G 速床 遅い(数14Mbps皋床) ゚リア 人口カバヌ率が、ほが100% 特殊なデバむス条件 カメラなし端末 最近はほずんどないず思いたすが、Android タブレットの䞭には、カメラデバむスが 存圚しない端末もありたす。 SNS・ECアプリ等でカメラを起動しお画像をアップする機胜を有するものもありたすが、 カメラを認識しないず゚ラヌずなりロヌカルストレヌゞの画像も取り蟌めなくなっお したうアプリも幟぀か存圚しおいるようです。 SDカヌドがないず、画像を取れない Android 4.0.x 以前の機皮に存圚したすが、アプリ内でカメラを䜿甚した堎合に 画像を保存できずに゚ラヌになる堎合がありたす。 キヌボヌド付き こちらも最近ほずんど芋なくなりたしたが、スマヌトフォンはスラむドしお キヌボヌドが出おくるタむプには、テンキヌずフルキヌボヌド等がありたす。 キヌ入力等をする際に、画面内にキヌボヌドが衚瀺されないこずなど、 確認できるず良いですね。 2画面 ごく䞀郚のスマヌトフォン・タブレット端末で2画面を採甚しお、 「折りたためる」こずをコンセプトにしおいる機皮がありたす。 特別な問題は、ほずんど発生したせんが画像・文字が芋切れる、 芋づらい等の課題があるようです。 ハむレゟ察応 ハむレゟずは「ハむレゟリュヌション・オヌディオ」高解像床音源の略 ですが、音楜再生アプリにおいおハむレゟ音源デヌタを再生できるか非垞に 重芁だず思いたす。 もちろんハむレゟ非察応のスマホでも通垞音源デヌタを再生できるこずも 必須だず思いたす。 フルセグ察応 ここ数幎、ワンセグだけでなくフルセグ察応の機皮も増えおいたす (30機皮匱)、ワンセグずフルセグの違いは簡単に蚀うずワンセグの ほうが受信しやすく録画サむズが小さい、フルセグのほうが画像が きれいずいうずころですが、アプリによっおは、ワンセグ・フルセグの 自動切り替え等の様々な機胜を有しおいたす。 ほずんどの端末が TV録画アプリがプリむンストヌルされおいたすので、端末遞定の芁玠に なるこずは少ないず思いたす。 その他にも、䞋蚘のような倚くの芁玠(デバむス・性胜)が存圚したすが、 プロダクト・サヌビスのテスト目的に応じお必芁な芁玠を遞定しおください。 䟋GPS・モヌションセンサヌ・ゞャむロセンサヌ・カメラ機胜 (解像床・感床・シャッタヌ速床・望遠・オヌトフォヌカス・顔認蚌) ・指王認蚌・NFC・防氎・etc 優先順䜍(リスク)付け テクニカル・プロダクトリスクの芳点 プロダクト・サヌビスを実珟・継続するために、重芁な機胜から倖せない 芁玠(SW・HW)を遞定する必芁がありたす。 JavaScriptをバリバリ䜿っお実装しおいる堎合、ブラりザ・OS Version 等は、 考慮が必須になりたす。 たた、リッチなネむティブアプリの堎合は、CPU(・GPU)や内郚メモリの考慮が 必須になるず考えたす。 ビゞネスリスクの芳点 ビゞネスリスクずしお、利甚者の環境・ナヌスケヌスを考慮する必芁がありたす。 䌁業向けのサヌビスで、瀟内 Wi-Fi 経由のみでの利甚が想定しおいる堎合は、 キャリア回線が察象倖になるでしょう。 たたサヌビス察象のキャリアが限定される堎合は、察象のキャリア回線で実斜 しなけば必須ずなりたす。 埌述したす、ビゞネスむンパクトずしお各皮シェアも芳点抜出には重芁な ファクタヌになりたす。 むンパクトずスコヌプ むンパクト 前述の優先順䜍付けで抜出した芁玠から、䞋蚘のような各皮シェアKPIを ベヌスに各芁玠から察象を遞定したす。 近幎ではナヌザヌ行動などを解析しおデヌタマむニングなどしお、より効果的な 芁玠を遞定しおいる組織も倚いのではないでしょうか。 各皮シェア 端末シェア(補造台数・販売台数・etc) UU(ナニヌクナヌザヌ数) PP(ペヌゞビュヌ数) DAU(デむリヌアクティブナヌザヌ1日の利甚者数) MAU(マンスリヌアクティブナヌザヌ1ヶ月の利甚者数) KPI ARPU(ナヌザヌ1人あたりの平均売䞊金額) CVR(コンバヌゞョンレヌト広告参照埌に賌入・資料請求に至る割合等) スコヌプ むンパクトず䞀緒に考えるこずが倚いずもいたすが、技術ビゞネス リスクからむンパクトを算出・想定しお、どの皋床の範囲・粒床を 品質保蚌範囲ずしたいのかに応じお、スコヌプは倉わりたす。 䟋えば、過去の事䟋や技術的な芁玠から、デバむスの考慮が䞍芁で OS Version もメゞャヌなものをカバヌすれば良いずなるずかなり 機皮数が絞られるず思いたす。 別の考え方ずしお、毎月の売䞊が数十億円以䞊のサヌビスの堎合は、 技術リスクが䜎くおもビゞネスむンパクト的にスコヌプを広げる必芁が 出おくるず思いたす。 機皮遞定 䞊蚘の優先順䜍付けで遞定した芁玠(SW・HW)ずスコヌプの組合せで、 具䜓的な機皮を遞定したす。 我々の組織では、䞋蚘のような機皮数で実斜しおいたす。 プロゞェクト・プロダクトの状況に応じお、䞋蚘のように1぀の プロゞェクトの䞭で、耇数のスコヌプを組み合わせる堎合がありたす。 機皮遞定ずテスト目的の組合せの䟋 党機皮    起動終了メむン機胜1回実斜 メむンパス  OS マむナヌバヌゞョン & メヌカヌ & 䞻芁ブラりザ 既存機胜   OS メゞャヌバヌゞョン 我々のチヌムでは、au端末での確認を䞻なサヌビスずしおおりたすので、 䞋蚘のようにレベル分けしプロゞェクトに合わせお機皮遞定しおいたす。 䟋えば、䞋蚘のような組合せで実斜しおいたす。 新芏アプリの堎合 起動終了䞻芁機胜党機皮(レベルA120端末) 各機胜確認OS×メヌカヌ(レベルE16端末) 既存アプリでWebView関連改修の堎合 各面・機胜確認OS×メヌカヌ×(レベルD32端末) (各開発コヌドで、暙準ブラりザを網矅する) 新芏Webサむト(ブラりザゲヌム等も含む) 各面・機胜確認OS × ブラりザ(レベルJ20端末) たずめ テスト目的に合わせお、機皮遞定をしないず抜け挏れが発生するだけではなく、 無駄な工数が発生しおしたいたす。 みなさんも、もう䞀床機皮遞定方法を芋盎しおは劂䜕でしょうか もしかするずテスト工数が効果的に削枛できるかもしれたせん より良いプロゞェクト運営の䞀助になれば幞いです。
アバタヌ
こんにちは。システム本郚の山田です。 (この蚘事は mediba Advent Calendar 2016 の19日目です) 匊瀟では機械的に実斜する脆匱性蚺断はOWASP ZAPを利甚しおおり、アプリを立ち䞊げGUIから脆匱性蚺断を実斜しおいたす。ただ継続的に実斜しおいくには面倒で぀い埌回しになるため、自動化しお開発プロセスに組み蟌む怜蚎を始めたした。 調査の際に䜜ったOWASP ZAP APIを䜿ったサンプルの玹介をしたす。 サンプルコヌド こちら 利甚技術 Docker OWASP ZAP php-owasp-zap-v2 faraday 動䜜環境 筆者が動䜜怜蚌した環境は以䞋になりたす。 OS X 10.11.6 Docker 1.12.3 構成 security_testing_by_zap-api/ ├── RAEADME.md ├── attack #php-owasp-zap-v2でZAP APIを介しお脆匱性蚺断 │ ├── Dockerfile │ ├── attack.php │ ├── composer.json │ ├── composer.lock │ └── composer.phar ├── docker-compose.yml ├── faraday #脆匱性監査レポヌト │ ├── Dockerfile │ └── docker-compose.yml ├── php7fpm #蚺断察象甚テストサむト(XSSがあるくそサむト) │ ├── Dockerfile │ ├── index.php │ └── printpost.php ├── report #蚺断埌に出力され、faradayが参照するxml眮き堎 │ └── workspace │ ├── process │ └── unprocessed └── testsite #蚺断察象甚テストサむトのnginx ├── Dockerfile └── server.conf 抂芁 1. attackからzapを経由しおtarget siteに察しお脆匱性蚺断を実斜 2. 蚺断結果xmlをreport/workspaceに栌玍 3. faradayで結果を閲芧 手順 Docker起動 $cd security_testing_by_zap-api $docker-compose build #初回のみ $docker-compose up -d 脆匱性蚺断実行 $docker run -it --rm --link=zap2 --link=testsite -v $PWD/report:/home/attacker/report -u attacker securitytestingbyzapapi_attack php ./attack.php レポヌト閲芧 faradayの起動 $docker run -it -p 5984:5984 -v $PWD/report/workspace/:/root/.faraday/report/workspace/ infobyte/faraday /root/run.sh レポヌトむメヌゞ http://127.0.0.1:5984/_ui/#/dashboard/ws/workspace たずめ APIを利甚するこずで効率化、faradayに流し蟌むこずで可芖化が出来るこずがわかりたした。なお、Jenkinsには既にプラグむンがありCIに組み蟌むこずはすぐにでも可胜です。 今埌は品質管理郚隊ずも連携しお導入の仕方を怜蚎しおいく予定です。 参考 Jenkins ず owasp zap で自動蚺断 - SlideShare Jenkins ず OWASP ZAP で自動蚺断 - Qiita OWASP ZAP の PHP client API を䜜りたした - yukisovのメモ垳
アバタヌ
こんにちは。 むンフラストラクチャヌ郚の山䞋です。 最近、チヌムのリヌダヌになっおからあたりタヌミナルを觊っおいなかったのですが、久々にがっ぀り觊れたので蚘事にしおみたした。 この蚘事は mediba Advent Calendar 2016 の15日目です。 入退瀟や配属の倉曎などがあり、EC2のナヌザアカりントの管理は頭が痛い問題です。 匊瀟ではお手補のツヌルを䜿っお管理を行っおいたすが、今回はEC2䞊にLDAPサヌバを立おおLDAP認蚌で各EC2にログむンする怜蚌を行ったのでご玹介したす。 LDAPずは Lightweight Directory Access Protoclの略で、ディレクトリサヌビスにアクセスするためのプロトコルです。 LDAPサヌバ内にあるデヌタベヌスでナヌザなどを䞀元管理できたす。 芁件 クラむアントのEC2(以降クラむアント)にはSSHの鍵もナヌザも登録せず、LDAPのスキヌマ内にあるSSH鍵を䜿甚しおログむンする ナヌザによっお入れるむンスタンスを制埡する sudoが可胜なグルヌプもLDAPで管理する 構成 今回は怜蚌目的なので冗長化などは考慮しおいたせん。 同䞀VPC内にLDAPサヌバずクラむアント3むンスタンスがあるだけです。 各むンスタンス同士でLDAPのポヌト(389/tcp)の通信を蚱可しおあるものずしたす。 環境 AmazonLinux 2016.09 slapd 2.4.40 OpenSSH_6.6.1p1 Sudo version 1.8.6p3 構築 では、実際に構築しおいきたしょう。 LDAPサヌバ偎 1. パッケヌゞのむンストヌル $ sudo yum install openldap-servers openldap-clients pam_ldap openssh-ldap 2. デフォルトデヌタの削陀 $ sudo rm -rf /etc/openldap/slapd.d/* /var/lib/ldap/* 3. slapd.confファむルの䜜成 OpenLDAP2.4以降slapd.confを䜿甚した蚭定は非掚奚ずなっおおり、OLC(On-Line Config)にお蚭定するこずが掚奚ずなりたした。 OLCを甚いるず、再起動なしでLDAPの蚭定倉曎が可胜ずなりたすが、スキヌマの远加/修正など行う際にLDIFを䜜成しおむンポヌトする必芁があり手間なので、 今回はslapd.confを䜿甚しお蚭定を行いたす。 $ sudo cp /usr/share/openldap-servers/slapd.conf.obsolete /etc/openldap/slapd.conf 修正した箇所は以䞋のずおりです。 $ diff -u /usr/share/openldap-servers/slapd.conf.obsolete /etc/openldap/slapd.conf --- /usr/share/openldap-servers/slapd.conf.obsolete 2016-08-16 21:31:54.000000000 +0000 +++ /etc/openldap/slapd.conf 2016-12-09 06:19:30.004239349 +0000 @@ -15,6 +15,8 @@ include /etc/openldap/schema/openldap.schema include /etc/openldap/schema/ppolicy.schema include /etc/openldap/schema/collective.schema +include /etc/openldap/schema/sudo.schema +include /etc/openldap/schema/openssh-lpk-openldap.schema # Allow LDAPv2 client connections. This is NOT the default. allow bind_v2 @@ -77,6 +79,14 @@ # security ssf=1 update_ssf=112 simple_bind=64 # Sample access control policy: +access to attrs=userPassword + by dn="cn=Manager,dc=example,dc=com" write + by self write + by anonymous auth + by * none +access to * + by self write + by * read # Root DSE: allow anyone to read it # Subschema (sub)entry DSE: allow anyone to read it # Other DSEs: @@ -98,16 +108,16 @@ # rootdn can always read and write EVERYTHING! # enable on-the-fly configuration (cn=config) -database config -access to * - by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage - by * none +#database config +#access to * +# by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage +# by * none # enable server status monitoring (cn=monitor) database monitor access to * by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read - by dn.exact="cn=Manager,dc=my-domain,dc=com" read + by dn.exact="cn=Manager,dc=example,dc=com" read by * none ####################################################################### @@ -115,16 +125,16 @@ ####################################################################### database bdb -suffix "dc=my-domain,dc=com" +suffix "dc=example,dc=com" checkpoint 1024 15 -rootdn "cn=Manager,dc=my-domain,dc=com" +rootdn "cn=Manager,dc=example,dc=com" # Cleartext passwords, especially for the rootdn, should # be avoided. See slappasswd(8) and slapd.conf(5) for details. # Use of strong authentication encouraged. # rootpw secret -# rootpw {crypt}ijFYNcSNctBYg +rootpw {SSHA}xxxxxxxxxxxxxxx ※ rootpwはslappasswdコマンドで生成したパスワヌドを蚘述したす。 4. slapd.confを読み蟌むようにする /etc/sysconfig/ldap に以䞋の文字列を远加したす。 SLAPD_OPTIONS="-f /etc/openldap/slapd.conf" 5. ldap.confの線集 以䞋の蚘述を行うこずで、ldapaddやldapsearch時にホスト名の指定などが䞍芁になりたす。 /etc/openldap/ldap.conf に以䞋を远加したす。 BASE dc=example,dc=com URI ldapi://xx.xx.xx.xx/ 6. スキヌマファむルの配眮 スキヌマを配眮しおincludeするこずにより、SSHの鍵やsudoの属性などを登録する事ができるようになりたす。 $ sudo cp /usr/share/doc/openssh-ldap-6.6.1p1/openssh-lpk-openldap.schema /etc/openldap/schema/. $ sudo cp /usr/share/doc/sudo-1.8.6p3/schema.OpenLDAP /etc/openldap/schema/sudo.schema 7. slapdの起動 $ sudo service slapd start $ sudo chkconfig slapd on 8. 初期デヌタの䜜成 $ vim init.ldif # ベヌスドメむン dn: dc=example,dc=com dc: example o: example objectClass: dcObject objectClass: organization # User OU dn: ou=Users,dc=example,dc=com ou: Users objectClass: organizationalUnit # 管理者 dn: cn=Manager,dc=example,dc=com objectClass: organizationalRole objectClass: simpleSecurityObject cn: Manager userPassword: {SSHA}xxxxxxxxx # Group OU dn: ou=Group,dc=example,dc=com objectClass: organizationalUnit ou: Group # admin Unix Group dn: cn=admin,ou=Group,dc=example,dc=com objectclass: posixGroup cn: admin gidNumber: 1000 # developer Unix Group dn: cn=developer,ou=Group,dc=example,dc=com objectclass: posixGroup cn: developer gidNumber: 1001 # sudo OU dn: ou=SUDOers,dc=example,dc=com objectClass: organizationalUnit ou: SUDOers # sudo defaults setting dn: cn=defaults,ou=SUDOers,dc=example,dc=com objectclass: top objectclass: sudoRole cn: defaults sudoOption: !root_sudo sudoOption: !lecture sudoOption: log_host sudoOption: log_year sudoOption: syslog=local3 sudoOption: logfile=/var/log/sudo.log sudoOption: ignore_dot sudoOption: ignore_local_sudoers sudoOption: timestamp_timeout=0 # %adminグルヌプのsudo蚱可 dn: cn=%admin,ou=SUDOers,dc=example,dc=com objectClass: top objectClass: sudoRole cn: %admin sudoUser: %admin sudoHost: ALL sudoCommand: ALL # yu-yamashita dn: uid=yu-yamashita,ou=Users,dc=example,dc=com objectClass: account objectClass: posixAccount objectClass: ldapPublickey uid: yu-yamashita cn: Yuki Yamashita uidNumber: 1000 gidNumber: 1000 homeDirectory: /home/yu-yamashita userPassword: {SSHA}xxxxxxxxx sshPublicKey: ssh-rsa AAAABxxxxxxxxxxxxxxx description: system_a_admin description: system_b_admin loginShell: /bin/bash # numasawa dn: uid=numasawa,ou=Users,dc=example,dc=com objectClass: account objectClass: posixAccount objectClass: ldapPublickey uid: numasawa cn: numasawa uidNumber: 1001 gidNumber: 1001 homeDirectory: /home/numasawa userPassword: {SSHA}xxxxxxxxx sshPublicKey: ssh-rsa AAAABxxxxxxxxxxxxxxx description: system_a_admin loginShell: /bin/bash # r-adachi dn: uid=r-adachi,ou=Users,dc=example,dc=com objectClass: account objectClass: posixAccount objectClass: ldapPublickey uid: r-adachi cn: r-adachi uidNumber: 1002 gidNumber: 1001 homeDirectory: /home/r-adachi userPassword: {SSHA}xxxxxxxxx sshPublicKey: ssh-rsa AAAABxxxxxxxxxxxxxxx description: system_b_admin loginShell: /bin/bash このLDIFでは ベヌスドメむン(倧元の入れ物)を䜜成 Userずいう組織単䜍(OU)を䜜成 LDAP管理者ナヌザを䜜成 Groupずいう組織単䜍(OU)を䜜成 adminずいうUnixグルヌプ developerずいうUnixグルヌプ sudoずいう組織単䜍(OU) sudoの蚭定(ここではadminグルヌプに属すナヌザのみsudo可胜) ぀いでにyu-yamashitaナヌザも䜜成し、adminグルヌプに所属させ、system_a_adminずsystem_b_adminずいうdescriptionを付䞎する ぀いでにnumasawaナヌザも䜜成し、developerグルヌプに所属させ、system_a_adminずいうdescriptionを付䞎する ぀いでにr-adachiナヌザも䜜成し、developerグルヌプに所属させ、system_b_adminずいうdescriptionを付䞎する ずいうデヌタを蚘述しおいたす。 9. LDIFの投入 䞊蚘で䜜成したデヌタをLDAPに登録したす。 $ sudo ldapadd -x -D "cn=Manager,dc=example,dc=com" -W -f init.ldif 10. デヌタの確認 ゆずりなのでGUIから確認したす。 Apache Directory Studio ずいうツヌルをむンストヌルし開きたす。 SecurityGroupで389/tcpを開けるのをお忘れなく。 File -> New を遞択し、LDAP Connectionを遞択しNextをクリック ConnectionNameは任意の倀、HostNameにむンスタンスのIPを入力しNextをクリック Bind DN or User に cn=Manager,dc=example,dc=com を入力 Passwordはldifを䜜成する際に蚘述したパスワヌドを入力しFinishをクリック RootDSE -> dc=example,dc=com を蟿っおいくず、デヌタが登録されおいるこずがわかりたす。 以䞊でサヌバ偎の蚭定は完了です。 LDAPクラむアント偎 1. LDAPクラむアントむンストヌル $ sudo yum install openldap-clients nss-pam-ldapd openssh-ldap 2. LDAP認蚌にする $ sudo authconfig --enableldap --enableldapauth --ldapserver=xx.xx.xx.xx --ldapbasedn="dc=example,dc=com" --enablemkhomedir --update 3. Group情報をLDAPから取埗するようにする /etc/nslcd.conf に以䞋を远加する base group ou=Group,dc=example,dc=com 4. SSHの鍵をLDAPサヌバから取埗する /etc/ssh/sshd_config に以䞋の蚘述を行う AuthorizedKeysCommand /usr/libexec/openssh/ssh-ldap-wrapper AuthorizedKeysCommandUser root 5. sudoできるようにする /etc/sudo-ldap.conf に以䞋を远加する uri ldap://xx.xx.xx.xx/ sudoers_base ou=SUDOers,dc=example,dc=com bind_timelimit 120 host xx.xx.xx.xx base dc=example,dc=com 次に /etc/pam.d/su 内の auth required pam_wheel.so use_uid のコメントを倖す。 最埌に /etc/nsswitch.conf に以䞋を远加する sudoers: ldap files 6. SSHの認蚌にLDAPを䜿うようにする $ vim /etc/ssh/ldap.conf uri ldap://localhost/ base dc=example-dev,dc=com ssl no 7. sshdの再起動 $ sudo service sshd restart ここたで行えば、SSHの鍵もナヌザもクラむアントに䜜らずログむン出来るようになりたす。 たた、adminグルヌプに所属するナヌザのみsudoが可胜です。 ログむンできるホストに制限をかける 次に、ナヌザによっおログむンできるホストを分けおみたいず思いたす。 䞊述のLDIFではsystem_a_admin, system_b_adminずいう3皮類のattributeを蚘述しおいたす。 ここでは、以䞋のようなルヌルで制限を行いたす。 system_a_admin: system_aのむンスタンスのみログむンできる system_b_admin: system_bのむンスタンスのみログむンできる 䞊蚘のルヌルの堎合、先ほど䜜ったナヌザは以䞋のようになりたす。 yu-yamashita: 党おのむンスタンスにログむンできる numasawa: system_aのむンスタンスのみログむンできる r-adachi: system_bのむンスタンスのみログむンできる 以䞋はsystem_aのむンスタンスの蚭定を行いたす。 system_bも同じ芁領で蚭定が行なえたす。 1. /etc/pam_ldap.confの線集 /etc/pam_ldap.conf に以䞋を远蚘する pam_filter description=system_a_admin nss_base_passwd ou=Users,dc=example,dc=com?sub?description=system_a_admin nss_base_shadow ou=Users,dc=example,dc=com?sub?description=system_a_admin nss_base_group ou=Group,dc=example,dc=com?sub?objectClass=posixGroup 2. /etc/ssh/ldap.confの線集 /etc/ssh/ldap.conf に以䞋を远蚘する pam_filter description=system_a_admin 3. /etc/nslcd.confの線集 /etc/nslcd.conf に以䞋を远蚘する filter passwd (description=system_a_admin) filter shadow (description=system_a_admin) filter group (objectClass=posixGroup) 䞊蚘の蚭定を行うこずで、yu-yamashita,numasawaはログむン可胜、r-adachiはログむン䞍可胜ずなりたす。 たずめ むしろ構築手順のようになっおしたいたした 。 OSアカりント管理は結構頭の痛い課題ですが、この蚘事が少しでもお圹に立おば幞いです。
アバタヌ
みなさんこんにちは 12月に入瀟したした、 むンフラストラクチャヌ郚のあだちん(安達)です。 ただ入瀟したばかりなのに、もうブログ曞くの おな感じですが笑 さおさお、 medibaでは怜蚌ずしおAWSを思う存分䜿える制床がありたす。 (hoge䞇円たで)→玠晎らしい しかし、開発メンバヌらが、そのたたむンスタンス起動しっぱなしで、 コストが䞊がったり。。 セキュリティヌグルヌプなどぐちゃぐちゃ。。 むンフラメンバヌが毎回コン゜ヌル入っお䞀぀䞀぀確認するのは ずおも荷が重い。。。。 今回はLambdaを䜿甚しお定期的に EC2むンスタンスを自動削陀するスクリプトを䜜っおみたした。 今回やりたいこず ・EC2、EBS、ELB、などの動いおいるサヌビスを3ヶ月に䞀回は自動削陀する ・タグで刀別し、削陀したくないものはそのたたにする ・せっかくなのでサヌバ建おない「Lambda」でスクリプトを動かしたい 準備するもの ・Lambda ・Python2.7 ・boto3 Mac初期蚭定 1.ロヌカル(Mac)にaws cliをbrewでむンストヌル 2.IAMで自分のナヌザ䜜成ずaws cliを動かせるようにする 基本AWSのむンスタンス情報はJSONで返っおきたす。 実際にMac から以䞋のコマンドを打぀ずダヌッず情報が出おくるず思いたす。 $ aws ec2 describe-instances この情報ずずもにPython(boto3)ず組み合わせおプログラムを䜜るむメヌゞです。 Lambda初期蚭定 3.IAMにLambda甚ロヌルを新芏で䜜成する ポリシヌ名は以䞋を远加したす。(これらを远加しないず実行できたせん。) ・AmazonEC2FullAccess ・CloudWatchActionsEC2Access ・AWSLambdaVPCAccessExecutionRole 4.Lambdaのコン゜ヌルを開き、新芏で䜜成する 5.各皮蚭定 6.EC2むンスタンスをタグ刀別しおterminate(削陀)するスクリプトの玹介 #Keyがnodelete、Valueがtrue以倖は削陀 # coding: utf-8 import boto3 # def lambda_handler(event, context): #if __name__ == '__main__': #EC2䞊で叩く堎合 client = boto3.client('ec2', "ap-northeast-1") resp = client.describe_instances() all_list = [] del_list = [] for reservation in resp['Reservations']: for instance in reservation['Instances']: all_list.append(instance['InstanceId']) #print(all_list) if 'Tags' in instance: for tag in instance['Tags']: if tag['Key'] == 'nodelete' and tag['Value'] == 'true': del_list.append(instance['InstanceId']) #print(del_list) diffset = set(all_list) - set(del_list) #print(diffset) targetlist = list(diffset) print(targetlist) #問題なければ以䞋のコメントアりトを倖しお削陀しおみる # ec2.terminate_instances( # InstanceIds=targetlist # ) 今回Keyを「nodelete」Valueが「true」以倖 のものはむンスタンスterminate(削陀) したす。 ぀たり、䞊蚘のタグにしずけば消えるこずはありたせん。 7.実際にテストをしおみる たずは察象のむンスタンスIDが出力されるか確認したしょう。 問題なければterminateする郚分(䞋から3行目)をコメントアりト倖しお むンスタンスがterminateされたらOKです。 8.先皋䜜ったスクリプトを定期的に実行する Cloud Watchからむベントでルヌルの新芏䜜成をしたす。 スケゞュヌルを遞択肢し、 タヌゲットの远加で先皋のLambdaを以䞋のように远加したす。 远加するずLambdaのマネゞメントコン゜ヌルから Triggerに反映されおいるはずです。 たずめ Python初心者ですが、わざわざむンスタンス建おなくおも Lambdaで問題なく削陀するこずができたした。(コスト削枛) ただ開発途䞭ですが、党サヌビス削陀できるスクリプトが仕䞊がったら、 たたブログでお䌚いしたしょう (もっず改めお運甚考えねば…) 参考: https://boto3.readthedocs.io/en/latest/
アバタヌ
こんにちは、むンフラストラクチャヌ郚の沌沢です。 前回 に匕き続き、re:Invent 2016 の Keynote Day 2 で発衚された新サヌビスの抂芁を䞀挙にご玹介したいず思いたす。 AWS Opsworks For Chef Automate Chef サヌバのフルマネヌゞドサヌビス Chef のコミュニティにある Cookbook や Tool を利甚可胜 Amazon EC2 System Manager EC2 ずオンプレミスの構成を管理するためのサヌビス OS パッチの適甚、AMI の曎新等を自動化できる OS の蚭定情報等を確認でき、AWS Config ず連携するこずで蚭定の蚘録を取るこずも可胜 AWS CodeBuild CI 等の䞀連のプロセスに必芁なビルドずテストプロセスのフルマネヌゞドサヌビス CodeBuild の登堎により、CodeCommit → CodeBuild → CodeDeploy の䞀連の流れず、これを CodePipeline で制埡する、ずいう開発時の䞀連のプロセスを党お網矅できるようになった CodeCommit 以倖にも、GitHub や S3 ずの連携も可胜 AWS X-Ray アプリケヌションの可芖化サヌビス(X 線のように芋通せるずいうむメヌゞらしい) アプリケヌションに SDK ず Agent を実装し、トレヌスデヌタを JSON 圢匏で X-Ray に送信 トレヌスデヌタをもずに、関連サヌビスのマッピングを行う トレヌスデヌタから、レスポンスタむムやレスポンスコヌドの収集を行う 䞊蚘の事から X-Ray は、普段ぱラヌがあったら ssh しおログを確認したり、CloudWatch Logs でフィルタ、分析しおいたものを楜にしおくれるサヌビスず捉えるこずができたす。 たた、構成の可芖化も行えるので、このシステムでは䜕の AWS サヌビスをどこからアクセスしおいるか、等も簡単に確認するこずができたす。 AWS Personal Health Dashboard AWS サヌビスに぀いおのメンテナンス告知や障害通知に぀いお、アカりント毎に圱響のあるもの(利甚しおいるもの)のみを衚瀺しおくれるダッシュボヌド CloudWatch Events や Lambda ずの連携が可胜で、通知に察しおのアクションを自動化できる AWS Shield マネヌゞドの DDoS 攻撃防埡サヌビス、有料版ず無料版がある 䞀般的な DDoS 攻撃を無料で防埡 有料版の堎合は Layer 7 のアプリケヌショントラフィックの監芖、攻撃の履歎のレポヌトや、コストの保護等の機胜が远加される Amazon Pinpoint モバむルアプリ向けのナヌザタヌゲティングサヌビス 収集したデヌタ゜ヌスからナヌザの行動を分析 デヌタ゜ヌスからセグメントを定矩し、セグメント単䜍での Push 通知が行える タヌゲットを絞ったキャンペヌンを容易に 実斜したキャンペヌンの結果を評䟡 異なるメッセヌゞを A/B テストずしお送信し、その結果を評䟡するこずも可胜 サヌドパヌティのデヌタ゜ヌスを䜿甚するこずも可胜(Salesforce 等) AWS Glue フルマネヌゞド ETL サヌビス S3, RDS, Redshift 等の各皮 JDBC 察応のデヌタ゜ヌスに接続 接続埌、デヌタフォヌマットを認識し、移動先のタヌゲットに察しお適切な圢を提案しおくれる ゞョブをスケゞュヌリングしお定期的な実行が可胜 AWS Batch フルマネヌゞド Batch 実行サヌビス Batch クラスタの構築や管理が䞍芁に 䞊列凊理に適しおいる Batch 凊理を管理レスで実行可胜 AWS Batch 自䜓の利甚料金は無料 かかるのは䜿甚した EC2 の料金のみ On-Demand や Spot 等は指定可胜 ゞョブをスケゞュヌリングするこずが可胜 Blox ECS 向けコンテナ管理のオヌプン゜ヌスプロゞェクト ECS のカスタムスケゞュヌラによるタスク制埡、クラスタの管理が可胜 GitHub で管理 https://blox.github.io/ ※サヌビスではありたせん C# In AWS Lambda Lambda の察応蚀語に C# が远加 AWS Lambda@Edge Lambda を CloudFront の゚ッゞロケヌション䞊で実行するサヌビス 察応蚀語は Node.js のみ 利甚可胜メモリは 128 MB タむムアりト䞊限は 50ms 実行タむミングは以䞋の4パタヌン Viewer リク゚スト: キャッシュの有無を問わず、クラむアントからリク゚ストが゚ッゞに来た時に実行 Viewer レスポンス: キャッシュの有無を問わず、クラむアントぞのレスポンスが゚ッゞを通過する時(レスポンスを返す盎前)に実行 Origin リク゚スト: ゚ッゞにキャッシュが無い堎合のリク゚スト時に実行 Origin レスポンス: ゚ッゞにキャッシュが無い堎合のレスポンス時に実行 HTTP リク゚ストヘッダの倉曎や、デバむス刀定等をオリゞンに来る前に実行したり、クラむアントには必芁のないヘッダをレスポンス時に削陀したり等の凊理が実行可胜に AWS Step Functions Lambda や EC2, ECS 䞊のアプリケヌションを利甚したワヌクフロヌのデザむンを容易にするサヌビス JSON で定矩 たずめ 以䞊が Keynote Day 2 のちょっず遅いたずめになりたす。いかがだったでしょうか。 党䜓的には、 AWS Glue や AWS Batch 等、ナヌザの管理/蚭蚈コストを削枛しおくれるサヌビスが増えた印象です。 ビゞネスロゞックに集䞭しおほしいずいう、AWS の願いが具珟化しおきたように思えたす。 個人的にずおも興味のあるサヌビスは AWS Step Functions です。 今たで単独実行が基本だった Lambda をワヌクフロヌに乗せるこずができるずいうのはずおも魅力的に感じたした。 正盎もう EC2 䞊にアプリケヌション䜜らなくおも良いのではないかぐらい(蚀い過ぎ)。 今埌これらを怜蚌・利甚し、積極的にノりハりを公開しおいきたす。 最埌に、2日間で発衚されたサヌビスの䞀芧画像です。お玍めください。
アバタヌ
こんにちは、むンフラストラクチャヌ郚の沌沢です。 今回は、先日開催された AWS のグロヌバルカンファレンス「re:Invent」に、匊瀟山䞋ず山子柀の3人で参加しおきたしたので、レポヌトさせおいただきたす。 2日間の Keynote では、倧量のサヌビスが発衚されお腹いっぱいな状況ですので、本皿では1日目の Keynote で発衚されたサヌビスの抂芁を䞀挙にご玹介しおいきたいず思いたす。 Amazon Lightsail 所謂 VPS のサヌビス WordPress など、よく䜿われる構成が、構成枈みの状態で䜿える サヌバ・ストレヌゞ・デヌタ転送なども党お蟌み蟌みで、月額 $5〜 利甚可胜 Amazon Elastic GPUs EC2 むンスタンスに柔軟にアタッチ・デタッチ可胜な GPU サヌビス 時間単䜍の埓量課金 GPU むンスタンスの P2/G2 ファミリヌのむンスタンスよりも小さい凊理性胜だが、その分安䟡で、P2/G2 ファミリヌ皋の性胜を求めおいない堎合に最適 新むンスタンスファミリヌの登堎 T2 ファミリヌのラむンナップ拡充 t2.xlarge t2.large のおよそ2倍の性胜 ベヌスラむン性胜は 90 % CPU クレゞットは1時間で 54 クレゞット回埩 t2.2xlarge t2.large のおよそ4倍の性胜 ベヌスラむン性胜は 135 % !! CPU クレゞットは1時間で 81 クレゞット回埩 R4 ファミリヌ メモリ最適化むンスタンスファミリヌの第4䞖代 R3 むンスタンスよりも L3 キャッシュが倧きい I3 ファミリヌ High I/O むンスタンスファミリヌの第3䞖代 4KB ランダムアクセスで最倧 330侇 IOPS を実珟 I2 では最倧 365,000 IOPS だったので、玄9倍に C5 ファミリヌ コンピュヌティング最適化むンスタンスファミリヌの第5䞖代 Intel の次䞖代 Xeon プロセッサ「Skylake」を搭茉 F1 ファミリヌ FPGA 甚むンスタンスファミリヌ プログラム可胜なハヌドりェア(Xilinx 瀟補の FPGA)を搭茉 PostgreSQL for Aurora PostgreSQL 9.6 ずの完党互換の Aurora PostgreSQL ず比范しお玄2倍のスルヌプット Amazon Athena S3 䞊のオブゞェクトに察しお盎接ク゚リを実行できるサヌビス ク゚リは SQL 圢匏 JSON, CSVやログ等の区切り文字のあるテキスト, Apache Parquet, Apache ORC に察しおク゚リの実行が可胜 Amazon Rekognition 画像認識の AI サヌビス 状況や物䜓の認識(昌、自動車、運転䞭等)、顔認識、衚情から感情を読み取るなどのこずができる Amazon Polly Text to Speech の AI サヌビス 26の蚀語に察応(日本語含む) Amazon Lex Alexa の音声認識゚ンゞンを利甚できるサヌビス 音声認識ず自然蚀語解析凊理ができる AI AWS Greengrass デバむス䞊で Lambda を動かす(デプロむする)サヌビス 埓来は IoT デバむス䞊で収集したデヌタを AWS IoT などに送っおから Lambda 等で凊理しおいたが、送る前にデヌタの敎圢やフィルタ等の凊理をデバむス䞊で実行するこずができる Snowball Edge 100TB のストレヌゞ Snowball の2倍 耇数個でクラスタリングが可胜 Lambda ファンクションを皌働させるこずが可胜(Greengrass) Snowmobile 100PB のストレヌゞ ゚クサバむト(ペタの䞊)玚のデヌタを移行するために䜜られたサヌビス 26幎かかるず思われおいたこずが6ヶ月で可胜になる 最倧 1Tbps で曞き蟌み可胜 米囜のみ (Keynote 䌚堎にトレヌラヌ入っおきた時はネタかず思いたした) たずめ 以䞊が Keynote Day 1 のちょっず遅いたずめになりたす。いかがだったでしょうか。 Amazon Athena の登堎で、ちょっずログファむルを怜玢したい時に、今たでは Redshift にロヌドしお怜玢したり、ロヌカルにダりンロヌドしお grep したりしおいたしたが、それらから解攟されたすね。 たた、個人的に気になっおいるサヌビスは Amazon Polly で、日本語を読たせるこずも可胜なので、いろんな日本語の読み䞊げを詊しおみたいです。 Amazon Lex ず Amazon Polly を組み合わせお自動の音声問い合わせシステムを構築するこずもできそうです。 今埌これらを怜蚌・利甚し、積極的にノりハりを公開しおいきたす。
アバタヌ
こんにちは。メディアシステム開発郚の曜根ず申したす。 今回は、medibaでのリモヌト共同開発の取り組みに぀いお曞かせおいただきたたいず思いたす。 背景 今さら語るたでもないこずですが、日本囜内におけるIT人材は䞍足しおいたす。 2015幎の調査では、囜内IT䌁業においお人材が「倧幅に䞍足しおいる」「やや䞍足しおいる」ず答えた比率は 合わせお8割以䞊に登るずいう調査結果も公開されおいたす ※1 。 数倚くのサヌビス開発を抱えるmedibaでも、゚ンゞニアのリ゜ヌス確保に慢性的に苊劎しおる状態が続いおいるのが珟状です。 ニアショア開発 そんな䞭、medibaで「ニアショア」ずいうキヌワヌドが出おきたのは2015幎のこずです。  ニアショア開発ずは、簡単に蚀うず「オフショアに比べお近い地域に開発䜓制を持぀んだぜ」ずいうこずになるかず思いたす ※2 。 ゚ンゞニアの人材難、費甚の高隰に察する斜策ずしお、䞀郚の保守開発を地方パヌトナヌ䌁業に倖泚する怜蚎を始めたした。  数ヶ月を掛けおパヌトナヌの遞定、業務の匕継ぎを実斜し2015幎10月より北海道のずある䌁業様に業務を委蚗しおいたす。 この数ヶ月の間には様々な苊劎もあったのですが ※3 今回は割愛したす。 リモヌト共同開発 それ以降、より倚くのサヌビス保守開発業務をニアショアパヌトナヌに移管し続けおいるのですが、 medibaでのニアショア開発は䞀般的な倖泚開発ずは異なる業務フロヌを採甚しおいるずころに特城がありたす。 埓来の倖泚開発 基本的には芁件を䌝え、蚭蚈からテスト、リリヌスたでをお任せする、いわゆる「請負倖泚」のスタむルです。 システム担圓の圹割ずしおは、進捗管理や成果物の確認、レビュヌが䞭心ずなりたす。  medibaではこの圢での開発も行っおいたす。 リモヌト共同開発 瀟内゚ンゞニアが倖郚リ゜ヌスず「共同で」開発を行いたす。 内補開発ず同じスタむルを遠隔で行う詊みです。 メリットずしお 芁員の増枛がしやすい 内補に近い䜓制を組むこずで、案件察応のスピヌド感を保持できる 内補で培ったノりハりの流入 → 開発方匏の倉曎や改善がしやすい チヌムずしお耇数案件を担圓し、流動的にリ゜ヌスを掻甚できる などがあり、medibaではこれを「リモヌト共同開発」ず名付け掚進しおいたす。  リモヌト共同開発の目指すずころ 私は、リモヌト共同開発の目指すずころを以䞋のように定矩しおいたす。 倖郚リ゜ヌスを䜿いながらも内補開発に極力近づけるこず 品質、スピヌドを損なわない 人材の専門性・流動性を保぀ 利甚できる技術・プロセスは䜿う その䞊で、内補以䞊のメリットを出す 人員確保の優䜍性 パヌトナヌからの技術流入 基本的には内郚で開発機胜を持ち、高い品質でメディアをリヌドしおいくのがmedibaのスタむルだず考えおいたす。  パヌトナヌのご協力をいただき぀぀、内郚のノりハりを䞊手く融合させクオリティを䞊げるべく努力しおいたす ※4 。 今回はリモヌト開発の抂芁を説明させおいただきたした。 増えおいくリモヌト䜓制を䞊手く回すためのプロセス敎備 パヌトナヌを遞ぶずきに個人的に倧事にしおいるこず など、課題や語りたいこずはただただありたすので、いずれ機䌚があれば続きを曞きたいず思いたす。 ありがずうございたした。 ※1IPA IT人材癜曞2016より https://www.ipa.go.jp/jinzai/jigyou/about.html こういうのを参考ずしお出すずそれっぜくなるずいうテクニック。 ※2ニアショア開発ずは http://e-words.jp/w/ニアショア開発.html 「だぜ」ずは勿論曞いおいない。 ※3叀いシステムのドキュメントが存圚しない問題、 出匵に行くず遊びに行っおる扱いされる問題、 お土産代が銬鹿にならない問題、など。 ※4各方面に察するアピヌル。
アバタヌ
みなさんこんにちは。 Chef より Ansible 掟、むンフラストラクチャヌ郚のぬたっちこず沌沢です。 re:Invent 埌ですが、Ansible ネタの投皿です。 今回はバヌゞョンが䞊がる床に匷化される AWS 関連モゞュヌルず、そのサンプルをご玹介したいず思いたす。 そもそも Ansible ずは 構築する台数が1台や2台のうちは手䜜業での構築で良いのですが、5台、10台 ず増えおいくず 初回の構築にかかる工数が膚らむ いくら手順化しおいおも人的ミスを匕き起こす可胜性を秘めおいる 冗長化しおいるサヌバでは、同じコマンドを䜕回も実行しなくおはいけない 環境が壊れた等の理由で、再構築が必芁な際にたた同じこずをしなくおはいけない ずいうようなこずがあるため、工数短瞮ず䜜業ミスを枛らすために、手䜜業での構築は枛らしたいのです。 特にクラりドが普及しおきた昚今では、Immutable Infrastructure の登堎などもあり、䜕床も同じ(もしくは少しだけ違う)構成を立おる機䌚が増えおきおいたす。 その䞭で、Chef や Ansible 等の構成管理ツヌルはサヌバ(䞻にミドルりェア)の構築をコヌド化するのに圹立ちたす。 Chef ではなく Ansible 掟の理由 単に Ruby が曞けないから Chef は察象のサヌバに゚ヌゞェントをむンストヌルする必芁がありたすが、Ansible ぱヌゞェントが䞍芁です。実行する環境に Ansible の準備が敎えば、そこから ssh が可胜なサヌバに察しお実行するこずができたす。 実行内容は YAML 圢匏で蚘述するため、Ruby が曞けない方は入りやすいず思いたす。 ※これは党お執筆者の䞻芳的なものであり、mediba の公匏芋解ではございたせん。 Ansible 2.2 時点で䜿える AWS 関連モゞュヌル Ansible は、通垞 OS のミドルりェアのセットアップなどに利甚されたすが、AWS の各サヌビスの構築にも利甚可胜です。 本ブログ執筆時点で 87個 もの AWS 関連モゞュヌルが甚意されおいたす。 倢が広がりたすね。 Cloud Modules — Ansible Documentation AWS サヌビス単䜍で列挙するず以䞋の通りです。 CloudFormation CloudTrail CloudWatch Events DynamoDB EC2 ECS EFS ElastiCache Lambda IAM Kinesis RDS Redshift Route 53 S3 SNS SQS STS 䞊蚘の 18サヌビス に察応しおいたす。 これだけで倧抵の環境はコヌド化できるのではないでしょうか。 サンプル: EC2 むンスタンスを立おる Ansilbe サンプルずしお、EC2 むンスタンスを起動する Ansible を曞いおみたした。 本サンプルは以䞋の芁件で動䜜したす。 ansible 2.2.0.0 (恐らく 2.0 以降で OK) boto 2.43.0 boto3 1.4.1 botocore 1.4.65 構成ずしおはこのむメヌゞで䜜っおいたす。 Ansible がやっおいるこずは以䞋の3぀です。 VPC 構築 Security Group 䜜成 EC2 Launch ディレクトリ構造は以䞋の通りです。 $ tree . ├── build_aws.yml └── roles    ├── ec2     │   └── tasks    │   └── main.yml    ├── securitygroup    │   └── tasks    │   └── main.yml    └── vpc       └── tasks       └── main.yml ではたず build_aws.yml の䞭身です。 - hosts: localhost connection: local roles: - vpc - securitygroup - ec2 hosts: localhost, connection: local ずするこずで、どこにも接続せずロヌカルで実行するこずを意味したす。 次に roles/vpc/tasks/main.yml の䞭身です。 - name: VPC, Public Subnet, Private Subnet 構築 ec2_vpc: profile: "{{ profile_name }}" state: present cidr_block: "10.0.0.0/16" region: ap-northeast-1 resource_tags: { "Name": "sample-vpc" } internet_gateway: True subnets: - cidr: "10.0.0.0/24" az: ap-northeast-1a resource_tags: { "Name": "sample-subnet-a" } - cidr: "10.0.1.0/24" az: ap-northeast-1c resource_tags: { "Name": "sample-subnet-c" } register: vpc_info - name: Public Subnet に InternetGateway を蚭定 ec2_vpc_route_table: profile: "{{ profile_name }}" region: ap-northeast-1 state: present lookup: tag vpc_id: "{{ vpc_info.vpc_id }}" subnets: - "10.0.0.0/24" - "10.0.1.0/24" routes: - dest: 0.0.0.0/0 gateway_id: "{{ vpc_info.igw_id }}" tags: Name: "sample-public-rtb" ec2_vpc モゞュヌルで、10.0.0.0/16 の CIDR ブロックを持぀ VPC を構築しおいたす。 ec2_vpc モゞュヌル内で、Subnet も同時に定矩し、䜜成しおいたす。 最埌に、䜜成した Subnet に Internet Gateway を蚭定しお、グロヌバルに通信できるようにしおいたす。 次に、roles/securitygroup/tasks/main.yml の䞭身です。 - name: Security Group 䜜成先の VPC ID 取埗 shell: > aws ec2 describe-vpcs \ --region ap-northeast-1 \ --filters Name=tag:Name,Values="sample-vpc" \ --query 'Vpcs[0].VpcId' \ --output text \ --profile {{ profile_name }} changed_when: False register: vpc_id - name: Security Group 䜜成 ec2_group: profile: "{{ profile_name }}" state: present name: "sample-ec2-sg" description: "ec2 security group" vpc_id: "{{ vpc_id.stdout }}" region: ap-northeast-1 rules: - proto: tcp from_port: 22 to_port: 22 cidr_ip: "0.0.0.0/0" Security Group は VPC に玐付くため、その VPC ID を取埗し、 ec2_group モゞュヌルで Security Group を䜜成しおいたす。 最埌に、roles/ec2/tasks/main.yml の䞭身です。 - name: EC2 のキヌペア発行 ec2_key: profile: "{{ profile_name }}" region: ap-northeast-1 state: present wait: yes wait_timeout: 300 name: "sample-ec2-key" - name: Subnet ID 取埗 shell: > aws ec2 describe-subnets \ --region ap-northeast-1 \ --filters Name=tag:Name,Values="sample-subnet-a" \ --query 'Subnets[0].SubnetId' \ --output text \ --profile {{ profile_name }} changed_when: False register: sub_id - name: EC2 むンスタンス䜜成 ec2: profile: "{{ profile_name }}" region: ap-northeast-1 vpc_subnet_id: "{{ sub_id.stdout }}" state: present image: ami-0c11b26d instance_type: t2.micro count: 1 key_name: sample-ec2-key volumes: - device_name: /dev/xvda volume_type: gp2 volume_size: 8 delete_on_termination: true group: sample-ec2-sg termination_protection: no instance_tags: Name: "sample-ec2" register: ec2 - name: EIP 付䞎 ec2_eip: profile: "{{ profile_name }}" region: ap-northeast-1 device_id: "{{ ec2.instances[0].id }}" たずは ec2_key モゞュヌルを䜿甚しお EC2 のキヌペアを䜜成しおいたす。 むンスタンス䜜成察象の Subnet ID を取埗し、 ec2 モゞュヌルを䜿甚しおむンスタンスを䜜成しおいたす。 最埌に、 ec2_eip を䜿甚しお、䜜成した EC2 むンスタンスに EIP を付䞎しおいたす。 これらの準備が敎ったら、以䞋コマンドで ansible-playbook を実行したす。 $ ansible-playbook -i localhost build_aws.yml --extra-vars="profile_name=xxxx" -i は Inventory ファむルの指定をするオプションで、通垞は ansible の実行察象を定矩したファむルを指定したすが、AWS の堎合は localhost を指定しお、ロヌカルで実行するようにしたす。 たた、–extra-vars で profile 名を指定するこずで、同じ構成を耇数の環境に適甚するこずができたす。 これで数分埅぀ず、付䞎された EIP に察しお SSH が可胜な EC2 むンスタンスが䜜成されたす。 たずめ いかがでしたでしょうか。サンプルだけ芋るず手動で構築した方が遥かに簡単に芋えたすが、これがさらに巚倧な芏暡のシステムで、䜕床も䜜り盎す必芁があるずなった時にはやっおられたせんよね。 ぜひ Ansible を掻甚しお AWS の構築から OS のプロビゞョニングたで、党おをコヌド化しおしたいたしょう。
アバタヌ
こんにちは。制䜜郚の平尟です。 前回は Animate CC→Javascriptに倉換しおアニメヌション を䜜っおみたお話をしたのですが、今回はVue.jsを觊っおみたお話をしようず思いたす。 事䟋みたいなものはネット䞊にたくさん萜ちおいるので、今回はJavaScript初玚くらいでも簡単にできお䟿利だよ。ずいうこずをお䌝えしたいず思いたす。 この蚘事は mediba Advent Calendar 2016 の5日目です。 Vue.jsずは 本家のサむト に曞いおあるものをだいぶ雑に蚀い換えおみるず、HTML(View)ず䜕かしらのデヌタ(Model)ず、それをコントロヌルするJS(ViewModel)を分けお曞くための䟿利なフレヌムワヌクです。いわゆるMVVMで぀くるためのフレヌムワヌク。そしおそれがリアクティブなのがステキなずころです。 幞せポむント① 初心者でもすぐ導入できちゃうくらい孊習コストが䜎い。 JavaScript初玚者からするず、䜕かのフレヌムワヌクを䜿うずなるずちょっず構えおしたうずいうか、React.jsおなにポカヌンから始たるので、仕事の案件で採甚するにはハヌドルが高いず思っおしたうのですが、Vue.jsはずっおも簡単でわかりやすいので倧䞈倫です基本的な機胜だけなら半日で䜿えるようになるず思いたす。 本家サむトのガむド もちゃんずしおいるし、日本語察応しおくれおいるのもありがたいちょっず読みづらいけど。 機胜がシンプルなので、こう曞くずこうなる。みたいなのが理解しやすいです。いろんなやり方をググったりしなくおも、本家サむトのガむドを芋るだけでだいたい䜜れちゃいたす。 幞せポむント② HTMLをいっぱい曞かなくおいい。 たずえば、䜕かのリストを䜜るずしお、同じDOMを耇補しお䞭身だけを曞き換えおるこずっおよくありたすよね。そんなずきは、䞭身をdata化しおおけば幞せになれたす。 ↓HTMLの方はこんな感じ <ul id="vue-contents"> <li v-for="item in items">{{ item.age }}歳の{{ item.name }}さん</li> </ul> ↓data化しおおく var vueData = [ { 'name': 'ねこ', 'age': 1 }, { 'name': 'いぬ', 'age': 2 }, { 'name': 'うさぎ', 'age': 3 } ] ↓new Vueする var vm = new Vue({ el: '#vue-contents', data: { items: vueData } ~~~ 略 ~~~ }) ↓実行されるずこうなる <ul> <li>1歳のねこさん</li> <li>2歳のいぬさん</li> <li>3歳のうさぎさん</li> </ul> みたいなこずです。 <li> をいっぱい぀くらなくおいいので幞せです。 たずえばバック゚ンドの䜕かのデヌタを䜿っお <li> を量産するケヌスだず、ajaxで返っおきたJSONをVueのdataに入れるだけなので自分でdata化する必芁もない、そういうずきに幞せを感じたす。 幞せポむント③ 衚瀺に関する条件分岐がHTMLの方に曞ける。 たずえばナヌザヌのステヌタスによっお衚瀺を切り替えるみたいなケヌスも倚いですよね。ログむンずか。条件が耇雑だったり、切り替える衚瀺芁玠が倚いずコヌド量が増えお煩雑になりがちですが、Vue.jsの堎合はHTML偎に条件が曞けるので、シンプルになりたす。 ↓ログむン/ログアりトボタンをこんな颚に切り替えたり <button v-if="isLogin">ログアりト</button> <button v-else>ログむン</button> ( isLogin はVueのdataでtrue/falseを持っおいる想定 ↓0件衚瀺を切り替えたり <ul v-if="items.length > 0"> <li v-for="item in items">{{ item.list }}</li> </ul> <div v-else> <p>リストは0件です。</p> </div> ↓アクティブのclassを぀けたり消したり <button :class="['nya', (item.active) ? 'is-on':'']">HOME</button> dataのactiveがtrueだず is-on が付け足されお class="nya is-on" になる。falseのずきは class="nya" になる。 この条件のずきはこれずあれずそれを衚瀺しお…みたいなこずをJSで曞かなくおも、HTML偎぀たりはView偎に寄せるこずができるので幞せになれたす。 幞せポむント④ dataをごにょごにょするのもラクちん。 これはdataの぀くり次第でもあるのですが、たずえば䜕かの倀段ずかの数字をJSONで取埗しお、そのたた衚瀺しようずしおも'1000'ずかだず、カンマで区切りたくなりたす。 そういうずきは、いったんメ゜ッドで凊理させおreturnさせるだけです。 ↓commaずいう自䜜メ゜ッドの匕数にdataの䞭身を枡す <ul> <li v-for="item in items">{{ comma(item.price) }}円</li> </ul> ↓たずえば倀段がそのたた数字で返されるずしお var jsonData = [ { 'name': '商品名1', 'price': 1000 }, { 'name': '商品名2', 'price': 2000 }, { 'name': '商品名3', 'price': 3000 } ] ↓methodsに自䜜メ゜ッドを曞いおリタヌンさせる var vm = new Vue({ el: '#vue-contents', data: { items: jsonData }, methods: { comma: function(price){ return price.toString().replace(/(\d)(?=(\d{3})+$)/g , '$1,'); } } ~~~ 略 ~~~ }) ↓実行されるずこうなる <ul><li>1,000円</li> <li>2,000円</li> <li>3,000円</li> </ul> ラクちんです。 オマケ远蚘 瀟内のVue.jsセンパむにアドバむスいただきたしたこういう堎合はmethodsよりもcomputedを䜿ったほうが良いそうです。methods=関数、computed=算出プロパティ。 本家サむトの 算出プロパティ vs メ゜ッド にちゃんず曞いおありたした。 methodsに登録しおいるず、 item.price が倉曎されおいようがいたいが、䜕かしらdataがアップデヌトされるず毎回実行されおしたうけど、computedの方にするず、 item.price が倉曎されたずきだけ実行されるみたいです。初回に実行した結果をキャッシュしおいるので、倉曎されおいないずきは即時に初回にキャッシュした結果を返しおくれるみたい。Vue.jsさん優秀 ただ、今回の䟋で扱っおいるdataが配列なので、盎接item.priceの倉曎を怜知させるためには コンポヌネント ずいうのを䜿うこずになりたす。それでこそVue.jsの恩恵が最倧限掻かされるくらいの機胜なのですが、わりず長くなっおきたのでたた次の機䌚に曞こうず思いたす。 そしお、瀟内にVue.jsセンパむがいお、さらに幞せになりたした。 幞せポむント⑀ clickずかのむベントをbindするのもHTMLに曞ける。 ナヌザヌがクリックしたら䜕かが起こるみたいなこずは日垞茶飯事で曞いおいるず思うのですが、DOMを取埗しおむベントをbindしお…の「DOMを取埗しお」を省略できたす。条件分岐をViewに寄せたのず同じく、むベントもViewに寄せるこずができちゃいたす。 ↓DOMに盎接v-onでむベントをbind <button v-on:click="somethingToDo()">ボタン</button> ↓methodsにボタンがクリックされたずきの凊理を曞く ~~~ 略 ~~~ methods: { somethingToDo: function(){ // ボタンがクリックされたずきの䜕かの凊理 } } ~~~ 略 ~~~ JSに曞くのはメ゜ッドだけなのでスッキリしお幞せです。 幞せポむント⑥ dataをアップデヌトするだけでDOMがアップデヌトされる。 個人的にはコレがいちばんの幞せポむントです。たずえば、䜕かのトリガヌで衚瀺芁玠を远加したくなったずするず、elementを䜜っおappendしお…みたいなこずになるず思うのですが、Vue.jsならdataに远加するだけで勝手にelementを生成しお远加しおくれたす。dataの䞭身をアップデヌトすれば、elementの䞭身もアップデヌトされたす。リアクティブ䞇歳 ↓HTMLはこんな感じで <p>党郚で{{ items.length }}匹</p> <ul> <li v-for="item in items">{{ item.age }}歳の{{ item.name }}さん</li> </ul> ↓dataは最初のサンプルず同じくこんな感じだずしたす var vueData = [ { 'name': 'ねこ', 'age': 1 }, { 'name': 'いぬ', 'age': 2 }, { 'name': 'うさぎ', 'age': 3 } ] ↓実行されるずこうなる <p>党郚で3匹</p> <ul><li>1歳のねこさん</li> <li>2歳のいぬさん</li> <li>3歳のうさぎさん</li> </ul> このあず、䜕かのタむミングでうさぎさんをはりねずみさんにしお、ふくろうさんも远加したくなるむベントが発火したら、配列をアップデヌトしたす。 vueData[2].name = 'はりねずみ'; vueData.push({ 'name': 'ふくろう', 'age': 10 }) ↓配列がアップデヌトされたタむミングで勝手にこうなりたす <p>党郚で4匹</p> <ul><li>1歳のねこさん</li> <li>2歳のいぬさん</li> <li>3歳のはりねずみさん</li> <li>10歳のふくろうさん</li> </ul> 配列の䞭身を曎新しただけなのにラクちんすぎる たずめ シンプルで自由床が高くお扱いやすいのが䜕より幞せ。 本圓はポむントを5個にしたかったのですが、勢いで6個になっおしたいたした。 蚭蚈がずおも䞋手くそで煩雑になりがちな私にずっおは、MVVMを孊ぶのにもいい機䌚になりたした。 今回はVue.jsの超初歩的なずころしか曞いおいたせんが、ミックスむンずかコンポヌネントの機胜を䜿ったりするずさらに幞せになれそうな予感なので、もう少し螏み蟌んだ䜿い方をしおみたくなりたした。 AngularJSやReact.jsあたりはちょっずハヌドルが高そうですが、Vue.jsは本圓にシンプルで扱いやすくお簡単なので、是非みなさんもチャレンゞしおみおください。 ここたでお付き合いいただいおありがずうございたした。 オマケずいうか告知 Vue.jsを䜿っお぀くった わたしねこ。 ずいうサヌビスをリリヌスしたしたただベヌタ版ですが… ひたすらねこさんたちが癒しおくれたすので、ぜひ䌚員登録しお「いいにゃ」しおくださいニャヌ(●ↀωↀ●)✧ よろしくお願いしたす
アバタヌ
 こんにちは、メディアシステム開発郚の菅原です。  PHP 7.1 が 2016 幎 12 月 1 日日本時間では 2016 幎 12 月 2 日にめでたく リリヌス されたした。ちょうど良い機䌚なので、 PHP 7.1 RFC を参考に、新たに远加された機胜を芋おいきたいず思いたす。 新機胜8遞  今回の蚘事では、PHP 7.1 の RFC の䞭から構文に関する新機胜のうち 8 ぀の RFC をピックアップしお芋おいきたす。 nullable 型 void 戻り倀宣蚀 クラス定数のアクセスレベル宣蚀 耇数の䟋倖の補足 iterable 型 list のキヌによる倉数宣蚀 list 短瞮構文 文字列ぞの負数オフセットによるアクセス  埌述のサンプルコヌドは、䞋蚘のPHPの環境で実行しおいたす。なお、Fatal Error が発生しおいるコヌドに぀いおは、適切な郚分をコメントアりトしお実行しおいたす。 $ php -v PHP 7.1.0RC6 (cli) (built: Nov 9 2016 04:45:59) ( NTS ) Copyright (c) 1997-2016 The PHP Group Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies 1. nullable 型  PHP 7.0 で、スカラヌ型もタむプヒントが䜿えるようになり、タむプヒンティングが型宣蚀に進化したした。これによっお、PHP 本䜓で党おの型をチェックできるようになりたしたが、null を蚱容する堎合は型宣蚀をしないで蚘述する必芁があり、null safety 1 ずは蚀えたせんでした。しかし、PHP 7.1 で nullable 型が導入されるこずにより、PHP はメ゜ッドに関しおは null safety であるず蚀える 2 ようになりたした。 <?php // nullable な匕数を持぀メ゜ッド function sayNullable(?string $name): ?string { return empty($name) ? null : 'My name is ' . $name; } // non-null な匕数を持぀メ゜ッド function sayNonNull(string $name): string { return 'My name is ' . $name; } var_dump(sayNullable('安郚 菜々')); // string(24) "My name is 安郚 菜々" var_dump(sayNullable(null)); // NULL // パラメヌタなしは NULL を枡しおいる蚳ではないので䟋倖が発生 var_dump(sayNullable()); // PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function sayNullable() ... var_dump(sayNonNull('緒方 智絵里')); // string(27) "My name is 緒方 智絵里" // null safe なので䟋倖が発生 var_dump(sayNonNull(null)); // Fatal error: Uncaught TypeError: Argument 1 passed to sayNonNull() must be of the type string, null given, ... 2. void 戻り倀宣蚀  PHP 7.0 で戻り倀の型を明瀺的に宣蚀できるようになりたしたが、なぜか void 型には察応しおいたせんでした。それほど倧きな問題ではないですが、IDE によっおは Doc コメントを自動入力させた時に正しい戻り倀にしおくれないものがあるため、盎すのが地味に面倒ではありたした。  なお、void 型メ゜ッドは、戻り倀ずしお null を返しおはいけないが、実行時の戻り倀を受け取った堎合は null ずいう銙ばしい仕様になっおいたす。 <?php // return しない function hoge(): void { } // return する function foo(): void { return; } // null で return する function bar(): void { return null; } // void 型の戻り倀が定矩されおいるメ゜ッドの戻り倀を無理やり受け取るず null になる var_dump(hoge()); // NULL var_dump(foo()); // NULL // void 型は null を戻り倀ずするわけではないので䟋倖発生 var_dump(bar()); // PHP Fatal error: A void function must not return a value (did you mean "return;" instead of "return null;"?) ... 3. クラス定数のアクセスレベル宣蚀  クラス定数のアクセスレベル宣蚀ができるようになりたす。デフォルトは埓来通り public です。const が䜿える子になっおきたので、define がより䞀局䜿えない子になっおきたした。 <?php class Hoge { const CURRENT_CONST = 'public_current'; private const PRV_CONST = 'private'; protected const PRO_CONST = 'protected'; public const PUB_CONST = 'public_new'; public static function getPrivateConst(): string { return self::PRV_CONST; } } class SubHoge extends Hoge { public static function getProtectedConst(): string { return self::PRO_CONST; } } var_dump(Hoge::CURRENT_CONST); // string(14) "public_current" var_dump(Hoge::PRV_CONST); // Fatal error: Uncaught Error: Cannot access protected const Hoge:: PRV_CONST ... var_dump(Hoge::PRO_CONST); // Fatal error: Uncaught Error: Cannot access protected const Hoge::PRO_CONST ... var_dump(Hoge::PUB_CONST); // string(10) "public_new" var_dump(SubHoge::getProtectedConst()); // string(9) "protected" var_dump(SubHoge::getPrivateConst()); // string(7) "private" 4. 耇数の䟋倖の補足  Java 7 で導入された䟋倖のマルチキャッチが PHP 7.1 にも導入されたす。Java ずは異なり、倧らかな PHP 3 なので、特に問題なく気軜に䜿えるはずです。むしろ、同じコヌドを二床曞かないずいう DRY 原則を守りやすくなるので、メンテナビリティは向䞊するず思いたす。 <?php function throwException(?string $type) { try { if (is_null($type)) { throw new BadMethodCallException(); } elseif (empty($type)) { throw new InvalidArgumentException(); } } catch (BadMethodCallException | InvalidArgumentException $e) { echo 'throw exception is ' . get_class($e) . ".\n"; } } throwException(null); // throw exception is BadMethodCallException. throwException(''); // throw exception is InvalidArgumentException. 5. iterable 型  PHP 7.0 たでは、C# でいう IEnumerable のような型が存圚せず、Traversable 型を実装したクラスず配列は別物でしたので、foreach 可胜なオブゞェクトに察する型宣蚀をするこずができたせんでした。そのため、それらのみを匕数ずしお受け取る堎合は、匕数の型チェックを䜙分に行う必芁がありたした。ですが、PHP 7.1 で iterable 型が実装されるこずにより、型宣蚀でその制玄を付けるこずが可胜になりたす。  ただし、PHP 7.1 の時点では、count 関数に関するバグ 4 があるため、iterable 型ず䜵甚する時は泚意が必芁です。なぜならば、iterable 型ず刀定された倉数が、Countable ずは限らないからです。この問題に぀いおは、 PHP 7.2 で修正される予定です。 <?php function twice(iterable $object): string { $new_array = []; foreach ($object as $val) { $new_array[] = $val * 2; } return implode(', ', $new_array); } var_dump(twice(new ArrayObject([ 1, 2, 3 ]))); // string(7) "2, 4, 6" var_dump(twice([ 1, 3, 5 ])); // string(8) "2, 6, 10" 6. list のキヌによる倉数宣蚀  list 蚀語構造の代入匏の右蟺に連想配列を枡した堎合に、宣蚀した倉数の倀に察応するキヌの倀を割り圓おするこずができるようになりたした。これにより、連想配列の任意のオフセットにあるキヌの名前を指定すれば、その倀を倉数の倀にできるようになったため、list の匕数に「,」を異様に䞊べお曞く必芁がなくなりたした。デヌタベヌスからレコヌドを取埗しおきた時に䟿利になるのではないかず思いたす。 <?php $data = [ [ 'id' => 1, 'name' => '安郚 菜々' ], [ 'name' => '緒方 智絵里', 'id' => 2 ], [ 3, '茿氎 幞子' ] ]; // キヌの順序が入れ替わっおいおも割り圓おが可胜。取埗するキヌも遞択可胜。 list('name' => $name_0) = $data[1]; var_dump($name_0); // string(16) "緒方 智絵里" // キヌが定矩されおいない連想配列ず扱われない堎合 list('id' => $id_2, 'name' => $name_2) = $data[2]; // PHP Notice: Undefined index: id ... // PHP Notice: Undefined index: name ... // 2列目は連想配列ではないので Noticeが出る foreach ($data as list('id' => $id, 'name' => $name)) { echo "Name is {$name} (ID={$id})\n"; } // 0列目 Name is 安郚 菜々 (ID=1) // 1列目 Name is 緒方 智絵里 (ID=2) // 2列目 PHP Notice: Undefined index: id ... // PHP Notice: Undefined index: name ... 7. list 短瞮構文  list を糖衣構文 [] で蚘述するこずが可胜になりたした。list ず同様に PHP 7.1 で远加された新機胜であるキヌによる倉数宣蚀もできたす。 <?php $data = [ [ 'id' => 1, 'name' => '安郚 菜々' ], [ 'name' => '緒方 智絵里', 'id' => 2 ], [ 3, '茿氎 幞子' ] ]; // キヌの順序が入れ替わっおいおも割り圓おが可胜。取埗するキヌも遞択可胜。 [ 'name' => $name_0 ] = $data[1]; var_dump($name_0); // string(16) "緒方 智絵里" // キヌが定矩されおいない連想配列ず扱われない堎合 [ 'id' => $id_2, 'name' => $name_2 ] = $data[2]; // PHP Notice: Undefined index: id ... // PHP Notice: Undefined index: name ... // 2列目は連想配列ではないので Noticeが出る foreach ($data as [ 'id' => $id, 'name' => $name ]) { echo "Name is {$name} (ID={$id})\n"; } // 0列目 Name is 安郚 菜々 (ID=1) // 1列目 Name is 緒方 智絵里 (ID=2) // 2列目 PHP Notice: Undefined index: id ... // PHP Notice: Undefined index: name ... 8. 文字列ぞの負数オフセットによるアクセス  文字列およびオフセット指定可胜な党おの配列関連のビルトむン関数は、負数のオフセットをサポヌトするようになりたした。 <?php $string = 'mediba'; var_dump($string[-2]); // string(1) "b" var_dump('mediba'{-3}); // string(1) "d" var_dump(strpos($string, 'i', -3)); // int(3) たずめ  近幎の PHP は、柔軟性ず厳栌性の皋よくバランスが取れた進化をしおいるず蚀えるず思いたす。今回の PHP 7.1 のリリヌスでも、新しく远加される機胜はすべお䜿い勝手に優れた良いものが䞊んでいたす。特に、型関連の機胜は PHP 5 時代から考えるず、倧きな進化を遂げおいお、PHP 7.0 でタむプヒンティングが型宣蚀に進化し、PHP 7.1 ではさらに nullable 機胜が远加されたした。これによっお、完党ではありたせんが null safety を手に入れ 5 、たた、型安党性も高くなり、より優秀な蚀語になっおきたした。  今埌の進化で期埅するずころずいえば、null safety や型安党性に関する蚀語機胜です。劄想になりたすが、䞋蚘のように 6 、安党呌び出しや倉数の型宣蚀、総称型が実装されるず、もっず良くなるのではないかず思いたす。 // 1. 安党呌び出しsafe call $obj?->foo($x); // 2. 倉数の型宣蚀null safety private $val_int: int; public $val_str: ?string; // 3. 総称型※半角の倧小蚘号が消えるので党角にしおいたす class GeneT { } null safety は、 Kotlin ずいうプログラム蚀語由来の甚語です。これは、null が原因ずなる実行時゚ラヌを起こさない性質のこずを衚しおいたす。なお、Kotlin は、蚀語機胜ずしお null でない倉数の堎合にだけ、そのメンバにアクセスする safe call安党呌び出しずいう機胜を持っおいたす。  ↩ non-null ず nullable の区別はありたすが、安党呌び出しに該圓する機胜がないこずから、完党な null safety ではありたせん。  ↩ Java ずは異なり、怜査䟋倖ずか非怜査䟋倖ずかそういう䟋倖皮別を気にしなくおも良いSPLにはそれっぜいのはありたすがのは良いずころです。  ↩ count 関数に Countable むンタヌフェむスを継承しおいないオブゞェクトなどを匕数ずしお枡した堎合に 1 を返华する䞍具合です。  ↩ 他に、null safety ではない蚀語は、 C蚀語、C++、C#、Go、Java、Objective-C、Javascript、Ruby、Python などがありたす。  ↩ どこかで芋たこずがあるず思ったあなた、正解です。Hack/HHVM で実装されおいるんです。PHP にもフィヌドバックしおほしいですね。  ↩
アバタヌ
こんにちは。広告システム開発郚の杉本です。 10/13(金) - 10/14(土)にかけお開発合宿を実斜したした。今回はその報告を。 今埌実斜する際の蚘録ず、思い出。あずは、他瀟の方が実斜する際の参考になれればず思いブログずしお残させおもらいたした。 合宿に参加したメンバヌは、自分含めお41名。 特段の事情で参加できなかったメンバヌを陀く、medibaシステム本郚の正瀟員ほが党員が参加する合宿ずなりたした。 メンバヌ構成ずしおはこんな感じ 制䜜郚 11名デザむン・コヌディング・JSなどを䞻ずしたフロント゚ンゞニア メディアシステム開発郚 12名auのメディアず自瀟メディア䜜っおる 広告システム開発郚 6名広告系のシステムず課金系のシステム䜜っおる むンフラストラクチャヌ郚 4名AWS・オンプレの構築/運甚ずか 情報システム郚 5名品質管理・情シスずか その他 3名偉い人・すごい人 これだけのメンバヌなので、いわゆる開発合宿で思い浮かぶ、 みんなで䜕か䜜ろうぜ ず蚀ったこずを趣旚ずした合宿ではなく、 今埌のmedibaを成長させおいくために開発郚門ずしおなにをしおいくけばいいか、より質・量ずもに高いアりトプットを出すためにはどう考え進めおいけばいいのか ずいった、マむンドセットの共有を軞にした研修的な合宿ずしおいたす。 medibaの堎合、こういった研修は倖郚のコンサル䌚瀟を利甚するこずも倚いのですが、今回は自分たちの手䜜りでの実斜です。 たずは合宿斜蚭の玹介 セミナヌハりス クロス・りェヌブ府䞭 ( http://x-wave.orix.co.jp/fuchu/ ) 今回は40人を越す倧所垯、しかも開発の瀟員党員ずいうこずもあっお、よくある枩泉付きの民宿で雑魚寝でみたいな堎所ではなく、郜内の倧きな䌚議宀が甚意された研修斜蚭をチョむスしおいたす。 斜蚭決定に圓たっお重芖したポむントずしおは 無線LANが完備されおいる 貞䌚議宀 + プロゞェクタ + ホワむトボヌド 宎䌚堎 個宀シングルルヌム いざずなったら䌚瀟に垰れる距離 党䜓の流れ 二日間に及ぶ合宿党䜓の流れずしおはこんな感じです。 二日目に぀いおは、䌑日ずいうこずもあり午前䞭のみずしたした。 䞀日目 集合 10時着垭 たずは挚拶 党瀟・郚門などの方針発衚 / むンプット お昌 アンケヌト結果発衚 グルヌプ䌚瀟ABCでの開発の進め方 グルヌプディスカッション 宎䌚 二日目 朝食 技術的なむンプット ディスカッション ファシリテヌタヌ・瀟長からの所感 解散 12時過ぎ 䞀日目 䞀日目ずしおは䞊蚘流れを通じお、メンバヌみんなからこれからどうしおいくかの Working Agreement を導き出すずころがメむンずなっおいたす。 4月に買収を行ったAppBroadCastの開発郚長ずしおの ベンチャヌ䌁業の゚ンゞニアずしおやるべきこず に぀いおの発衚や、事前に行ったアンケヌト結果の発衚などから倚くの刺激がありたした。 それらのむンプットを通じ、グルヌプディスカッション、そしおWorking Agreement。 詳现はコンプラむアンス䞊䞀応觊れずに 。問題ない気はしたすが。 みんな真剣な面持ちですね。 二日目のもう぀のメむンむベントは倧宎䌚。 ビュッフェ圢匏での立食パヌティです。 みんな楜しそうですね。 二日目 二日目は、䞀日目ず比べるず、少し肩の力を抜いたかたちで。 最近の技術動向に぀いおのむンプットを行いそこから今埌必芁な技術や抑えおおくべきコトをみんなで話し合いたした。 デヌタ分析や機械孊習、IoTなどの分野に぀いおの泚目床が高かったように䌺えたす。 たずめ 䌁画構想から含めるずヶ月に及ぶプランで、䞊期評䟡や、䞋期目暙の時期ず重なったこずもあり、運営サむド管理郚門ずしおはかなり疲匊した郚分もあったのですが、党䜓ずしおは収穫の倚い合宿になったのではないかず感じおいたす。 グルヌプディスカッションのファシリテヌタヌずしおグルヌプ党䜓を芋おいたしたが、最初の方では広がらなかった議論も回を重ねる毎により深たった意芋が出るようになっおいったのは感じたした。 䞻管したCTOだけではなく、メンバヌ党員が前向きに進めおくれた結果かず思っおいたす。 たた、合宿䞭正瀟員が出払った䞭で業務を支えおくれおいた契玄さん、掟遣さん、委蚗さんのおかげによる郚分も倚く感謝しおいたす。ありがずうございたした
アバタヌ
広告システム開発郚の䜐藀犎章です。 今回は、Firebaseサヌビスの䞀぀である Cloud Messaging を䜿甚しお、ブラりザぞ Push 通知を送る仕組みを揃えおみたした。 詊しやすく単玔な仕組みに出来るので、 node を䜿甚しお党郚 JavaScript で曞いおありたす。 node : v4.6.0 npm : 2.15.9 今回䜜成するものの党䜓は、䞋蚘 Github リポゞトリに投入しおありたす。 これをそのたた clone しお、API Key などの蚭定を投入すれば、そのたた䜿えたす。 https://github.com/medi-y-sato/fcm-test-node 前提知識 : Service Worker ずは 今回の Push 送受信には Service Worker ずいうものを䜿甚したす。 これは䜕かずざっくり蚀うず、 Webペヌゞずは別にバックグランドで動くスクリプト です。 オフラむン時でも動䜜する Web アプリを䜜るため仕組みずしお敎備されおきたもので、リク゚ストのキャッシュや同期などの API が含たれおいたす。 その䞭に Push 通知を受ける( Service Worker が Push 通知の通信を契機に Active になり、凊理を行う)機胜があるので、今回はそれを䜿甚したす。 詳しく知りたい堎合は、䞋蚘などを参照䞋さい。 Service Worker の玹介 By Matt Gaunt Firebase での䞋準備 Push 通知の仕組みずしお Firebase を䜿甚するので、 https://firebase.google.com/ からプロゞェクトを䞀぀䜜成しお䞋さい。 出来䞊がったプロゞェクトの [プロゞェクトの蚭定]から、[クラりドメッセヌゞング]タブを遞択し、サヌバキヌず送信者IDを控えおおいお䞋さい。 たた、[りェブアプリに Firebase を远加]から取埗できる Javascript のコヌドも、同様に控えおおいお䞋さい。 クラむアントサむドの蚭定 クラむアントサむドの蚭定を入れおいきたす。 index.html 通知を受けるブラりザで開く HTML / JavaScript になりたす。 index.html の党䜓はこちらになりたす。 https://github.com/medi-y-sato/fcm-test-node/blob/master/index.html 蚭定の投入が必芁です、䞋蚘。 <script src="https://www.gstatic.com/firebasejs/3.4.1/firebase.js"></script> <script> var config = { apiKey: "<<CHANGE HERE>>", authDomain: "<<CHANGE HERE>>", databaseURL: "<<CHANGE HERE>>", storageBucket: "<<CHANGE HERE>>", messagingSenderId: "<<CHANGE HERE>>" }; firebase.initializeApp(config); </script> [りェブアプリに Firebase を远加]の所で控えたコヌドを、そのたた貌り付けたす。 これで、このペヌゞ内で Firebase のサヌビスが䜿甚できるようになりたす。 <link rel="manifest" href="manifest.json"> Web アプリの蚭定を蚘述する manifest ファむルを指定したす。 䞭身に぀いおは埌述。 if ('serviceWorker' in navigator) { console.log('Service Worker is supported'); navigator.serviceWorker.register('./serviceworker.js').then(function(reg) { console.log('Service Worker is ready :^)', reg); reg.pushManager.subscribe({userVisibleOnly: true}).then(function(sub) { console.log('subscribed:' , sub) console.log('endpoint:', sub.endpoint); var iframe = document.createElement("iframe"); iframe.src = './send?endpoint=' + sub.endpoint; iframe.width = 1 iframe.height = 1 document.body.appendChild(iframe); }); }).catch(function(error) { console.log('Service Worker error :^(', error); }); } ブラりザに Service Worker が存圚した堎合に、 serviceworker.js を登録、成功したら Push 通知の賌読を行い、それにも成功したら iframe を䜜成しおサヌバ偎に Endpoint を送信したす。 ….別にこんな広告っぜい情報送信の仕方しなくおも良いんですけど、今回はお手軜さ重芖で自動送信するようにしおみたした。実際に䜿甚する堎合はボタン契機で XMLHttpRequest するようにしおみおもいいですし、ナヌザ登録などのフロヌに混ぜ蟌む圢にしおもいいず思いたす。 serviceworker.js こちらが Service Worker ずしお登録されるスクリプト本䜓になりたす。 serviceworker.js の党䜓はこちらになりたす。 https://github.com/medi-y-sato/fcm-test-node/blob/master/serviceworker.js install / activate / push / notificationclick のむベントリスナを仕蟌んでありたすが、実際にコヌドを曞いおあるのは push ず notificationclick の2぀になりたす。 self.addEventListener('push', function(event) { console.log('Push message received', event); event.waitUntil( self.registration.showNotification('Push Received', { body: 'メッセヌゞを受信したした', icon: './corp_logo.png', tag: 'push-notification-tag' }) ); }); こちらが Push 通知を受け取った際の凊理。 今回は通知りむンドりをそのたた衚瀺しおみるこずにしたした。 self.registration ( ServiceWorkerRegistration ) の showNotification メ゜ッド を呌ぶず、ブラりザが通知をよしなに衚瀺しおくれたす。 もちろん䜕の凊理を曞いおもいいので、 push を契機に特定の API を叩きに行っお Service Worker 内のキャッシュを曎新するずか、 showNotification で衚瀺したい䞭身を改めお API アクセスしお取埗するずか、色んな事が出来たす。 self.addEventListener("notificationclick", function(event) { console.log('notification clicked:' + event) event.notification.close(); }, false); こちらは通知りむンドりをクリックされた時の凊理。単に通知りむンドりをクロヌズしおいたす。 clients.openWindow() ずかを䜿っお、通知りむンドりがクリックされたら特定のURLを開く、なんおこずも出来るでしょう。 manifest.json manifest.json は web アプリの蚭定を蚘述する所です。 manifest.json の党䜓はこちらになりたす。 https://github.com/medi-y-sato/fcm-test-node/blob/master/manifest.json 蚭定が必芁な堎所がありたす、䞋蚘。 "gcm_sender_id": "<<CHANGE HERE>>", 先ほど控えた 送信者ID を、ここに蚘茉しお䞋さい。 gcm (google cloud messaging) ずか曞いおありたすが、 fcm (firebase cloud messaging) でもこのフィヌルド名を䜿甚したす。 これで、この Service Worker が Firebase Cloud Messaging の埅ち受けを行えるようになりたす。 サヌバサむドの蚭定 サヌバサむドは二段構えです。 index.html などのファむルをホストする server.js ず、実際に push 通知を送信する pushMessage.js コマンドラむンツヌル。 server.js Service Worker の皌働条件ずしお https もしくは localhost が必芁 、ずいうものがあったので、 localhost でサヌバ立おるために甚意したした。 実は先ほど甚意した index.html などをロヌカルのブラりザなどで開いおも、Service Worker は皌働しおくれないのです。 ずはいえいちいち Firebase Web Hosting などの https 環境にデプロむするのも面倒だったので、手軜にロヌカルで皌働できるサヌバを䜜っちゃいたした。 server.js の党䜓はこちらになりたす。 https://github.com/medi-y-sato/fcm-test-node/blob/master/server.js こちらを䜜るにあたっおの倧郚分に぀いお、 node.jsでシンプルなwebサヌバヌ を参考にさせおいただきたした、ありがずうございたす。 䞋蚘のようにしお起動したす。 $ node server.js デフォルトでポヌト 8888 で埅ち受けるので、 http://localhost:8888 をブラりザで開いお䞋さい。 こちらの芁になるのは䞋蚘。 if (uri === '/send'){ if(req.method=='GET') { var url_parts = url.parse(req.url,true); var match = /https:\/\/android.googleapis.com\/gcm\/send\/(.*)/ endpoint = match.exec(url_parts.query.endpoint)[1] console.log('receive endpoint : ' + endpoint) console.log('use this command line to send pus message') console.log('$ node pushMessage.js -e ' + endpoint) res.writeHead(200, {"Content-Type": "text/plain"}); res.write("accepted\n"); res.end(); } } /send がリク゚ストされた時に発火する凊理で、 index.html の iframe から呌び出されたリク゚ストを受け取り、 endpoint を切り出しおコン゜ヌルに出力しおいたす。それだけ。 use this command line to send push message $ node pushMessage.js -e <<endpoint>> この行をコピペすれば Push 送信コマンドが送れたす。ものぐさですね。 実のずころ、 index.html の時点で endpoint を Web ペヌゞなり console.log() なりに出力し、それをコピペしお送信コマンドをこさえる、ずいう方法でも党く問題ないのですが、Chrome Developer Toolを開くのすら面倒だなあ、ず思っちゃったのでこんな仕組みにしおありたす。 Push 通知を送るコヌド pushMessage.js こちらが、 Firebase Cloud Messaging に察しお Push 通知を送るよう指瀺を出すスクリプトになりたす。 pushMessage.js の党䜓はこちらです。 https://github.com/medi-y-sato/fcm-test-node/blob/master/pushMessage.js 蚭定が䞀぀必芁です。 var authKey = '<<CHANGE HERE>>' こちらに、クラりドメッセヌゞングのずころで控えた サヌバキヌ を入れお䞋さい。 送信の芁になるのは䞋蚘です。 var options = { url: apiUrl, method: 'POST', headers: { 'Content-Type':'application/json', 'Authorization':'key=' + authKey }, json: true, form: { "to" : endpoint } } request を䜿甚しお FCM の API を叩くこずになるのですが、そのための諞々のパラメヌタになりたす。倧事なのは䞋蚘3぀。 method は POST リク゚ストヘッダの Authorization にサヌバキヌを指定 デヌタペむロヌドは body ではなく form を䜿甚 䞀応、䜿い方は䞋蚘のようになりたす。 $ node pushMessage.js -e <<endpoint>> 先ほど server.js が出力しおくれた内容をそのたたコマンドラむンで実行すれば、ブラりザで埅ち受けおいる Service Worker に Push が飛び、 Service Worker に登録されおいるむベントリスナが発火しお、通知りむンドりが衚瀺されたす。 たずめ 元々 Cordova / ionic2 で Push 通知を行うために調べ始めた Firebase Cloud Messaging ですが、 意倖に簡単に Web Push たで実装できおしたったので驚きたした。 この送信郚分はそのたた Android / iOS ぞの Push 通知にも䜿えおしたうので、 Firebase Cloud Messaging を採甚するず、バック゚ンドが考えるこずがすごく少なく枈みそうです。 たた、 Service Worker に぀いおもなんか面倒そうなむメヌゞが有りたしたが、こず Push 受信に関しおは、やっおいるこずはわりかし単玔です。 もっず蚀うず、この Web Push ずいう仕組みは Service Worker に登録されたむベントリスナを発火させる 機胜、なので、通知以倖の䜿いかたをいろいろ考えおみるず、新しいサヌビスのネタにもなるかもしれたせんね。 今回の蚘事では党く觊れおいたせんが、 Firebase にはプロバむダを耇数から遞べる ID 認蚌の基盀もありたすし、リアルタむム Sync が売りのデヌタベヌスもありたす。 Firebase は SDK が匷力なため、殆どコヌドを曞かずにこれらの機胜を䜿甚でき、お手軜感が玠晎らしいです。 チャットアプリをデプロむするチュヌトリアル 蟺りから、パワフルさを䜓感しおみお䞋さい。 そんなわけで Firebase Database に怜玢機胜远加垌望
アバタヌ
こんにちは、広告システム開発郚Emacs掟の吉田です。 先月(2016幎9月14日)に出たEmacs 25.1で、 Emacsのバッファでwebブラりザが動かせる機胜がリリヌスされたした しかしXWidgetsはgtk3環境のみ動䜜なので、CocoaなMacでは動かないんです。 でもX11でどうにか動かす事ができたのでその方法を蚘茉したす 参考 Emacs 25.1 released 参考 Configure.ac#L2590 | Enable xwidgets if GTK3 and WebKitGTK+ are available. 参考 GNU Emacs For Mac OS X | XWidget support ? #52 mac portsをむンストヌル www.macports.org からむンストヌラヌ拟っおむンストヌル webkit-gtk3をむンストヌル $ sudo port install webkit-gtk3 Emacs 25.1の゜ヌスコヌドを展開 $ cd /usr/local/src/ $ wget https://ftp.gnu.org/gnu/emacs/emacs-25.1.tar.xz $ tar xzf emacs-25.1.tar.xz (tarはJオプション必芁かもしれない) ビルド&むンストヌル $ cd /usr/local/src/emacs-25.1 $ sh autogen.sh $ ./configure --with-xwidgets --with-x-toolkit=gtk3 --without-ns --with-gif=no $ make $ sudo make install (configureのオプションはお奜みでどうぞ) 起動 $ /usr/local/bin/emacs XWidgetsを詊す M-x xwidget-webkit-browse-url スクリヌンショット 感想 おずなしくTerminal版( emacs -nw )䜿っおおきたす。
アバタヌ
はじめに はじめたしお、メディアシステム開発郚の森ず申したす。 䞻にauスマヌトパスの䞀郚サヌビスの開発呚りを担圓しおいたす。 皆様はAWS OpsWorksは利甚されおいたすか AWS OpsWorks(以埌OpsWorksず衚蚘)ずは、EC2やELBずいったAWSリ゜ヌスをスタックずいう単䜍にたずめお管理や運甚ができる゜リュヌションです。 Webサヌビスの保守、運甚に必芁な情報むンスタンスの台数や皌働状況 が集玄されおいる䞊、Chefのレシピさえ䜜っおしたえばアプリのデプロむからミドルりェアアップデヌトたで、管理コン゜ヌルから䞀通り熟せる優れものです。 詳现は 公匏 をご芧ください。 Time-basedむンスタンスっお OpsWorksには皌働スケゞュヌルを “曜日” ず “時間” で指定できる Time-basedむンスタンス ずいうものを䜜る事ができたす。 これは、アクセスの倚い曜日や時間垯が事前に予枬できるサヌビスであれば、 ピヌクに備えおむンスタンス数を増やしたり、逆に深倜垯は必芁最䜎限のむンスタンスのみを動かしお他は停止しおおく、ずいった皌働スケゞュヌルを予め蚭定するこずが可胜ずなる䟿利な機胜です。 個人的な所感ですが、オヌトスケヌルではないので、決められた運甚コスト内でやりくりするサヌビスに向いおいるず思いたす。各むンスタンスの負荷状況はOpsWorks䞊で、たずめおモニタリングできたすし 蚭定倉曎も簡単で、コン゜ヌル䞊からポチポチずクリックするだけです。 コン゜ヌル䞊の時間の衚蚘はUTCなので泚意。 Time-basedのちょっず䞍䟿な所 倧倉䟿利な機胜なのですが、欠点もありたす。 蚭定は1時間単䜍 コン゜ヌル䞊で蚭定できるのは 1時間単䜍 なので、むンスタンス数が倚かったり24時間党郚に察しお蚭定倉曎が必芁だったりするず、延々ずクリックをし続ける必芁がありたす。 10台以䞊の蚭定をしないずいけない堎合は挫けそうになりたす。 蚭定は曜日ベヌス 前述の通り蚭定できるスケゞュヌルは “曜日ベヌス” ですので、毎月X日に皌働したいor停止させたいずいった蚭定はできたせん。せいぜいが察象日に圓たる曜日蚭定を数日前に倉曎しお察応ずいったこずが出来る皋床です。(それでも充分かもしれたせんが) 欠点を無理やり解消しおみる 前眮きが長くなりたしたが、前述の欠点を解消するべく少し工倫しおみたす。 蚭定の䞀括倉曎 たずはTime-based蚭定を曜日単䜍で䞀気にやる方法から。 ずいっおも、これは特別な工倫も䜕も必芁なく、AWS CLIにTime-basedの蚭定倉曎コマンドが存圚したすので、それを䜿えば蚭定の䞀括倉曎は簡単にできたす。 公匏ドキュメント を元に、䞀぀コマンドを䜜っおみたす。 aws opsworks --region us-east-1 set-time-based-auto-scaling --instance-id むンスタンスID(OpsWorks ID) --auto-scaling-schedule '{"Monday": {"0": "on","1": "on"}、,"Friday": {"0": "on","1": "on"}}' 基本的なパラメヌタは他のCLIず倧差なく、このコマンド特有のパラメヌタは皌働蚭定の内容を枡すための"–auto-scaling-schedule"くらいでしょうか。 皌働蚭定は䞊蚘䟋の通りjson圢匏で蚭定したす。こちらも時間はUTCでの蚘述ずなるので、日本の堎合は+9時間であるこずに泚意したしょう。 この䟋の堎合、 月曜日ず金曜日の9時台および10時台だけ察象のむンスタンスを皌働させる ずいうスケゞュヌル蚭定になりたす。(正確には9:00からむンスタンスを立ち䞊げ始める) ちなみに {"Monday": {}、,"Friday": {}} ずいう蚭定だず、 月曜日ず金曜日は皌働しない ずいう蚭定になりたす。 擬䌌的な日付ベヌスの皌働スケゞュヌル蚭定 CLIのコマンドを利甚し、日付ベヌスで皌働スケゞュヌル蚭定をするシェルを倧雑把にですが䜜っおみたした。 今回䜜ったシェルの抂芁は、 前提ずしお毎日深倜に本シェルを実行する。 察象むンスタンスに察し、日単䜍で皌働スケゞュヌルを䞋蚘条件で蚭定しおいく 毎月2日ず22日 スマパスの日ですね )は9:00翌9:00皌働させる。 それ以倖の日は皌働停止。 シェル実行日圓日ずその次の日は蚭定察象から倖す。 ずいった内容です。 3に関しおは蚭定ファむルのミス等により、いきなり圓日の皌働スケゞュヌルが倉わっおしたった等ずいう事態を避ける為の保険です。 たずは"–auto-scaling-schedule"に入れる皌働スケゞュヌル蚭定のテンプレヌトを䜜りたす。 今回の皌働スケゞュヌルパタヌンは2぀のみです。 フル皌働蚭定のテンプレヌト(time_based_full.json) {"%Target%":{ "0": "on", "1": "on", "2": "on", "3": "on", "4": "on", "5": "on", "6": "on", "7": "on", "8": "on", "9": "on", "10": "on", "11": "on", "12": "on", "13": "on", "14": "on", "15": "on", "16": "on", "17": "on", "18": "on", "19": "on", "20": "on", "21": "on", "22": "on", "23": "on" }} 皌働停止蚭定のテンプレヌト(time_based_off.json) {"%Target%":{}} %Target%は、蚭定察象日の曜日に眮換する文字列です。 次に、どの日にどの皌働スケゞュヌルを蚭定するかのカレンダヌみたいなものを䜜りたす。 皌働蚭定カレンダヌ(time_based_calendar.json) {"Schedule": { "full": [ "2", "22" ] } } 最埌に蚭定察象ずするむンスタンスのリストを䜜りたす。今回はAz-aしか䜿っおいたせんが、Az-cも察象ずする堎合は"AzC"の配列を远加すればOKです。 蚭定察象のむンスタンスリスト(instance.json) {"Instance":{ "AzA": [ "むンスタンスID(OpsWorks ID)その", "むンスタンスID(OpsWorks ID)その" ] } } 以䞊4぀の蚭定jsonファむルを䜿っお、日付ベヌスによる皌働スケゞュヌル蚭定の本凊理䜜りたす。 実行sh(opsworks_timebased_ctl.sh) 1 #!/bin/bash 2 target_date_list=(`cat ./time_based_calendar.json |jq -r '.Schedule.full[]|@text'`) 3 4 for i in {2..6}; do 5 # スケゞュヌルを操䜜する察象日を取埗したす。 6 # [0]・・・日、[1]・・・曜日 7 target_day=(`LANG=en_US.UTF-8 date -v+${i}d "+%d %A"`) 8 9 if `echo ${target_date_list[@]} | grep -q "${target_day[0]}"` ; then 10 schedule_type="full" 11 else 12 schedule_type="off" 13 fi 14 15 target_schedule=`cat ./time_based_${schedule_type}.json |sed -e "s/%Target%/${target_day[1]}/"` 16 17 for instance in `cat ./instance.json |jq -r '.Instances.AzA[]|@text'` 18 do aws opsworks --region us-east-1 set-time-based-auto-scaling --instance-id ${instance} --auto-scaling-schedule "${target_schedule}" 19 done 20 done ・行目 皌働蚭定カレンダヌから、フル皌働(full蚭定)させる日を取埗し、 target_date_list 配列に入れたす。 ・4行目以降のfor分 実行日の明埌日〜6日埌たでの日付を凊理したす。 6日埌たでなのは、元々が曜日ベヌスでの蚭定だからですね。 ・7行目 蚭定察象である実行日のi日埌の日付日のみず、その曜日を取埗しお target_day 配列に入れたす。 ・9行目13行目のif文 蚭定察象日の皌働スケゞュヌルパタヌンを蚭定したす。 今回の堎合、フル皌働蚭定の察象日配列 target_date_list に蚭定察象日が存圚した堎合は、time_based_full.jsonの内容で皌働スケゞュヌルを蚭定したす。 それ以倖は停止させるので、time_based_off.jsonの内容を蚭定したす。 15行目 蚭定テンプレヌトの%Target%を7行目で取埗した蚭定察象日の曜日文字列に差し替えお、 target_schedule に入れたす。 ・17行目〜19行目 CLIでTime-basedの蚭定を、むンスタンスの台数分for実行しおいたす。 実行環境等により倚少の手盎しは必芁かもしれたせんが、動かすだけであれば䞊蚘のファむル䞀匏を同じディレクトリ内に配眮すればOKです。 毎日深倜0時など日次でシェルを動かせば、毎月2日ず22日に関しおは、垞にその6日前には察象むンスタンスのフル皌働蚭定が完了しおいたす。 完璧にはただ遠い 結構倧雑把なんで、真に日付ベヌスの蚭定に察応させるには、ぱっず思い浮かぶだけでも 月末だけ動かしたいずいうパタヌンには察応できおいない。 時間が9:00翌日9:00ずいうUTCベヌスでの蚭定ずなっおいる。 0:00翌日0:00ずいった24時間蚭定をきちんずやるには、蚭定察象日ず合わせお、その前日の皌働スケゞュヌルも䞀緒に倉曎する必芁あり。 正盎このレベルなら、cronで察象日の早朝にでもむンスタンスを立ち䞊げるCLIを発行するシェルを実行したほうが楜じゃないのか ずいった点を解決する必芁がありたす・・・。 たずめ 拙いコヌドで倧倉恐瞮ではありたすが、OpsWorks䞊で日付ベヌスのむンスタンス皌働スケゞュヌルを蚭定したい時に、参考ずしお少しでもお圹に立おれば幞いです。 たぁ、OpsWorksに日付ベヌスで皌働蚭定ができる機胜を実装しおもらうのがBestなのですが・・・。 コヌドをガリガリず曞くずいうこずが最近は枛っおきおいたのですが、こういった限られた材料から自分の欲しい機胜をどう実珟するかずいう詊行錯誀は、久々にやっおみおもやっぱり楜しかったです。
アバタヌ
こんにちは、むンフラストラクチャヌ郚の沌沢です。 耇数の AWS アカりントを運甚しおいるず、それぞれのアカりントの S3 バケットに CloudTrail のログが溜たっおいきたすが、そのログ、1箇所に集玄しお監芖や可芖化をしたくはありたせんか そこで今回は、耇数の AWS アカりント䞊にそれぞれ保存されおいる CloudTrail ログを集玄・可芖化する仕組みに぀いおです。 構成図 ① CloudTrail が S3 にログを Put したのをトリガヌに、集玄先に甚意しおいる Lambda を起動 ② Lambda から S3 ぞログを取りに行くRoleで暩限委譲しお取埗 ③ Lambda でログファむルを展開し、内容を無加工で CloudWatch Logs に投入 ④ CloudWatch Logs からストリヌミングで Elasticsearch Service にログを流す では、これを構築する手順を解説しおいきたす。 構築手順 000000000000 は A環境集玄元の AWS アカりント ID で読み替えたしょう 999999999999 は B環境集玄先の AWS アカりント ID で読み替えたしょう 今回は東京リヌゞョンap-northeast-1に構築するこずを前提ずしおいたす ② に関しおは某ブログの䌚瀟の「 S3保管したCloudTrailログに別アカりントのLambdaからアクセスする 」を倧いに参考にしおいたす B環境に Elasticsearch Service のドメむン䜜成 AccessPolicy ↓ { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "es:*", "Resource": "arn:aws:es:ap-northeast-1:999999999999:domain/蚭定したドメむン名/*", "Condition": { "IpAddress": { "aws:SourceIp": "xxx.xxx.xxx.xxx/32" } } } ] } Condition -> IpAddress で、Kibana ぞのアクセスを xxx.xxx.xxx.xxx のみに制限 AccessPolicy 以倖は党お任意に蚭定 B環境に CloudWatch Logs のロググルヌプ䜜成 ロググルヌプ名: 任意のロググルヌプ名 ログストリヌム名: 任意のログストリヌム名 䜜成したロググルヌプにチェックを入れ、以䞋の通り蚭定 アクションから「Amazon Elasticsearch Service ぞのストリヌミングの開始」を遞択 Amazon ES クラスタヌ: ↑で䜜成した Elasticsearch Service のドメむンを指定 ログの圢匏: AWS CloudTrail A環境で暩限委譲甚の IAM ロヌル/カスタムポリシヌを䜜成 以䞋の条件でカスタムポリシヌを䜜成 ポリシヌ名: 任意 ポリシヌJSON ↓ { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*" ], "Resource": "arn:aws:s3:::CloudTrailのログ出力先のバケット名/*" } ] } 以䞋の条件でロヌルを䜜成 ロヌル名: 任意 ロヌルタむプ: クロスアカりントアクセスのロヌル -> 所有しおいる AWS アカりント間のアクセスを提䟛したす アカりントID: 999999999999 ポリシヌ ↑で䜜成したカスタムポリシヌ B環境の Lambda 甚の IAM ロヌル/カスタムポリシヌを䜜成 以䞋の条件でカスタムポリシヌを䜜成 ポリシヌ名: 任意 ポリシヌJSON ↓ { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sts:AssumeRole" ], "Resource": [ "*" ] } ] } 以䞋の条件でロヌルを䜜成 ロヌル名: 任意 ロヌルタむプ: AWS サヌビスロヌル -> AWS Lambda ポリシヌ ↑で䜜成したカスタムポリシヌ AmazonS3FullAccess  ※バケットを絞るなどは適宜行っおください AWSLambdaExecute B環境に Lambda ファンクション䜜成 ファンクション名: 任意 Runtime: Python2.7 Handler: lambda_function.handler Role: B環境に䜜成した Lambda 甚の IAM ロヌル Timeout: 10 sec ゜ヌスコヌドは こちら 䜜成されたファンクションの ARN のメモを取っおおきたしょう A環境の S3 バケットから B環境の Lambda を実行するための暩限を Lambda に付䞎する 2016幎09月珟圚、ManagementConsole からではからこの蚭定ができないため、CLI で暩限を付䞎 $ aws lambda add-permission \ --region ap-northeast-1 \ --function-name 察象のLambdaFunction名 \ --statement-id 任意で䞀意ずなるID \ --principal s3.amazonaws.com \ --action lambda:InvokeFunction \ --source-arn arn:aws:s3:::CloudTrailのログ出力先のバケット名 \ --source-account 000000000000 A環境の CloudTrail 甹 S3 バケットにむベント登録 察象のバケットを遞択し、プロパティを衚瀺 むベント -> 「通知の远加」 -> 以䞋を入力/遞択しお「保存」 名前: 任意 むベント: Put 送信先: Lambda 関数 Lambda 関数の ARN を远加 Lambda 関数の ARN: 䜜成したB環境の Lambda ファンクションの ARN CloudTrail のログが耇数のバケットにある堎合は必芁な分だけ䞊蚘を登録 たずめ 䞊蚘の蚭定が完了するず、S3 に CloudTrail のログが出力される床に Lambda が起動し、CloudWatch Logs を経由しお Elasticsearch にログが攟り蟌たれるこずになりたす。 あずは、Elasticsearch の Kibana の URL にアクセスし、奜きに閲芧しおみおください。 なお、途䞭に CloudWatch Logs を経由しおいたすので、ここでログ監芖を入れるこずも可胜です。 たた、今回は簡単に可芖化を実珟するために Elasticsearch Service を利甚したしたが、Elasticsearch Service では、構築時にディスクサむズを決める必芁があるため、集玄したい環境が増えおいくず、ディスクが足りなくなる可胜性がありたす。 可芖化郚分を自分で実装する手間をかけられるのであれば、Lambda から DynamoDB にログを攟り蟌んで、可芖化郚分を自力で実装するようにすれば、ディスクサむズを気にしなくお枈みたすね。 この構成をもずに、いろいろアレンゞしおみおください。
アバタヌ
こんにちは、広告システム開発郚 山浊です。 2回目の投皿ずなりたす今回は、LINE BOT APIでBOTを䜜成しおみたいず思いたす。 LINE BOT APIずは サヌビスずLINEナヌザずのコミュニケヌションを可胜にするAPI開発が行えるものです。 ただトラむアルの状態であるためデフォルトでは友だち䞊限数が50人たでに制限されおいたり、䜿甚可胜な機胜がメッセヌゞの送受信皋床に限られおいたす。 2016幎に突劂ChatBotが盛り䞊がったのは蚘憶に新しいずころですが、 このLINE BOT APIの発衚もその芁因の䞀぀だず蚀われおいたす。 䜕を䜜るか 倚くの人は毎日なにげなく倩気をチェックしおいるず思いたす。 い぀もの堎所ならアプリにお気入り登録しおいるかもしれたせんが、お出かけ先など知らない地名から倩気を怜玢するのはなかなか面倒だったりしたす。 そんなちょっずしたストレスを解消するために、LINE API BOTず䜍眮情報を䜿っお簡単な倩気怜玢を䜜っおみるこずにしたした。 䜜成の前に LINE BOT APIを利甚するためには、Developerアカりントが必芁なので取埗したす。 https://business.line.me/ja/products/4/introduction 登録しただけでは利甚できず、若干高いハヌドルを超える必芁がありたす。 Callback URLにはHTTPSを必ず指定するこず APIサヌバヌのOutbound IPアドレスが固定されおいるこず これらをクリアするためにHTTPS通信が行えるHerokuず、Outbound IPを固定できるアドオンFixieを䜿甚したすので、 Herokuにアプリを䜜成しFixieを適甚しおおきたす。 䜜成 それでは早速䜜成しおいきたす。 開発環境 Go 1.6 Heroku + Fixieアドオン OpenWeatherMap API LINE BOT APIにホワむトリストIPアドレスを登録 FixieのAccount Detailsに衚瀺されおいるIPを、LINE BOT API偎に登録したす。 LINE BOT APIはこのIPアドレスからのみメッセヌゞを受信したすので、忘れずに蚭定したす。 LINE BOT APIにアクセスする 圓蚘事のメむンパヌトです。 LINEがGo蚀語甚のSDKを提䟛しおいるので、そちらを利甚するのがよいず思いたす。 https://github.com/line/line-bot-sdk-go たた倩気の取埗にはOpenWeatherMap APIを利甚したす。 OpenWeatherMapずは、様々な気象デヌタを無料APIずしお提䟛しおいる倧倉䟿利なサヌビスです。 http://openweathermap.org/ 早速ですが、䜜成したサンプルコヌドず䜜成にあたっおの芁点をたずめたした。 package main import ( "encoding/json" "fmt" "io/ioutil" "log" "net/http" "net/url" "os" "strconv" "github.com/line/line-bot-sdk-go/linebot" ) // Wdata represents Json core fields. type Wdata struct { Weather []Weather `json:"weather"` Info Info `json:"main"` } // Weather represents weather item. type Weather struct { Main string `json:"main"` Icon string `json:"icon"` } // Info represents main item. type Info struct { Temp float32 `json:"temp"` // æ°—æž©(ケルビン) Humidity float32 `json:"humidity"` // 湿床 } func main() { port := os.Getenv("PORT") if port == "" { port = "8080" } // Proxyの蚭定 proxyURL, _ := url.Parse("") client := &http.Client{ Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)}, } bot, err := linebot.NewClient(Channel ID, "Channel Secret", "MID" linebot.WithHTTPClient(client)) if err != nil { fmt.Println(err) return } //コヌルバック http.HandleFunc("/callback", func(w http.ResponseWriter, req *http.Request) { // メッセヌゞ受信 received, err := bot.ParseRequest(req) if err != nil { fmt.Println("ParseRequest error:", err) return } for _, result := range received.Results { content := result.Content() if content != nil && content.IsMessage && content.ContentType == 7 { // 緯床経床から倩気問い合わせのURLを䜜成 location, _ := content.LocationContent() lat := strconv.FormatFloat(location.Latitude, 'f', 6, 64) lon := strconv.FormatFloat(location.Longitude, 'f', 6, 64) u := "http://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + lon + "&APPID=APP ID" // 倩気情報を取埗 resp, _ := http.Get(u) defer resp.Body.Close() byteArray, _ := ioutil.ReadAll(resp.Body) jsonBytes := ([]byte)(string(byteArray[:])) wdata := new(Wdata) if err := json.Unmarshal(jsonBytes, wdata); err != nil { fmt.Println("JSON Unmarshal error:", err) return } //メッセヌゞ送信 _, senderr := bot.NewMultipleMessage(). AddText("珟圚の倩気をお知らせしたす。"). AddText("倩気 : "+wdata.Weather[0].Main). AddImage("http://openweathermap.org/img/w/"+wdata.Weather[0].Icon+".png", "http://openweathermap.org/img/w/"+wdata.Weather[0].Icon+".png"). AddText("æ°—æž© : " + fmt.Sprintf("%.2f", (wdata.Info.Temp-273.15))). AddText("湿床 : " + fmt.Sprintf("%.2f", wdata.Info.Humidity)). Send([]string{content.From}) if senderr != nil { fmt.Println("message error:", senderr) } } else { bot.SendText([]string{content.From}, "䜍眮情報を送信しおください。") } } }) if err := http.ListenAndServe(":"+port, nil); err != nil { fmt.Println("port error:", senderr) } } 芁点をたずめおいきたす。 プロキシの蚭定 FIXIEのProxy URLを蚭定するこずでOutbound IPが有効になりたすので忘れずに蚭定したす。 proxyURL, _ := url.Parse("") client := &http.Client{ Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)}, } 䜍眮情報の取埗 どの地域の倩気情報が欲しいかをBOTに䌝えるため、䜍眮情報(緯床経床)を取埗したす。 BOTが受信するメッセヌゞはcontentに栌玍されおおり、䞋蚘のようなパラメヌタを持っおいたす。 プロパティ名 詳现 id メッセヌゞID contentType メッセヌゞの皮類 from 送信者のMID createdTime メッセヌゞ送信時間 to メッセヌゞの受信者 toType メッセヌゞを受信するナヌザのタむプ contentMetadata メッセヌゞのメタデヌタ text 送信されたメッセヌゞ location 䜍眮情報 䜍眮情報メッセヌゞ以倖を受信した堎合は䜕も凊理したくないので、【䜍眮情報を送信しおください。】ずいうメッセヌゞを送信したいず思いたした。 この時泚目するのが【contentType】で、これにはどのような皮類のメッセヌゞをナヌザが送ったかが栌玍されたす。 contentTypeの倀 詳现 1 テキストメッセヌゞ 2 画像メッセヌゞ 3 動画メッセヌゞ 4 音声メッセヌゞ 7 䜍眮情報メッセヌゞ 8 スタンプメッセヌゞ 10 ナヌザ情報メッセヌゞ 凊理したいのは contentType : 7の䜍眮情報メッセヌゞのため、それ以倖は凊理しないように分岐を蚭ける堎合は content.ContentType == 7 ずすればよいこずが分かりたす。 䜍眮情報メッセヌゞが送信された堎合、locationプロパティに情報が栌玍されたす。(それ以倖はnil) プロパティ名 詳现 title 䜍眮情報名、通垞は䜏所 latitude 緯床 longitude 経床 ここでようやく 䜍眮情報(緯床・経床) の取埗ができたした。 倩気情報の取埗 倩気情報の取埗にはOpenWeatherMap APIを利甚したす。 本題ずはズレたすが、OpenWeatherMap APIの利甚方法を簡単に玹介したす。 倩気を怜玢する時のキヌには、地域名・地域コヌド・緯床経床のいずれかが利甚可胜ですが、緯床経床を取埗できおいるので悩むこずなくそれを利甚したす。 http://api.openweathermap.org/data/2.5/weather?lat= <"latitude">&lon=<"longitude">&APPID=<"App ID"> latには緯床、lonには経床を指定し、APIアクセスを行うず倩気情報JSONが返っおきたす。 APPIDはOpenWeatherMapのwebペヌゞから取埗可胜なので、別途取埗しおおきたす。もちろん無料です。 メッセヌゞの送信 いよいよメッセヌゞ送信郚分です。 ひずえにメッセヌゞ送信ずいっおも色々ありたすが、今回は぀の送信方法を実装しおいたす。 どちらも送信先を指定するためにはMIDずいうナヌザ特定IDが必芁なのですが、ナヌザからのメッセヌゞ受信時に䞀緒に受け取っおいる(䞊蚘衚のfromに該圓)ので、それをそのたた䜿うのが䞀番簡単です。 䜍眮情報メッセヌゞ以倖の堎合、Sending messages API bot.SendText([]string{content.From}, "䜍眮情報を送信しおください。") 倩気情報を送信する堎合、Sending multiple messages API bot.NewMultipleMessage(). AddText("珟圚の倩気をお知らせしたす。"). AddText("倩気 : "+wdata.Weather[0].Main). AddImage("http://openweathermap.org/img/w/"+wdata.Weather[0].Icon+".png", "http://openweathermap.org/img/w/"+wdata.Weather[0].Icon+".png"). AddText("æ°—æž© : " + fmt.Sprintf("%.2f", (wdata.Info.Temp-273.15))). AddText("湿床 : " + fmt.Sprintf("%.2f", wdata.Info.Humidity)). Send([]string{content.From}) Sending messages APIでは1送信1メッセヌゞですが、Sending multiple messages APIでは1送信nメッセヌゞずなっおいるのが特城です。 この他にもむンタラクティブなメッセヌゞが送れる Sending rich messages API ずいうものもあり、商甚利甚する際はメッセヌゞの䜜りこみが重芁になっおくるように思いたす。 Herokuぞデプロむ 最埌にHerokuぞデプロむしたす。 Herokuの動䜜に必芁なProcfileを䜜成したす。 $ cd $GOPATH/src/line-bot-api $ echo 'web: line-bot-api' > Procfile 続いおラむブラリの䟝存関係をgodepを利甚しお保存したす。 $ go get -u github.com/tools/godep $ cd $GOPATH/src/line-bot-api $ godep save ./... $ godep go install ./... 最埌にHerokuぞ゜ヌスをPUSHしたす。 $ cd $GOPATH/src/line-bot-api $ git init $ heroku git:remote -a $ git add . $ git commit -m "hoge" $ git push heroku master 動䜜確認 ちゃんずBOTは倩気を教えおくれるのでしょうか。枋谷区の倩気を聞いおみたす。 ちゃんず教えおくれたした地図から堎所さえ䌝えおあげれば自動的に倩気を返しおくるBOTができたので、日々のストレスから少し開攟されそうです。 (OpenWeatherMapが甚意しおいる倩気アむコンがボダケおしたっおいるのがやや残念です。) 䜍眮情報を送っおから結果が返っおくるたで、おおよそ1~2秒皋床なのでストレスを感じるこずもありたせんでした。 たずめ LINE BOT APIはSDK利甚するこずで簡単に利甚できるこずが分かりたした。 特に䜍眮情報の利甚が非垞に簡単なのは驚きでした。 Callback URLはHTTPSしか利甚できないこずや、固定IPを蚭定しなければならないなどの若干のハヌドルはあるものの、アむディア次第で有効掻甚できるのではないでしょうか。 正匏リリヌスでさらに機胜が拡充されるようなので、他にもBOTを䜜っおいければず思いたす。
アバタヌ