OpenSSLで暗号化したDBデータのデータ移行した話し

qiitaに記事を書きました qiita.com

enum-i18nの話し

この記事はみんなのウェディング Advent Calendar 2017 - Qiita 22日目の記事です。

dotenv+itamae環境をconfig+yaml_vaultに移行した話 - amyroi's logの記事に引き続き@amyroiが担当します。

enum-i18n

Rails4のEnumI18nに対応するイケているgemがなかったので 簡単に作ったものを後日gemにしました。 こちらについて書いていこうと思います。

https://rubygems.org/gems/enum-i18n

以前HatenaBlogの記事で簡単な紹介をしました。 amyroi.hateblo.jp

みんなのウェディングではこのgemを使っていません!

  • 社内ではモンキーパッチとしてリポジトリ内に配置しています。

作った背景

  • プロジェクト内のI18nの構成を綺麗にした。
  • models, viewsで綺麗な構成になったけどenumカラムに対応させてない。
  • enumerizeみたいにRailsEnumも対応させたい! https://github.com/brainspec/enumerize
  • Rails本体にはいつから対応するのかな。まだされない。。

なぜ社内で使えないのか

https://github.com/amyroi/enum-i18n/blob/master/lib/enum-i18n.rb#L10

ライブラリ内部でActiveModel::Name#model_nameメソッドを呼んでいます。

name = model_name.try(:i18n_key).to_s

しかし弊社ではmodel_nameというカラムがschemaに存在します。 そのため、特定のテーブルに対するロジックを書く必要があり、 モンキーパッチとして置くことになりました。

name = (self.class == ::User) ? 'user' : model_name.try(:i18n_key).to_s

残念!

gemにした理由

とても個人的な理由で作りました。

  1. 2017年の抱負を決めずに過ごしてきたので年内に何か残したかったから。
  2. gitのsubmoduleでライブラリを作った記憶はあるけどOSS化はしていなかった。
  3. フリーランスで活動する上でOSS活動について聞かれる事が増えてきたから。

増やしたいメソッド

  • enumカラムの翻訳対応された一覧を取得できるoptionsを追加していきたい。

Contributing

PR送ってくれたら喜びます。

明日のAdvent Calendarは?

みんなのウェディング Advent Calendar 2017 23日目は@matsuhisa_h さんの記事です。

dotenv+itamae環境をconfig+yaml_vaultに移行した話

この記事はみんなのウェディング Advent Calendar 2017 - Qiita 19日目の記事です。
現在業務委託エンジニアとして開発基盤まわりのお手伝いをしている@amyroiです。
12月は各社のAdvent Calendarが盛り上がっていますね。

環境変数管理をdotenvからconfigへのスムーズな移行手順

弊社ではプロジェクトの環境変数管理をDotenv+itamaeで管理していましたが、
Dotenvの廃止をフリーランスでジョインした会社で2回(2社)経験するという珍しい体験をしたので、 今回はその手順、ノウハウを書いていこうと思います。

どうして廃止するの

  • プロジェクトのリポジトリに公開したくない秘密情報をdotenvで管理してhost毎に管理する為によく使われるdotenvですが、host側の管理となると会社の規模によってはインフラ担当者に依頼が発生し、いちエンジニアが管理できない。
  • dotenvファイルを暗号化する機構を別で持つ事もあり、一つの環境変数を変更するのにインフラから作業が切り離せない。
  • host毎の環境変数管理を管理する便利なgemがちゃんとあるのでconfigに変更しようよ。

実現できた事

  • 環境変数をconfigに変更しいちエンジニア側で管理を完結できるようになった。
  • itamaeなどの構成管理が不要になる。
  • 暗号化復号化の機構もリポジトリ内で完結
  • 暗号化用のkeyをAWSのKMSを使い、エンジニア毎・ホスト毎のkeyを一度作るだけでOK。
  • 暗号化復号化処理を自動化させることによりプロジェクトに参加したばかりのエンジニアでも意識する必要がない。

いいことづくめですね

