Save 37% off PRO during our Black Friday Sale! »

なぜRubyだったのか?Rubyで成長したOSS / fukuokark02

なぜRubyだったのか?Rubyで成長したOSS / fukuokark02

69b93af68320a590f607c296e8edff73?s=128

Ken’ichiro Oyama

November 25, 2017
Tweet

Transcript

  1. なぜRubyだったのか?Rubyで成⻑したOSS Kenʼichiro Oyama Fusic Co.,Ltd. 2017.11.25 1 福岡Ruby会議02

  2. Who 2 福岡Ruby会議02

  3. k1LoW   Kenʼichiro Oyama   @k1LoW   Fusic Co.,Ltd. エンジニア

      基盤ユニット テックリード   PHPer   GitHub organizations   fukuokarb / faultline / emacs-jp / etc. 3 福岡Ruby会議02
  4. 4 福岡Ruby会議02

  5. awspec   RSpec tests for your AWS resources.   https://github.com/k1LoW/awspec

      AWS上に展開したリソースがあるべき状態になっている かどうかをテストするツール 5 福岡Ruby会議02
  6. ec2 6 福岡Ruby会議02  describe ec2('my-ec2-tag-name') do   it { should

    be_running }   its(:instance_id) { should eq 'i-ec12345a' }   its(:instance_type) { should eq ’t2.small' }   its(:public_ip_address) { should eq '123.0.456.789' }   it { should have_security_group('my-sg-name') }   it { should belong_to_vpc('my-vpc') }   it { should have_eip('123.0.456.789') }  end
  7. route53_hosted_zone 7 福岡Ruby会議02  describe route53_hosted_zone('example.com.') do   it { should

    exist }   its(:resource_record_set_count) { should eq 5 }   it { should have_record_set('example.com.').a('123.456.7.890') }   it { should have_record_set('example.com.').mx('10 mail.example.com') }   it { should have_record_set('mail.example.com.')   .a('123.456.7.890').ttl(3600) }   it { should have_record_set('s3.example.com.')   .alias('s3-website-us-east-1.amazonaws.com.', 'Z2ABCDEFGHIJKL') }  end
  8. 63 Resource Types (v.0.88.2)   acm   alb   alb_listener

      alb_target_group   ami   autoscaling_group   cloudformation_stack   cloudfront_distribution   cloudtrail   cloudwatch_alarm   cloudwatch_event   cloudwatch_logs   customer_gateway   directconnect_virtual_inte rface   dynamodb_table   ebs   ec2   ecr_repository   ecs_cluster   ecs_container_instance   ecs_service   ecs_task_definition   efs   eip   elasticache   elasticache_cache_param eter_group   elasticsearch   elastictranscoder_pipeline   elb   iam_group   iam_policy   iam_role   iam_user   internet_gateway   kms   lambda   launch_configuration   nat_gateway   network_acl   network_interface   rds   rds_db_cluster_paramete r_group   rds_db_parameter_group   route53_hosted_zone   route_table   s3_bucket   security_group   ses_identity   sqs   subnet   vpc   vpn_connection   vpn_gateway   waf_web_acl   account 8 福岡Ruby会議02
  9. awspec written by Ruby 9 福岡Ruby会議02

  10. 10 福岡Ruby会議02

  11. アジェンダ   なぜRubyを採⽤したのか   awspecがRubyのコミュニティでどのように成⻑し たのか、様々な問題をRubyの世界でどのように解決 したのか   どのようなPull Requestがあったのか

      awspecのこれから 11 福岡Ruby会議02 awspec v0.x 初期 awspec v0.x 中期 awspec v0.x 後期
  12. なぜRubyを採⽤したのか? 12 福岡Ruby会議02 awspec v0.x 初期

  13. この頃の私にとってのRuby   Ruby on Rails   (挫折したまま   PHPにはない標準機能、構⽂、概念、世界  

    ⾔語⾃体が(Webな)PHPよりも広く⾒えた   豊富で羨ましいGem   Matzと多くの⽇本⼈のRubyコミッタ   その結果⽇本語で展開されるレベルの⾼い議論   難しい。。厳しい。。。⾃分にはできなさそう。。。 13 福岡Ruby会議02
  14. それでいて、 なぜRubyを採⽤したのか? 14 福岡Ruby会議02

  15. 15 福岡Ruby会議02

  16. Serverspec   RSpec tests for your servers.   https://github.com/mizzy/serverspec  

    サーバに展開したリソースがあるべき状態になっている かどうかをテストするツール   RSpec tests for your servers configured by CFEngine, Puppet, Ansible, Itamae or anything else. 16 福岡Ruby会議02
  17. Serverspec 17 福岡Ruby会議02  describe service('ntpd') do   it { should

    be_enabled.with_level(3) }  end  describe iptables do   it { should have_rule('-P INPUT ACCEPT') }  end  describe cgroup('group1') do   its('cpuset.cpus') { should eq 1 }  end
  18. なぜRubyを採⽤したのか?   ServerspecのようにAWSのリソースをテストしたかった   Rubyは書けないがツールとしてServerspecを利⽤していて、DSLという モノの強⼒さを初めて体感した   同じようなDSLで書きたかった   Serverspec本の存在(Serverspecのアーキテクチャの説明)

      Serverspecのコードを参考に実現できるのではないか?   aws-sdk-rubyがAWS SDK for PHPよりも良くできているように⾒ えた   GitHubも活発だった 18 福岡Ruby会議02
  19. awspec is inspired by Serverspec 19 福岡Ruby会議02

  20. Ruby製の素晴らしいOSS と⾔語としての表現⼒に惹かれたから 20 福岡Ruby会議02

  21. Rubyへの苦⼿意識を 作りたい気持ちがまさった 21 福岡Ruby会議02

  22. awspecがRubyのコミュニティでどのように成⻑したのか、 様々な問題をRubyの世界でどのように解決したのか 22 福岡Ruby会議02 awspec v0.x 中期

  23. aws-sdk-ruby 23 福岡Ruby会議02

  24. aws-sdk-ruby v2   リソースを操作するクラスは、以下の2種類   Seahorse::Client::Baseを継承したAws::*::Client   (Aws::EC2::Clientなど)   Resources::Resourceを継承したAws::*::Somename

      (Aws::EC2::Instanceなど)   Clientベースはaws-cliのコマンド名と近いメソッドで操作   Resourceベースのほうがリソースをオブジェクトとして操作できる   aws-sdk-ruby v1の名残? 24 福岡Ruby会議02
  25. awspecはClientベース   Clientベースは基本的に全てのAWSリソースで実装されている   Resourceベースは⼀部にしかない   できるだけ多くのAWSリソースを実装できたほうがよいので awspecのバックエンドはClientベース   ⼀⽅でClientベースだと実装したAWSリソースの設定値の範囲しか

    テストができない 25 福岡Ruby会議02
  26. 26 福岡Ruby会議02

  27. Resourceも活⽤できるようにする⽅向に 27 福岡Ruby会議02

  28. vpc 28 福岡Ruby会議02  describe vpc('vpc-ab123cde') do   it { should

    exist }   its('route_tables.first.route_table_id') { should eq 'rtb-a12bcd34' }  end
  29. 29 福岡Ruby会議02

  30. Resourceベースでの実装の課題   awspecはリソースのREADが基本   ClientベースだとStructの値を利⽤するだけだから安⼼   しかし、Resourceベースのクラスにはリソースの操作(READ以 外)をするメソッドもあるので安易に組み込めない   「awspec使ってて書き⽅間違えたらインスタンスが削除された」は

    洒落にならない   どう解決すべきかのアイデアがあっても、どう実装すべきかがわか らない。。 30 福岡Ruby会議02
  31. Fukuoka.rb 31 福岡Ruby会議02

  32. Rubyコミュニティのサポート 32 福岡Ruby会議02

  33. 33 Awspec::ResourceReader 福岡Ruby会議02

  34. Awspec::ResourceReader   method_missingの機構を利⽤して通常通りStructの値を返すかResource を呼び出すかをスイッチング   Resourceを呼び出すときは必ずAwspec::ResourceReaderを経由 する   Awspec::ResourceReaderでAWSリソースを操作しそうなメソッ ドを潰している

      ブラックリスト⽅式   これで多少は安全にawspecでResourceベースが使えるように 34 福岡Ruby会議02
  35. その他Rubyの機能で解決したこと   method_missing機構を使って、実⾏オブジェクトを変更   オープンクラス機構を使って、AWSからのレスポンスのチェ ック機構を実装   define_method機構を使って、同じようなAWS APIコールメ ソッドを⼀括定義

      クラスメソッド機構を使って、DeprecatedなAPIの保持と Warn表⽰ 35 福岡Ruby会議02
  36. コミュニティに助けられて 考えもしなかった機能が、 Rubyの機能で 想像もできなかった実装⽅法で実現されていく 36 福岡Ruby会議02

  37. どのようなPull Requestがあったのか 37 福岡Ruby会議02 awspec v0.x 中期〜後期

  38. Pull Requestとユースケースの関係   awspecを作っていても実際のユースケースや事例はわからない   本当にわかるのは⾃分のユースケースだけ   awspecをメンテナンスして、Pull RequestやIssueを受け付けるこ とでいろいろな気付きがあった

      Pull RequestやIssueからユースケースを想像できるのでは? 38 福岡Ruby会議02
  39. Add tag matching support. 39 福岡Ruby会議02

  40. Add tag matching support 40 福岡Ruby会議02   各リソースにおいて、タグの保持をテストするマッチ ャの追加  

    #119 PR by igorlg  describe ec2('my-ec2') do   it { should have_tag('Name').value('my-ec2') }  end
  41. タグの活⽤   AWSリソースには⼤抵タグ(ラベルのようなイメー ジ)を付与できる   役割(ロール)でわけたり   設定を記述したり   AMIバックアップ頻度設定とか

      タグが重要だからタグの保持のチェックをしたいので は? 41 福岡Ruby会議02
  42. Add opened_only matcher for security groups. 42 福岡Ruby会議02

  43. Add opened_only matcher for security groups. 福岡Ruby会議02 43   Security

    Groupの「このポートだけオープンしている こと」をテストするマッチャの追加   #121 PR by ceaess  describe security_group('my-sg') do   its(:outbound) do should be_opened_only(50_000)   .protocol('tcp')   .for(%w(100.456.789.012/32 200.567.890.123/32))   end  end
  44. 過不⾜ないかを確認したい   セキュリティグループの「ポートが開いている」だけ のテストでは⼼もとない   もともと、設定数のカウントのチェックとの組み合わせで上 記を満たすことはできていたが、⾒やすさという点で欲しか ったのでは? 44 福岡Ruby会議02

  45. Add ec2 `have_event()` and `have_events()`. 45 福岡Ruby会議02

  46. Add ec2 `have_event()` and `have_events()` 46 福岡Ruby会議02   EC2にイベント(再起動イベントなど)があるか確認 するマッチャの追加

      #131 PR by k1LoW  describe ec2('my-ec2') do   it { should have_event('system-reboot') }  end  describe ec2(’other-ec2') do   it { should_not have_events }  end
  47. イベント通知のチェック   AWSから通知されるスケジュールイベント   メールを⾒過ごしていきなりリブートは怖い   イベント通知が「無いこと」を確認しておきたい   should_not 47

    福岡Ruby会議02
  48. Add ec2 `have_classiclink_security_group()` 48 福岡Ruby会議02

  49. Add ec2 `have_classiclink_security_group()` 49 福岡Ruby会議02   EC2-ClassicがClassicLink先のSecurity Groupをもっ ているかどうかを確認するマッチャの追加  

    #150 PR by matsuzj  describe ec2('my-classic-ec2') do   it { should have_classiclink_security_group('sg-2a3b4cd5') }   it { should have_classiclink_security_group('my-vpc-security- group-name') }  end
  50. EC2-Classicからの脱却   EC2-ClassicをEC2 on VPCへ   https://nulab-inc.com/ja/blog/backlog/move-vpc-ec2- classic/   コードで管理されていない⼿動で作られた構成にテス

    トの恩恵を 50 福岡Ruby会議02
  51. Add CloudTrail support to check if logging is enabled. 51

    福岡Ruby会議02
  52. Add CloudTrail support to check if logging is enabled. 52

    福岡Ruby会議02   CloudTrailでロギングが有効になっているかをテストす るマッチャの追加   #164 PR by arimbun  describe cloudtrail('my-trail') do   it { should be_logging }  end
  53. そもそも   CloudTrailが動いていればAWSに対してのAPIコール を管理できる   「そもそも」そのCloudTrailが動いていなかったら?   ⼼配はつきない 53 福岡Ruby会議02

  54. Add shared_context to specify region by context 54 福岡Ruby会議02

  55. Add shared_context to specify region by context 55 福岡Ruby会議02  

    複数のリージョンをまたいだテストができるようにす る修正   #187 PR by takaishi  describe ec2('my-ec2’), region: 'us-east-1' do   it { should exist }  end
  56. Tokyoリージョンにない(なかった)サービス   AWSのサービスのリリースはだいたい北⽶から   その時から稼働しているus-east-1のサービスとap- northeast-1のサービス両⽅共管理したい 56 福岡Ruby会議02

  57. Backoff sleep for Errors::RequestLimitExceeded errors 57 福岡Ruby会議02

  58. Backoff sleep for Errors::RequestLimitExceeded errors 58 福岡Ruby会議02   AWSのリクエスト制限に引っかかった時に再施⾏をす る機構

      SDKに搭載されているリトライとは別に実装   #328 PR by craigmonson
  59. ⾼速かつ並列に実⾏   コンテナ上から⼤規模に状態テストで利⽤しているら しく、rate limitにすぐに引っかかってしまうらしい   Our tests are too

    fast, and we often get rate limiting errors. 59 福岡Ruby会議02
  60. Pull Requestから想像するニーズ   より⼤きく複雑な構成のものがAWS上に展開されているイメージ   リソースの特定(何をテストするか)はIDではできないレベルになってい る   ワイルドカードや正規表現でのリソース特定の要望もある  

    Wildcard or array matching for subnets #270   Support resources with Regex #323   ⼀⽅でテストは厳密にできるように 60 福岡Ruby会議02
  61. awspecのこれから 61 福岡Ruby会議02

  62. GitHub Star History 62 福岡Ruby会議02

  63. awspecのこれから   awspecは「どこかで使われているOSS」になった   現時点で求められる機能の⾻組みはもうできているはず   「安定」を第⼀としてメンテナンスしていきたい   「テストツールの変化はゆっくりがいい」 by

    t_wada   Semantic Versioning   ⼀部にニーズのある機能はできるだけ分離(柔軟なリソースファ インダなど) -> awsrm   しかしAWSのSDKの機能拡張には追従する   aws-sdk-ruby v3対応 63 福岡Ruby会議02
  64. v0.88.2 64 福岡Ruby会議02

  65. v1.0.0 65 福岡Ruby会議02

  66. 66 福岡Ruby会議02

  67. 「もう⼀度、Rubyと出会う」 67 福岡Ruby会議02

  68. 「もう⼀度、Rubyと出会う」   ⾃分にとっては初めてのRubyとの出会い   Rubyという⾔語だから、コミュニティがあったから、 awspecはできた   awspecというOSSを通じて⼀番成⻑できたのは⾃分   またいつか、もう⼀度Rubyと良い出会い⽅をしたい

    68 福岡Ruby会議02
  69. RubyとFukuoka.rbとOSSに関わる皆さんに感謝します 69 福岡Ruby会議02

  70. 70 Fusicはテクノロジーが 好きなエンジニアを募集しています > https://fusic.github.io Thank you! 福岡Ruby会議02