Ruby on Railsにwebpackを使ってPostCSSを導入してみた【ローカル環境編】
こんにちは、エンジニアの井戸田です。
今回はモダンなCSS環境を構築するために流行っていると言われているPostCSS×webpackをRailsに導入してみました。
今回は開発環境だけですが、次回本番運用に関して書いていきたいと思います。
- 環境
- PostCSSとは
- Railsプロジェクトを作る
- webpack環境のためのディレクトリを作成
- npmで必要なライブラリをインストール
- webpack.config.jsにビルドの設定を書く
- Rails側の設定
- テスト
- PostCSSのプラグインの導入方法
- PostCSSのプラグインの紹介
- We’re hiring!!
環境
PostCSSとは
PostCSSはJSプラグインでスタイルを変換するためのツールです。特徴として下記のことが挙げられます。
- PostCSS自体が変換するのではなくCSSパーサーとASTを操作するためのAPIを提供しているだけで、実際にCSSに変換するのはPostCSSのプラグインが行います。
- Sassでよく使う
mixin
extend
変数($)
などの機能がそれぞれ1つ1つのプラグインになっており、それらを入れることで使用が可能になります。 - メタ言語の中でも特にPostCSSは速度が速いです。
ref) https://github.com/postcss/benchmark
Railsプロジェクトを作る
$ rails new sample-postcss -BJ $ bundle install --path vendor/bundle
とりあえず $ bundle exec rails s -b 0.0.0.0 -p 3000
webpack環境のためのディレクトリを作成
プロジェクトルートに client
というディレクトリを作成。ここがwebpack環境のためのディレクトリになっています。
clientディレクトリの構成については下記のようになります。
client |-- webpack.config.js |-- node_modules |-- package.json └── src |-- images |-- javascripts └── stylesheets
npmで必要なライブラリをインストール
client
ディレクトリに移動し、下記のコマンドを入力して package.json
を生成します。
$ npm init -y
webpackをインストール。webpackでは1系を使用したかった為、バージョンの指定をしています。
$ npm install -D webpack@1.14.0
ローカル環境では下記ことを可能にする webpack-dev-server
が、便利なので使っていきます。 webpack-dev-server
はポート8080を使うNode.jsのexpressサーバーです。
- ファイルの変更を検知して自動でビルドをしたのち、ブラウザを自動でリロードする
- HMR(
Hot Module Replacement
)という編集したモジュールを自動で更新する
$ npm install -D webpack-dev-servser
cssやpostcssに必要な style-loader
css-loader
postcss-loader
モジュールと、CSSをJavaScriptでロードせずにlinkタグでロードさせるため、 extract-text-webpack-text
をインストール。
$ npm install -D style-loader css-loader postcss-loader extract-text-webpack-plugin@1.0.1
webpack.config.jsにビルドの設定を書く
- デバッグ用のSourceMapの設定
- entryポイントの設定
- 出力先を設定
- トランスパイルの設定
exstract-text-webpack-plugin
の設定webpack-dev-server
でファイル変更した際に検知し、自動でビルド、自動でブラウザをリロードしてくれるように設定
client/webpack.config.js
/** * Require basic plugins */ const path = require('path'); const webpack = require('webpack'); /** * webpack plugins */ const ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { devtool: 'inline-source-map', context: path.join(__dirname + '/../client/src'), entry: { application: [ 'webpack-dev-server/client?http://localhost:8080', 'webpack/hot/dev-server', './javascripts/application.js' ] }, output: { filename: '[name].js', publicPath: 'http://localhost:8080/assets/' }, module: { loaders: [ { test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css!postcss') } ] }, plugins: [ new ExtractTextPlugin('[name].css'), new webpack.HotModuleReplacementPlugin() ], devServer: { headers: { 'Access-Control-Allow-Origin': 'http://localhost:3000', 'Access-Control-Allow-Credentials': 'true' } } };
webpack-dev-serverの起動用にpackage.jsonに追記
client/package.json
{ ... "scripts": { "dev": " ./node_modules/.bin/webpack-dev-server --debug --hot --inline --devtool --public --host 0.0.0.0 --port 8080 --config ./webpack.config.js", ... }, ... }
webpack.config.js
のentryは client/src/javascripts/application.js
なので、 application.js
に client/src/stylesheets/application.css
をrequireさせます。
画像などもwebpackで配信したい場合は、同様に application.js
にrequireさせます。
client/src/javascripts/application.js
/** * Require stylesheets */ require('../stylesheets/application.css');
Rails側の設定
headタグ内のjavascript_include_tag, stylesheet_link_tagを変更
assets部分は webpack-dev-server
から取得するため、 app/views/layouts/application.html.erb
のheadタグの stylesheet_link_tag
と javascript_include_tag
部分を変更。
app/views/layouts/application.html.erb
<!DOCTYPE html> <html> <head> <title>SamplePostcss</title> <%= csrf_meta_tags %> <%= stylesheet_link_tag 'http://localhost:8080/application.css', media: 'all' %> <%= javascript_include_tag 'http://localhost:8080/application.js' %> </head> <body> <%= yield %> </body> </html>
Railsの起動設定
rails s
と npm run dev
の2つのコマンドを打てば起動できるのですが、面倒くさいので foreman
というgemを使っていきます。
group :development do gem 'foreman' end
ルートディクトリに Procfile
という名前でファイルを作成し編集していきます。
rails: bundle exec rails server -b 0.0.0.0 -p 3000 webpack: npm --prefix ./client run dev
$ bundle exec foreman start
のコマンドで立ち上がります。
テスト
以上でローカル環境の構築は完了したので、テストしていきましょう。
config/routes.rb
Rails.application.routes.draw do root 'static_pages#about' end
app/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController # GET / def about end end
app/views/static_pages/about.html.erb
<h1>about</h1>
client/src/stylesheets/application.css
h1 { color: red; }
http://localhost:3000
にアクセスした結果
h1
タグのcolorが red
になっているのと、 gray
に変更した時に自動でブラウザの更新を行い色が変わりました。
PostCSSのプラグインの導入方法
autoprefixer
というprefixをつけてくれるプラグインを入れていきます。
まず client
ディレクトリに移りnpmで autoprefixer
をインストールします。
$ npm install -D autoprefixer
webpack.config.js
を編集していきます。下記の記述でPostCSSのプラグインを導入することができます。
client/webpack.config.js
... /** * postcss plugins */ const autoprefixer = require('autoprefixer'); module.exports = { ... postcss: [autoprefixer], ... }
それではcssファイルの方に flex
を書いてみます。
client/src/stylesheets/application.css
div { display: flex; }
webpackのビルド後は以下のようになります。
dev { display: -webkit-box; display: -ms-flexbox; display: flex; }
PostCSSのプラグインの紹介
postcss-import
ref) https://github.com/postcss/postcss-import
@import
が使用できるプラグインになっています。postcss-simple-vars
など他のプラグインを使用したファイルをimportした時にエラーになる可能性があるので、config.webpack.js
の postcss
の 方でこちらのプラグインを最初に読み込ませておくようにしましょう。
@import 'componsents/button.css'; @import 'base.css';
postcss-simple-vars
ref) https://github.com/postcss/postcss-simple-vars
SCSSのような $
を使って変数が定義できます。また弊社では変数( $
)はcolorの色を定義時に使用しています。
before
$red-color: #ff0000; $column: 200px; h1 { color: $red-color; } .column-400px { width: calc(2 * column); }
after
h1 { color: #ff0000; } .column-400px { width: calc(2 * 200px); }
postcss-nested
ref) https://github.com/postcss/postcss-nested
SCSSの様にネストを使用できるpluginです。
before
.item { &_title { width: 500px; @media (max-width: 500px) { width: auto; } body.is_dark & { color: white; } } img { display: block; } }
after
.item_title { width: 500px; } @media (max-width: 500px) { .item_title { width: auto; } } body.is_dark .item_title { color: white; } .item img { display: block; }
postcss-mixins
ref) https://github.com/postcss/postcss-mixins
SCSSの様に @mixin
で定義し、 @include
で呼び出す形ではないので注意が必要です。
before
@define-mixin margin-10px { margin: 10px; } .column { @mixin margin-10px; }
after
.column { margin: 10px }
また引数を指定することも可能です。
@define-mixin
引数で 0
を指定しています。 @mixin
の方で $px
の値を指定しなければ 0
になり、指定すればその指定した数値になります。
今回の場合は margin: 10px
となります。
@define-mixin margin $px: 0 { margin: $px } .column { @mixin margin 10px; }
PostCSS Sassy Mixinsと言うプラグインもあり、こちらだとSCSSの時と同じ記法で書けますので検討してみてください。
postcss-extend
ref) https://github.com/travco/postcss-extend
SCSSで使っていたextendと同じ記法で書けます。
before
%padding { padding: 10px; } .margin { margin: 10px; } .item { @extend %padding; @extend .margin; }
after
.item { padding: 10px; margin: 10px; }
いかがでしたでしょうか?
PostCSSのプラグインの種類は豊富で、 mixin
の機能を使いたい思った時には上記で書いた様に、 postcss-mixins
, postCSS-sassy-mixins
など複数ブラグインが存在するので、記法やコードを読んで選んでいく必要がありそうですね。
また拡張しすぎると本来のCSSの記法とかけ離れてしまうため使うプラグインは最小限に抑えるべきだと考えます。
We’re hiring!!
Cluexではエンジニアサイド、ビジネスサイド共にメンバーを募集しています! お気軽にご連絡下さいませ! エンジニアの方、ぜひ情報交換しましょう!
Docker with ECS × Railsを実現させるために考えたこと(導入編)
こんにちは。エンジニアの志村です。
今回から私は「Docker on Rails with ECSを実現させるために考えたこと」と題して、実際にDockerをProductionで運用する際にハマったポイント、また考慮すべき点に関して、数記事に渡って執筆していこうかなと考えております。
弊社では開発環境はDocker + compose、その他はItamae × EC2の構成でしたが、現在ドッグフーディング・本番環境をDocker with ECSに移行しております。
ProductionをDockerで運用しようと思った背景
今回インフラ環境を見直した背景として、
- プロビジョニングツールの管理つらい
→緊急で直接サーバ内で作業をした際にプロビジョニングツールとサーバ側の差異が発生。 - OSにインストールしているライブラリのアップデートが完全手動になっている。
→自動化したい - Productionとドッグフーディング環境の差異
→ドッグフーディング環境で新規ミドルウェアや設定の実験を繰り返していたため
といった理由が挙げられます。
プロビジョニングツール、本番環境とドッグフーディング環境の差異に関してはルールを決めて厳密に管理、またライブラリのアップデートも定期的に新規インスタンスを自動起動するスクリプトを作成すれば問題ないとは思います。
しかし、規模が大きくなったタイミングで導入するのはかなりのコストがかかる、またなるべく上記のようなことを考えずに実装に集中したいという思いから今回のインフラ刷新に踏み切りました。
ProductionをDockerで運用する際に考慮した点
開発環境は既にDockerizeしておりましたが、実際にProductionをDockerにて運用する為には様々な障壁にぶつかりました。
デプロイ
Blue-Green Deployment
恐らく、ECSを使用する際に最も悩むのがデプロイの方式をどのようにするかだと思います。
今まででの環境であればCapistranoを叩いてgitをpullして〜のようにデプロイ出来ましたが、コンテナの場合そのようなデプロイ方法は難しいです。
ECSのデプロイ方法として真っ先に挙げられるのがBlue-Green Deploymentです。
BG Deploymentについては割愛しますが、
- ロールバックが容易
- デプロイ時のダウンタイムを極力抑えることが出来る
のような特徴があげられます。 ロールバックの容易さ、ダウンタイム極小化の観点から弊社でもBG Deployment方式にしました。
BG Deploymentは良いことずくめに見えますが、デプロイの戦略を立てる上では中々苦労した部分です。
ECSを使用した際のBG Deploymentには以下の3種類が考えられるかと思います。
- ECSのMaximum healthy percent, Minimum healthy percentを調整し、徐々にタスクが切り替わるように調整する。
- CLB(Classic Load Balancer)× Autoscaling Groupを使用して切り替える
- ALBに紐付いているTarget groupの優先順位を切り替える
- Routes53を使用し、Standby, ActiveのELBを切り替える
結論から言うと弊社は3を選択しました。 選んだ理由やそれぞれのメリット・デメリットに関しては別の記事で書きたいと思います。
スクリプト
今までの環境であれば、Capistranoという素晴らしいツールが存在するのでそこまでデプロイ環境で悩むことも無かったですが、DockerになるとCapistrano単体でのデプロイ環境の構築は中々難しいと感じました。
デプロイの手順としては下記の通りになります。
- Task definitionの更新
- ECSのServiceをupdate
- TaskがRUNNINGになっているか確認
- インスタンスの状況を見て、ALBのTarget groupの優先順位を切り替える
現在では様々なECS向けのデプロイツールが出ておりますが、上述している通りALBのTarget groupの優先順位を切り替えるという作業が発生する為、社内専用のデプロイツールを作成する方針にしました。
この辺りも詳しくは別の記事で書いていきたいと思います。
CI
現在、CircleCIをはじめとして様々なCIサービスが出ていますね。
弊社でもCircleCIを使用し、Rubocop -> scss-lint -> RSpec -> capistranoという流れでデプロイを行っておりました。
今回の移行にあたって、Jenkinsへシフトさせました。
Jenkins移行の理由として、カスタマイズ性が一番の理由です。
弊社では、ドッグフーディング環境においてはテスト有りデプロイ、テスト無しデプロイの2種類が存在します。
cap dogfooding deploy 〜
のように手動デプロイをし、テストを通す前からディレクターに動作を確認して貰う手順をとっております。
勿論テストを通して完璧な状態で見てもらうのが一番ですが、確認を早め早めにすることによって、実装の最終段階でディレクターの意図と違う!というような不一致を極力減らすことが出来ます。
テストを通してからデプロイだとその回数が減ってしまい、リリーススピードが結果的に落ちてしまうのでテスト無しデプロイを可能にする環境を構築したいという背景がありました。
CircleCIでこのような環境を作成するのは結構な手間だったため、今回はJenkinsのパラメータ付きビルドで処理することにしました。
マイグレーション
RailsではDBスキーマの変更、データのクレンジングにActiveRecord::Migrationを使用します。
一定規模になると ActiveRecord::Migrationを使わない例が多いですが、弊社ではロールバックが容易なのとRubyで記述出来るという点で未だに使用しております。
以前の環境であればcapistranoがよしなにやってくれたのですが、今回の環境の場合、稼働用のTask definitionで実行するのは難しいと判断しました。
そこでbatch, migration専用のインスタンス・クラスタを作成し、デプロイスクリプトを走らせた際にまずmigrationを当該クラスタで実行させるようにしました。
こちらはデプロイスクリプトにバッチ専用のコマンドを実装しました。
バッチ
上記のマイグレーションに使用しているインスタンス・クラスタと併用しております。
cronによるバッチ処理+sidekiqをこのインスタンスで管理しています。
環境変数の扱い
環境変数はEC2 Systems Manager・EC2のインスタンスメタデータ・S3と様々な方法があるかと思います。
今回は管理の手軽さ、実装の容易さというメリットから、S3を選択しました。
具体的にはビルド前にS3からenvファイルをダウンロード→ビルド→デプロイ
という流れになります。
また環境によってnginxのconfやfluentdのconfの中身を変えたいという場合がありますが、
これに関してはenvsubstコマンドを使用し、ビルド時にconfの中身を動的に変えるようにしています。
assets周り
弊社ではwebpackを使用し、assetsをビルドしております。
webpackにてビルド→asset_syncを使用し、S3にアップロード→CloudfrontのInvalidationを走らせる
というフローでデプロイを行っておりました。
デプロイフローが複雑になる + Herokuも推奨していないという点から今回はこのasset_syncを使用するのをやめ、Webサーバから直接配信→サイト前段にCloudfrontを張ってキャッシュをさせるようにしました。
ログ周り
fluentdコンテナを立て、Kinesis, BigQueryにログを流すように変更しました。
厳密なログの記録が必要ないサービスに関しては、Cloudwatchにそのまま流して記録しております。
監視
zabbix-agentコンテナを立て、そこからzabbixにデータを流すようにしています。
勿論zabbix, grafana自体もDockerizeしております。
https://hub.docker.com/r/monitoringartist/dockbix-agent-xxl-limited/
非常に使い勝手が良いので、上記のイメージを使用しております。
インスタンス起動時に勝手に登録してくれてとても使い勝手が良いのですが、インスタンス消えた時にホスト情報をどう削除するか未だに悩んでおります…
以上になります。
次回からは項目ごとに具体的な事例と共に執筆していきたいと考えています。
エンジニアが暗号理論を学んでみた。〜暗号の基礎編〜
こんにちは、神山です。
今まで週3日運動してたのですが、今冬、寒さのあまり週1日のみになってしまいました。極端に寒さに弱いです。
今回は暗号理論についてブログを書かせて頂きました。
暗号理論とは
暗号理論は暗号の仕組みを研究する分野になります。Wikipediaを引用させて頂きました。
暗号理論では主に次の二つを扱う。
- 暗号系 (cryptosystem) の構成方法や性能・安全性などに関する研究
- 暗号や電子署名といった守秘 (confidentiality) や完全性 (integrity) を実現する、 暗号アルゴリズムや暗号プロトコルの研究
暗号理論では、主として、アルゴリズムやプロトコルによってセキュリティ機能を実現する研究(情報セキュリティ)がなされており、 OSやネットワークの特徴を生かしてセキュリティ機能を実現する研究(コンピュータセキュリティやネットワークセキュリティ)と区 別される。
暗号理論には、情報理論、符号理論、計算複雑性理論といった計算機科学、数論や代数幾何、離散数学といった数学、時には 力学系などの物理学の知見が用いられることもある。
引用元: https://ja.wikipedia.org/wiki/%E6%9A%97%E5%8F%B7%E7%90%86%E8%AB%96
要するに、暗号のアルゴリズムの仕組みと安全性を学ぶ学問ということです。ただ、学ぶには大学レベルの数学(主に代数分野)の知識が必要になります。
自分は数学科出身の為、大学時代に少しだけかじりました(専門外だったので習熟度は低いですが…)。最近になって、HTTPSの仕組みを学ぶのに必要になり再度勉強しております。
暗号の代表例
例えば、シーザー暗号とかRSA暗号とか聞いたことある人も多いのではないでしょうか。また合言葉も暗号の一種と言えます。
そこまで詳しくない人もいると思うのでシーザー暗号について説明しようと思います。 シーザー暗号はもとのメッセージ(アルファベットの文字列)を適当に決めた数字の数だけシフトさせて暗号化する方法です。
シフトさせる文字数を3文字としたとき。 a -> d k -> n のように、3文字シフトさせて暗号化する。 「THE ALFEE」 をシーザー暗号(文字数3)で暗号化すると、 「WKH DOIHH」 となる。
メッセージを送りたい人に事前に「3文字シフトで」と伝えておけば、暗号を送り合うことができます。
ちなみにシーザー暗号の由来は、ジュリアス・シーザーから来ております。 ジュリアス・シーザーは紀元前に活躍したとされる政治家、軍人です。「賽は投げられた」という有名な言葉を残しております。
馴染み深い例として、シェイクスピアの戯曲「ジュリアス・シーザー」はご存知でしょうか?
「ブルータス、お前もか」というセリフが出て来る有名なものです。
その「ブルータス、お前もか」のセリフを放った人こそ、ジュリアス・シーザーです。
用語
基本的な知っておくべき用語を挙げました。先程のシーザー暗号を例に取り説明します。
平文
暗号化したいメッセージのことです。「THE ALFEE」が平文です。暗号化
平文を暗号化することです。「THE ALFEE」を「WKH DOIHH」とすることです。復号
暗号文を正規の方法で平文に戻すことです。シーザー暗号で「3文字シフトした」と共有されていた場合、「WKH DOIHH」から「THE ALFEE」という平文を取り出すことを指しております。
ちなみに復号化という言葉が使われることもありますが同じ意味になります。ただ復号という言葉に「暗号を平文に戻す」という意味があるので、復号「化」とすると意味が2重になる為、本当は間違いらしいです。暗号化方式
暗号の名称です。シーザー暗号やRSA暗号などにあたります。鍵
平文を暗号化するのに使うもの、また暗号文を復号するのに使うものです。暗号化方式がシーザー暗号の場合、シフトさせる文字数が鍵です。上の例だと「3」が鍵になります。解読
これは復号と似て非なるものなので注意してください。暗号文から平文を取り出すことではあるのですが、鍵を知らない状態で取り出すことです。
例えば、「探偵が暗号を解読した」というセリフがドラマ等であると思います。これは探偵が鍵を知らない状態で暗号を読み取るからです。基本的に探偵がするのは「解読」です。
もし「復号」としたら、探偵自身が重要参考人ですね(暗号を平文に戻す方法を知っているということなので)。
そもそも暗号とは?
最後に暗号を数学的に説明しようと思います。
暗号化方式とは。 P: 平文の集合(plaintext) C: 暗号化文の集合(ciphertext) K: 鍵の集合(key) E: 暗号化関数の集まり(encryption function) (暗号化関数とは、平文を暗号化するもの。シーザー暗号(文字数3)で暗号化することだと考えればよい。) D: 復号関数の集まり (decryption function) (復号関数とは、暗号文を復号するもの。暗号文をシーザー暗号(文字数3)で復号することだと考えればよい。) この5つからなるものを暗号化方式という。また下記を満たさなくてはいけない。 ∀k ∈ K, ∀p ∈ P, ∃e ∈ E => ∃d ∈ D, d(k, e(k, p)) = p (直訳すると、適当な鍵を用いて平文を暗号化したとき、必ず復号できる方法があるということ。)
数学用語で書いてみましたが、基本的に最後の直訳を理解して頂ければ大丈夫です。 数学こそ、簡単な言葉をただ難しくする暗号ですね。
他にも、秘密鍵暗号(共通鍵暗号)とか公開鍵暗号とか書きたいことがあるのですが、内容が重くなりすぎるのでまた別の機会で書こうと思います。
We’re hiring!!
Cluexではビジネスサイド、エンジニアサイド共にメンバーを募集しています!
お気軽にご連絡下さいませ! エンジニアの方、ぜひ情報交換しましょう!
GrafanaでZabbix/CloudWatchのメトリクス監視を一元化する
Grafanaかっこいいですよね。いつまでも見ていられそうです。
今回は統合監視ツールZabbixとAWSのCloudWatchメトリクス群を Grafanaで一元的に可視化して見れるようにしてみます。
今回の背景
CloudWatchやEC2のメトリクスを見るのに、 AWSにコンソールで入っていちいち確認するの面倒じゃないですか。 加えてサービスごとにAWSアカウントが分かれているとなると更に不便じゃないですか。
・よりリアルタイムなデータを見たいものはZabbixのメトリクスを使用したい
・ELBにアタッチされてるホストの数も見たい
・オートスケーリングどんな感じか見たい
・インスタンス毎のメトリクスも見たい
・ついでにサービス全体でどれくらいの負荷がかかってるかも見たい
・なんなら複数のAWSのアカウントを跨いで見れると尚良い
・・・ということで全部grafanaに突っ込みました。
構成
今回のメインはzabbix-server、Grafana及びCloudWatchあたりになります。
構成はこんな感じです。
Grafanaは標準でCloudWatchをサポートしていて、 Zabbixもプラグインを入れることでデータソースとして使用することが可能です。
ちなみにGrafanaで標準サポートされているデータソースがこちら
・CloudWatch
・Elasticsearch
・Graphite
・InfluxDB
・OpenTSDB
・Prometheus
Zabbixも標準でサポートしてくれると嬉しいです。
grafanaをインストールする
インストールはOSはUbuntuベースで話を進めていきます。
Ubuntu以外に関してのGrafanaのインストールは、詳しくはこちらをご覧ください。
$ wget https://grafanarel.s3.amazonaws.com/builds/grafana_4.1.1-1484211277_amd64.deb $ sudo dpkg -i grafana_4.1.1-1484211277_amd64.deb $ sudo apt-get install grafana
grafanaにZabbixのプラグインをインストール
$ sudo grafana-cli plugins install alexanderzobnin-zabbix-app
GitHub - alexanderzobnin/grafana-zabbix: Zabbix plugin for Grafana dashboard
grafanaを起動
$ sudo service grafana-server start
Grafana自体にHTTPサーバーの機能も内臓されているので、これでGrafanaが立ち上がります。 デフォルトでは3000番ポートを使用するので、適宜リバースプロキシでnginxを前にかませるといいかと思います。そのままでも問題なく使えます。
では次にZabbixのデータを取り込んでいこうと思います。
Zabbix側でgrafana用のユーザーを作成
Zabbix側の手順としては
・grafana用のユーザーを作成する。
・grafana用ユーザーにREAD権限を付与。
といった流れになります。
ちなみにZabbix側でgrafanaユーザーに適切なパーミッションを与えていなかった結果、grafanaからAPI叩いてもデータが取れずに2時間ばかり無駄にしたのは私です。 パーミッションを与えてください。
Zabbixのパーミッションなどは本家にドキュメントがあります。
grafanaでZabbixデータソースの設定
左上のロゴから、[Data Sources] → [Add data source]と辿っていきます。
設定はこんな感じです。
Zabbixには標準でAPIが用意されているので
http://エンドポイント/zabbix/api_jsonrpc.php
をURLのところに設定してあげます。
Zabbix API Detailsには先ほどZabbix側で作成したgrafana用ユーザーのUsernameとPasswordを設定してください。
今回は便宜上、Zabbix Serverが入っているEC2インスタンスにGrafanaも入れているのでVPCやSGなどは特に気にせず、GrafanaをプロキシとしてlocalhostでZabbixのエンドポイントを叩いています。
Zabbix用のダッシュボードを作成
ダッシュボードの作り方などはServerworksさんのこちらのブログが詳しいです。
個人的な要件:EC2のメトリクス表示をオートスケーリングに対応させたい
Grafanaでダッシュボード作ったのはいいものの、 オートスケーリングでインスタンスが増減するたびにグラフの設定し直すのとかめちゃめちゃ面倒ですよね。
そもそもオートスケーリングしなくてもインスタンス多いとグラフ作るのが面倒。
でも1つのパネルで全インスタンスのCPU利用率とか表示させたい。
解決策:正規表現でフィルタリングができる。
文字が黄色くなっている箇所ですが、Host名でフィルタをかけて、ホスト名がマッチするサーバー群のメトリクスを一発で表示することができます。
上の設定だけでこんなグラフがすぐに出来上がります。
これだけでもパネル設定がかなりラクになりました。
そのほかの色々なグラフなどの作り方はgrafana-zabbix.orgが出しているデモの設定が参考になります。
http://play.grafana-zabbix.org/dashboard/db/grafana-zabbix-demo
GrafanaでCloudWatchをデータソースに設定する
続いてGrafanaにCloudWatchのデータを取り込んで、グラフを表示させていきます。
AWS IAMでgrafana用のユーザーを作成
CloudWarchReadOnlyAccess
ポリシーをアタッチしたユーザーをIAMで作成します。
Grafanaの方で使用する認証情報はアクセスキー及びシークレットキーになります。
GrafanaでCloudWatchデータソースの設定
本家Grafanaのドキュメントではaws-cliのクレデンシャルファイルを使用した設定方法となっていますが、 設定画面から直接IAMユーザーのアクセスキーとシークレットキーを入れることも可能です。
個人的にはサーバーの中に credential
を置く必要ないので、GUIで設定しちゃうとがラクかなと思います。
GUIで設定しても、再度設定を開くとアクセスキーなどは見れないようになっています。
これでCloudWatchの方からもメトリクスを表示が可能となりました。
複数のAWSアカウントを設定する際も同じ要領でIAMユーザーを作成し、データソースを追加していくことでGrafanaからデータを取り出せます。
ELBのHealthyHostCountをパネルに表示する
試しにCloudWatchからのメトリクスとしてELBにアタッチされているHealthyHostCountのメトリクスを表示させてみます。
設定としてはこんな感じです。
これでZabbix及びCloudWatchからデータが取れるようになったので、あとはパネルを一通り作れば、完成です!
【番外編】 AWSの請求情報をgrafanaで確認する
AWSの請求情報、ついでにGrafanaで見たくないですか? 私は見たいです。
例えばこんな感じ。
Grafanaの公式サイトにあるテンプレートを使えばすぐに表示させることができます。
上記のものだとインポートした後にカスタマイズができないので、 インポートした後にカスタマイズしたいという方には、カスタマイズできるやつ置いておきます。
よかったら使ってください。
GitHub - yoshi42662/Grafana-AWS-Billing-Dashboard
We’re hiring!!
Cluexではビジネスサイド、エンジニアサイド共にメンバーを募集しています! お気軽にご連絡下さいませ! エンジニアの方、ぜひ情報交換しましょう!
男もすなるsshといふものを、我もしてみむとて解説するなり
こんにちは。エンジニアでインターンをしている村田です。 最近寒くてベッドから起き上がるのがつらいです。
最近デスクトップ環境をxubuntuにしたのですが使いやすくて感動してます。 軽くて、Ubuntuらしい便利な機能も多くありますので他の方にもぜひおすすめです!
話は変わりますが、コンピュータの用語で新しく知ったものを調べると なんでこんなにわかりづらい説明しかないんだ!! と思ったことってありませんか?
自分は結構多いです、この現象(笑)。 学習していくとそれが当たり前になってしまうので「このサイトにわかりやすく書いてあるじゃん」と思うのですが、最初は難しく感じてしまうものなんですよね。
今回は以前自分が概念を理解するまでに苦労してしまった「sshのしくみ」についてまとめていこうと思います。 (「わかりやすい」というのは個人的な感想です。)
「ssh」略さずに言うと?
「ssh」はsecure shellの略です。 日本語にすると安全なシェルということです。
「ssh」っていつ使うの?
「sshとは安全なシェルのことです!」と言われてもそれではなんのことかわからないと思いますので、もう少しかみ砕いて説明していきます。 このページをご覧になっている方は、例えば「サーバーにアクセスしようとしたけどsshってどういうことなんだ?」とか「GitHubを使ってみたいけどなんか登録してsshを使わなくちゃいけないらしい」といった方が多いかと思います。
それではsshとはどういう場面で必要なのでしょうか?
簡単な言葉で説明すると「他のコンピュータに対してアクセスして、何かしらの操作を加えたいとき」にsshを使います。 例えば「サーバーに対してコマンドを実行して環境を作りたい」とか「GitHubなどのリモートリポジトリに対してブランチをマージさせたい」といったところで、sshというコマンドを使用したいわけです。
基本的にはssh user@host_name
で使います。
これは色々なところで書いてあるのでわかりやすいと思います。
そもそも、「安全なシェル」の「シェル」とは人間とコンピュータが気軽におしゃべりするための言語です。 ディレクトリを変えたり、 ファイルを削除したい!というときの「cd」とか「rm」はそれに当たりますよね。
遠くのコンピュータに命令したいときも当然同じようにおしゃべりできたら便利なわけですから、シェルを使いたいですよね。 ただし、暗号化なしで通信するとほかの人に見られる危険などがあるため安全なシェルすなわちsshを使いたいということなのです。 (実は以前は暗号化されていないtelnetというものを使っていました。基本的な機能しかないことを利用して、現在もサーバーを作る際にときどき用いることがあります。)
暗号化の仕組み
sshで公開鍵暗号方式を使用しています。(実は違うやり方でパスワード認証方式というのもありますが、あまり使われないように思われます。) 公開鍵暗号方式の通信とはサーバーに公開鍵を持たせて文書等を暗号化させて、受信する際には自分の持っている秘密鍵を使用して複合する通信のことです。
これを例えるとすると、 公開鍵を錠(lock)、秘密鍵はその錠の鍵(key)だと考えてください。
南京錠などを想像すればわかるように、lockのやり方がわかっても、keyが用意できなければ実際に中身にたどり着くことはできません。 リアルの世界とは違って暗号化の世界では錠の鍵穴を見て鍵を作り出すことができない(らしい)ので、自分の秘密鍵をばらさなければこれで安全に通信することが可能なわけです。
また、sshではより安全性を高めるために秘密鍵に対して鍵をかけるのが一般的です。 鍵に鍵をかけるというのは面白いですよね。
この鍵は暗号化も複合化も同じ共通鍵暗号方式を使用しています。
実際に使用していくコマンド
ここでは実践で使っていくコマンドを簡単に紹介していきます。 紹介できなかったオプションやコマンドがたくさんあると思うので、不足している部分に関しては最後の参照URL等をご覧ください。
また事前知識としてsshに関するファイルは~/.ssh
というディレクトリに入るのですが、そこのファイルの役割を紹介しておきます。
authorized_keys 公開鍵を登録しておくファイル。 config SSH接続に関する設定を書いておくファイル。 known_hosts 過去に接続したことがあるサーバーを書いておくファイル。
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
これはgithubで推奨されている鍵の作り方です。
-t rsa
の部分はRSAという暗号化方式を使って作成するという意味です。
他にもDSAやECDSAといった種類がありますが一般的にはRSAを用いるのではないかと思います。
また-b 4096
では鍵のビット数をしてしています。デフォルトでは2048になのでより強固に作成していると言えますね。
-C "your_email@example.com"
の部分はコメントなので必要なければ省いて構いません。
途中でパスフレーズを聞かれると思いますが、これが先ほど書いたとおり秘密鍵に対するパスワードになっているので忘れないものを使用してください。
このコマンドを実行するとid_rsa
とid_rsa.pub
が作成されます。もちろん前者が秘密鍵、後者が公開鍵です。
余談ですが、GitHubユーザーのSSH鍵6万個を調べてみたでGitHubのssh鍵に関して面白い考察がありました。
ssh-copy-id -i ~/.ssh/id_rsa.pub user@host_name
これはsshの公開鍵を登録したいサーバーに送るコマンドです。
i
オプションで任意のファイルを指定して送ることができます。ここでは先程作成した~/.ssh/id_rsa.pub
を指定しています。
ssh-agentとssh-add ~/.ssh/id_rsa
ssh-agent
は認証エージェントとよばれるもので、sshをするときに必要なパスワードの入力をショートカットできるようにするコマンドです。
(ubuntuやMacの人は自動的に起動しているのでこのコマンドは忘れてしまっても問題ありません。ただ、他のOSではssh-agent bash
などを打たないといけないかもしれません。)
ssh-add
はssh-agent
に秘密鍵を追加するメソッドです。
引数にとった秘密鍵を追加します。
参照URL
http://qiita.com/tag1216/items/5d06bad7468f731f590e http://qiita.com/suthio/items/2760e4cff0e185fe2db9 http://webos-goodies.jp/archives/50672669.html
またこちらは書籍ですが、私がsshの仕組みを少し理解できるようになったきっかけになった本です。 はじめてUNIXで仕事をする人が読む本
HTMLテンプレートエンジン「slim」の解析ツールslim-lintを導入してみた!
こんにちは、エンジニアの井戸田です。
弊社ではmamanokoという子育てをするママのためのメディアをRuby on Railsで運営しており、viewではHTMLテンプレートエンジンであるslimを使用しています。今までrubyの解析ツール rubocop
や、scssの解析ツール scss-lint
は導入しましたが、slimの解析ツールを導入していなかったということで、今回導入してみました。
インストール
$ gem install slim_lint
又は Gemfile
に下記を記入して bundle install
をすることでインストールが可能です。
gem 'slim_lint', require: false
require: false
を指定することで、 autorequire
をしないようにしています。
実行方法
スキャンするディレクトリ、又は複数のディレクトリを指定することによって、コマンドラインから slim-lint
を実行することが可能です。
$ slim-lint app/views $ slim-lint app/**/*.slim
又 slim-lint -v/--version
を指定するとバージョンを確認ができます。他にもいろいろなオプションがあるので、下記のURLから御覧ください。
ref) https://github.com/sds/slim-lint#usage
実装
slim-lintはデフォルトで下記のような設定になっています。
ref) https://github.com/sds/slim-lint/blob/master/config/default.yml
# Default application configuration that all configurations inherit from. # # This is an opinionated list of which hooks are valuable to run and what their # out of the box settings should be. # Whether to ignore frontmatter at the beginning of Slim documents for # frameworks such as Jekyll/Middleman skip_frontmatter: false linters: CommentControlStatement: enabled: true ConsecutiveControlStatements: enabled: true max_consecutive: 2 EmptyControlStatement: enabled: true RedundantDiv: enabled: true LineLength: enabled: true max: 80 RuboCop: enabled: true # These cops are incredibly noisy since the Ruby we extract from Slim # templates isn't well-formatted, so we ignore them. # WARNING: If you define this list in your own .slim-lint.yml file, you'll # be overriding the list defined here. ignored_cops: - Lint/BlockAlignment - Lint/EndAlignment - Lint/Void - Metrics/LineLength - Style/AlignHash - Style/AlignParameters - Style/BlockNesting - Style/FileName - Style/FirstParameterIndentation - Style/FrozenStringLiteralComment - Style/IfUnlessModifier - Style/IndentationConsistency - Style/IndentationWidth - Style/MultilineArrayBraceLayout - Style/MultilineAssignmentLayout - Style/MultilineHashBraceLayout - Style/MultilineMethodCallBraceLayout - Style/MultilineMethodDefinitionBraceLayout - Style/MultilineMethodCallIndentation - Style/MultilineOperationIndentation - Style/Next - Style/TrailingBlankLines - Style/TrailingWhitespace - Style/WhileUntilModifier TagCase: enabled: true TrailingWhitespace: enabled: true
この設定の中で、不要・変更したい設定に対して、ホームディレクトリに .slim-lint.yml
というファイルを作成し、記述することで無効化・変更します。
.slim-lint.yml
の記述例
exclude: - 'repository_name/app/views/**/*.slim' linters: CommentControlStatement: enabled: false LineLength: include: 'repository_name/app/views/**/*.slim' max: 80 EmptyControlStatement: exclude: 'repository_name/app/views/**/*.slim'
オプション | 説明 |
---|---|
exclude | slim-lintや各linterから除外したいファイルがある時に使用します。 |
include | 指定したファイルで絞り込みを行います。 |
enable | false とした時には、そのlinterが走ることはありません。そのlinterが不要な時に使用します。 |
linterの説明
CommentControlStatement
コメントの書き方についての制御するlinterです。
- Bad
# commentout
- Good
/ commentout
ConsecutiveControlStatements
連続の制御文に対して制御するlinterです。
ConsecutiveControlStatements
には下記ようなオプションがあります。
制御構文が同じインデントで2行以上続くのでしたら、見やすさからviewに書かずに helper
にその制御を移動させた方がいいと思います。
オプション | 説明 |
---|---|
max_consecutive | 行に指定できる制御文の最大数 |
- Bad
- code1 - code2 - code3
- Better
ruby: code1 code2 code3
- Good
- helper_method_name
EmptyControlStatement
空行に対して制御するlinterです。
こちらのlinterを true
にすると空行がなくなり、場合によっては見づらくなる可能性があるので、注意する必要がありそうですね。
- Bad
p pタグ - p pタグ
- Good
p pタグ p pタグ
RedundantDiv
div
タグに対して制御するlinterです。
slimでは div.class_name
と書かずに .class_name
と記述するだけで divタグ
になります。不要な場合に div
と記述しないというのが、このlinterの役割です。
- Bad
div.class_name
- Good
class・idを指定せず、ただの改行などの場合に使用する場合にはdiv
と記述する必要があります。
div
- Good
.class_name
RuboCop
このlinterはテンプレート内に存在する Ruby
コードをチェックする為のものです。
ホームディレクトリに作成された .rubocop.yml
の内容が反映されるようです。
ref) https://github.com/bbatsov/rubocop
オプション | 説明 |
---|---|
ignored_cops | 無視したいRubocopの設定を記述 |
TagCase
大文字のタグ名を報告するlinterです。
HTMLの標準では、小文字のタグ名を限定するということはなく、大文字でも対応できるのですが、XHTMLでは小文字の記述が必須なので、一貫性としてこのlinterが作られたようです。
個人的に大文字・小文字が混ざっているいると見づらい点や、小文字にすることで大文字より見やすくなる点があるので、小文字で揃えた方がいいと思います。
- Bad
BODY p pタグ
- Good
body p pタグ
いかがでしたでしょうか?
slim-lint
を導入することで、気をつけて同じフォーマットにしようとしていても、どうしても見逃してしまう部分や、行数を制限することで、1つのファイルだけで処理するのではなく、partial化させることにより見やすくなると思います。
最後まで読んでいただきありがとうございます。
We’re hiring!
フロントエンジニアの方で、サーバーサイドを触ってみたい方、ぜひ一度Cluexに遊びに来てください!!
AWSのCloudFrontからコンテンツをHTTP2 & gzipで高速に配信する
こんにちは、高橋です。
みなさん快適で楽しいAWSライフを送れていますか?
実は2ヶ月ほど前、AWSからCloudFrontでHTTP2によるコンテンツの配信ができるようになったので早速導入して見ました。
Amazon CloudFront now supports HTTP/2
S3のバケットにあるCSSやJS、画像などのアセットをCloudFrontから配信するというパターンは AWSでインフラを構築するサービスではよくあると思います。
今回はこういったS3上にあるアセットをHTTP2とgzipを使用してCloudFrontから配信するための設定方法などを見ていきたいと思います。
設定そのものは3分くらいで終わります。
CloudFrontにHTTP2を適用する
先ずはAWSのコンソールを開き、CloudFrontを選択します。
リンクまたはチェックボックスを押して「Distribution Settings」からディストリビューションの設定画面に飛びます。
「General」タブの「Edit」ボタンから基本設定の変更ページへ飛びます。
「Supported HTTP Versions」をHTTP2が含まれているものを選択して、右下の「Yes, Edit」ボタンを押します。
ちなみに「Supported HTTP Versions」の右にある黒いボタンを押すと、下記のような説明が出てきます。
For viewer requests, choose the versions of the HTTP protocol that you want CloudFront to accept. In general, HTTP/2 is faster. CloudFront always forwards requests to the origin using HTTP/1.1.
日本語にすると
ユーザーからCloudFrontへのリクエストの際に使用するHTTPプロトコルを選択してください。一般的にHTTP2は速いっすよ。CloudFrontからオリジンへのリクエストはHTTP 1.1だけ使うでー。
といった感じでしょうか。
ユーザーからのリクエストはHTTP2を使用できますが、CloudFront内部でのリクエストではHTTP2はまだ未対応のようです。
とはいえ、ひとまずこれで設定完了です!楽勝ですね!
あとは設定が完了するまで時間を潰して、 設定が完了したらブラウザから確認できればOK!
Chromeなどのブラウザのデベロッパーツールから見てみると.....
レスポンスは304になっていますが、「Protocol」のところが「h2」になっていれば設定完了です!
CloudFrontでgzip圧縮による配信をする
では次にファイルをgzip圧縮して配信する設定を見ていきましょう。
先ほどのディストリビューションの設定画面に飛びます。
今回は「Behaviors」タブを選択して、gzip配信にしたいものにチェックボックスを入れて「Edit」を押します。
下にスクロールしていくと、一番下に「Compress Objects Automatically」という設定項目があるので、「Yes」を選択してから右下の「Yes, Edit」を押して設定完了!
ちなみに「Compress Objects Automatically」の右にある黒いボタンを押すと、下記のような説明が出てきます。
Select whether you want CloudFront to automatically compress content for web requests that include Accept-Encoding: gzip in the request header. CloudFront compresses files of certain types for both Amazon S3 and custom origins.
日本語にすると
わいに頼んでくれたらリクエストヘッダにAccept-Encoding: gzipがあった時はCloudFrontの方でコンテンツの圧縮しとくで。S3とか別のオリジンのファイルでも圧縮できそうなら、わいが勝手にしとくやでー。
といった感じでしょうか。
圧縮倍率はCloudFrontの方でよしなに決めてくれるようです。
ということで設定が終わったのでブラウザから確認して見ましょう!
先ほどと同様にChromeなどでデベロッパーツールを開き、CloudFrontから配信されているファイルのレスポンスヘッダを確認します。
「content-encoding: gzip」となっていますね!
これでCloudFrontにHTTP2とgzip配信の設定が完了しました!
手軽にできてすぐに効果が期待できるので、気になった方は試して見てください!
We're hiring!
Cluexではビジネスサイド、エンジニアサイド共にメンバーを募集しています! お気軽にご連絡下さい!