何を使うの?

実際に対応したRails,Rubyのバージョンと実現するために使ったgemを紹介します。 新たに追加したのはconfig, yaml_vault, AWS KMSです。

始める前に

  • 事前調査と設計をしてから手をつけるのが得策です。
  • 事前準備(調査)編と導入編に分けました。
  • 2回目となるconfigへの移行作業の規模が大きく、なかなか大掛かりとなりました。調査と設計をしっかりしていくのがポイントとなります。

事前準備(調査)編

dotenvで管理している機構を確認する

まずはdotenvがリリース環境で展開されどのような構成で動作しているのかを確認します。

  1. dotenvの各enviromentsでの管理の仕方を確認
  2. インフラ側の管理の仕組みを確認
  3. 暗号化の仕組みを確認
  4. 各enviroment環境で復号化される機構の確認
  5. dotenvで管理している環境変数の種類の確認

実例
dotenvの各ホストへの配布にitamae,暗号化にyaml_vaultを利用していました。こちらは全てインフラ側で行われていました。 またdotenvとは別に独自環境変数のclass定義がありました。

enviromentsの目的を明確にする。

プロジェクトで使われているproduction, staging, development, testのenviromentsの意味を明確にします。

実例 developmentとlocal環境、ローカルでのtestとcircle ciでのテストで使っている環境変数に相違がある場合がありました。 みなさんはそんな事しないと思いますが何があるか分かりませんね。ここは前もって整理しておきましょう。

使っている環境変数を確認

  1. 各enviromentsで使われいてる環境変数を復号化して一覧にします。
  2. dotenv以外の独自環境変数classがないかチェックし移行対象にします。
  3. 必要のない環境変数の洗い出しをします。

実例 dotenv以外に独自にclassからYAML.loadさせてアプリ固有の環境変数を作っていました。 そして一部の変数はdotenvから呼び出すというスパゲッティ。

既に使われていない環境変数が残っている事、独自定義の環境変数もどきと重複のチェックも行います。

環境変数の呼び出し元の種類を確認

呼び出し元が統一されていたら楽ですが、そうもいきません。

  • シンゴルクオーテーションとダブルコーテーションの違い
  • exists?を使っているところ
# 3種類ありました。
ENV['GOOGLE_CLIENT_ID']
ENV["GOOGLE_CLIENT_ID"]
ENV.exists?('GOOGLE_CLIENT_ID')

プロジェクト内でRails.env.{enviroment}?で制御している箇所を洗い出す

環境変数をつかっているのにRails.env.{enviroment}?でif分制御している箇所があったりします。 これは [enviromentsの目的を明確にする]でローカルとdevelopmentで違う値を使いたいときなどにハードコーディングしている場合がありますのでリファクタしていくことにしましょう。

導入(設計)編

まだ実装しません。暗号化の仕組みを選定し、設計をしていきます。

暗号化の仕組みを選定する

候補

sekrets(https://github.com/ahoward/sekrets)

Rails5.1から導入される秘密情報の暗号化の参考にされているsekretsが有力候補でしたが、ファイル事暗号化してしまう為、環境変数名がリポジトリ上で確認できません。

yaml_vault(https://github.com/joker1007/yaml_vault)

jokerさんのyaml_vault、vaultキー配下のkeyのvalueだけ暗号化してくれます。 key管理にKMSが使える。

決定

本来ならsekretsにするところですが、key名までも暗号化されてしまうと変数名すらわからない状態になってしまう為、yaml_vaultを採用しました。より運用しやすくするためにrakeタスクを作成することにしました。

暗号化・復号化の仕組みを考える

  • リポジトリには暗号化されたファイルをcommit
  • 復号化されたファイルは.gitignore対象にしコミットしない
  • 復号化のキーはAWS KMSで管理

復号化するタイミングを決める

環境構築時

bin/setup 内で復号化

capistranoデプロイ時

deployコマンドに仕込みます。

code deploy デプロイ時

deployタスクに仕込みます。

導入(実装)編

やっと実装していきます。

config導入

構成

暗号化対象と対象外のファイル、配置構成を下記としました。

config/secret.yml # cookie,sessionkey等。暗号化対象外
config/settings.yml #  enviroments共通の設定ファイル。暗号化対象外
config/settings/ # 復号化されたenviroment毎の設定ファイル(gitignore対象)
|
| - development.yml
| - staging.yml
| - test.yml
| - production.yml
|
config/encrypted/ # 暗号化されたenviroment毎の設定ファイル
|
| - development.yml
| - stging.yml
| - test.yml
| - production.yml

configファイルに環境変数を移動する。

整理した環境変数をconfigファイルに移動していきます。 命名規則も綺麗にしていきましょう。

  • サンプル
ENV['GOOGLE_CLIENT_ID']

=>

Settings.google.client_id

dotenvとconfigの変数の対応表を作ります。

主にRspecでの単体テスト用に作っていきます。 懐かしいjpmobileの絵文字のconversion_tableを思い出して作りました。

このconversion_tableがあれば動作テストを減らすこともできますし、もし移行によるバグが発生しても変更された変数名が他のエンジニアでも容易にチェックできます。

SETTINGS_TABLE_FOR_ENV =
{ 
  GOOGLE_CLIENT_ID: 'google.client_id'
}

削除対象の環境変数は対応表にはいれません。 その代わりSpecに検証対象外のkeyとして残しておきます。

yaml_vaultのrakeタスクを作成する。

さてここでyaml_vaultのrakeタスクを作ります。

理由

  • yaml_vaultのISSUEにも上がっていますが、現時点(2017/08/04)でyaml_vaultは暗号化対象yamlのvaultキー配下をデフォルトで暗号化します。
  • configファイルにvaultキーを作るとSettings.vault.google.client_id となりかっこ悪い
  • オプションで暗号化対象のkeyを渡すとvaultキー以外でも暗号化してくれますが、全て指定しないと他が暗号化されないまま出力されてしまう。
  • エンジニアの日々の運用をしやすいようにSettingsファイル配下のkey一覧を取得して、keyを指定せずに暗号化復号化できるようにrakeタスクを作りました。

実例をお見せしたいですが、ここは公開していないコードになる為割愛します。

実行タスクは下記のようにしました。

暗号化

  • config/encrypted/{enviroment}.ymlからconfig/settings/{enviroment}.ymlを作成
  • config/settings/{enviroment}.ymlが存在する状態で実行
# 全enviromentsを暗号化
$ bundle exec rake yaml_vault:encrypt
# enviroment指定
$ bundle exec rake yaml_vault:encrypt['development']

復号化

  • config/encrypted/{enviroment}.ymlから config/settings/{enviroment}.ymlを作成
# 全enviromentsを復号化
$ bundle exec rake yaml_vault:decrypt

# enviroment指定
$ bundle exec rake yaml_vault:decrypt['development']

暗号化復号化をbin/setup, デプロイタスクに組み込む

環境開発時、検証環境・本番サーバーへのデプロイ時のタスクにそれぞれ上記で作ったrakeタスクを組み込んでいきます。

namespace :config do
  task :decrypted do
    on roles(:app) do
      execute :rake, 'yaml_vault:decrypt["staging"]'
    end
  end
end

after 'deploy:updated', 'config:decrypted'

dotenvからconfig移行のテストを書く

これが一番大事ですね。 rakeタスクのspecはもちろんですが、dotenvとconfigの変数の対応表を使い、specを作っていきます。

  • 各enviroments毎にループさせ、Dotenv.loadをした値と、復号化したconfigファイルの値が一致しているのかのテストを書いていきます。

ここで値チェックは終わりです。あと少し!

dotenvの呼び出し元をconfigの変数名に置換

環境変数の削除の準備ができましたのでconfigの変数名に置換していきます。 ここは対応表を使って置換していくのがいいでしょう。

コードのリファクタ

  • 独自環境変数用のクラス、if分制御している箇所をリファクタしていきます。

動作テスト

  • 各enviroments用のテスト環境を作り、動作テストを行います。

dotenv削除

  1. gem dotenv削除
  2. itamae側のdotenv配置ロジックを削除
  3. リポジトリ内にサンプルのdotenv等があればそちらも削除

リリース!

  • 移行作業を行います。
  • 変更点が多いので監視をしましょう。

後処理

  • 動作テストしてリリースしたら後処理を行います。
  • リリース後ホスト内にあるdotenvファイル群を削除していきます。

移行完了

お疲れ様でした!

最後に(感想など)

  • KMSの設定やテスト環境の構築などは省略しました。
  • dotenvをリリース環境で使っているプロジェクトもまだまだあるんだなというのが正直な感想。
  • 元々インフラチームが管理していた構成は移行作業にもインフラとの密な連携が必要となるのでやるなら早めにした方がよいよ。
  • 調査・設計・実装・テスト・デプロイも全て担当したのでやった感あり。
  • これから移行して行こうと思っている方々の参考になるかな。
  • 最後まで読んでいただきありがとうございます

明日のAdvent Calendarは?

みんなのウェディング Advent Calendar 2017 - Qiita 20日目は@yasukexxx さんの記事です。

RailsのEnumのi18n対応gemを作成しました

RailsEnumi18n対応gemを作成しました

Rails4.1に入ったEnumですがRails5.1になってもi18nに対応していなかったので gemのEnumelizeを使うこともあったと思いますが、 できればRails標準のEnumを使いたかったので、gemを作りました。

enum-i18n | RubyGems.org | your community gem host

f:id:mad-berry:20171008180612p:plain

動くサンプルもこちらに作っています。

github.com

特徴

  • ApplicationRecordにincludeする事により、enum設定してあるカラム全てに自動でi18nの翻訳を対応できるようにしています。
  • i18nのスコープが独自の階層で定義していてもscopを引数に渡すことで既存のi18n定義も呼び出せるようにしています。

その他

Contributingも募集していますのでお気軽にどうぞ

環境変数管理をdotenvからconfigへのスムーズな移行手順

qiitaに記事を書きました qiita.com

リモートワーク環境とツール

この記事は Wondershake Advent Calendar 2016 の6日目の記事です。

リモートワークについて3日目の記事です。 徐々にネタがかぶっていきそうなので先に書いたもん勝ちですね。

2日目は佐々木さんでした。サムネイルが最高ですね。

engineering.wondershake.com

今日話すこと

私はWondershakeの社歴が短いので、リモートを始めたきっかけから 仕事環境とツールについて話そうと思います。

はじめに

自己紹介

@amyroi

サーバーサイドエンジニア

フリーランスを5年経験後女性向けのサービスLocariの開発に参加するために最近Wondershakeに入社しました。

リモートワークのきっかけ

フリーランスを始めたのが2011年でした。

この2011年をきっかけに自宅作業の環境整備をしいられる企業が多くありました。

この年に完全リモートでシステム開発を請け負うエージェントの社長に出会い本格的にリモートワークを開始することになりました。

リモート環境整備

5年の間に自宅でのリモート環境の整備を二転三転させながら、今はとても快適な環境となってきたので紹介します。

デスク

最初はローテーブルに正座椅子、TVをディスプレイ代わりに開発をしていましたが、すぐに長時間での作業は難しくなり、 リビングに合うダイニングテーブルを購入しました。 テーブルの脚をセミオーダーでカットし、キーボードを打つ時に肩が上がらない高さにしました。

椅子

お店の人の勧めで最初にバロンチェアを購入しました。 エンジニアが好きそうなその椅子は購入時の満足感はあったものの、どちらかというと男性向けで 生地の反発力が強く、すぐに疲れるようになってしまい売却。

www.offinet.com

もう一つ悩んでいたCassicoチェアを購入しなおしました。 これは女性専用の椅子でCSの人達やOLさんの多いオフィスで使われているそうです。 www.itoki.jp

ツール

タイムログ

リモートで困るのが稼働時間が見えないこと。 特に稼働時間の提出が必要ない場合があると、自分もどれくらい稼働しているのか見えないのが不安になる時があります。 よく使っていたのがtogglです。

Toggl - Free Time Tracking Software

タスク管理

複数の案件が走ることも多かったので、各プロジェクトでのツールと別に 自分用のタスク管理ツールとしてHiTaskを使っていました。 各プロジェクトと事業用のタスクをまとめて管理していました。 hitask.com

最近Asanaを見つけたので今使うならこっちがオススメ。 asana.com

ビデオ会議

始業時間が決まっている会社の場合は毎日朝会と夕会をビデオ会議でしていました。 これがあるとリモートでも気持ちが引き締まるので結構好きでした。

hangouts.google.com

その他

意識

夜型の多い業界ですが、ここ数年は残業禁止の契約が多かったため、1日の働く時間を決めてその時間に100%集中して仕事を終えるということをしてきました。 そうすると、周りが勝手にそのリズムに合わせてくれるようになりました。帰ってしまう前に決める事はこの時間内に決めてしまおう。 早く帰る人がいるから俺たちももう帰ろう。リリース前や緊急時は別ですが、健全なサイクルが回り始めたりしました。

監視ツール

監視…されてますかね?#姐さんの為に働いてます

さいごに

明日はshirokuraさんのリモートワーク4日目の記事です。皆さんのリモート環境気になりますね!

Ruby on Rails Tech Meetupに行ってきた

Ruby on Rails Tech Meetup

Ruby on Rails Tech Meetupに行ってきました。 久しぶりのRails系の勉強会かも。 ただのメモですがそのうち綺麗にするかも。

「Upgrade Forkwell to Rails5 the faster」

@sinsoku_listy さん

qiita.com

7月のRails5リリース後すぐにプロダクトのRails5へアップデートしたのをよく覚えている。

対応内容として gem update rails5対応のgemへupdaate 定期的にgem updateしてPR送る自社システムを常に使っていた。 Rails Guide読んで対応 落ちたテストの対応 PR作った時点で、Rails4.2でもmergeできるものが有ることに気付き、は先にmergeをした。 APIモードActonCable未使用だったのも比較的悩むこともなかった要因かも。 Railsブランチの監視を常にしていた。 最速リリースをあえて目指してみた。 性能テストはちゃんとはしてないけど、バッチとか遅くなかった。あまり意識していなかった部分。

「まだRailsで消耗してるの?」

@h3_potetoさん
CWのエンジニア CWのRailsつらい.. 何も移譲してないのにポリモーフィック? elixirの話し いろいろRubyっぽいよ bundler + rake -> mix Gemfile -> mix.exs, deps.get, mix phoenix.server rails g model -> mix phoenix.gen.model ORM -> Ecto route -> router.ex erb -> eex 嬉しいこと:sprocketsがいない 非同期処理: そもそも軽量プロセス

「 The State of Sprockets 」

@_yasaichi さん

speakerdeck.com

Pixta Inc. compile assets Rackアプリで実装 sprocketsによりasset pipeline sprockets4.0.0.beta4 source maps devmodeで挙動が変わる application.jsとsource mapsだけ 本番と同じように圧縮して開発可能 ES6 support

Browserify/Webpackでビルドしてsporocketsから離れる

「巨人でない我々のためのバッチ基盤」

@joker1007 さん repro バッチで主にすること aggregate ogs settlement data deletion backup

依存性があって順番を考える必要がある 並行で実行できること retry any jobs 有効非巡回グラフ DAG (Dyrect Analytics Graph) library tsort トポロジカルソート Rukawa gem ワークフローエンジン 分散実行

github.com

依存関係をみながら、 全並行数をセットしながら動かせる creating DAG simple ruby class interface concurrent-rubyを使っている dig dagがリリースされる前に作っていた

感想

一番興味があったのがsporocketsの事とrukawaちょっと使ってみたい