Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

Who 2 福岡Ruby会議02

Slide 3

Slide 3 text

k1LoW   Kenʼichiro Oyama   @k1LoW   Fusic Co.,Ltd. エンジニア   基盤ユニット テックリード   PHPer   GitHub organizations   fukuokarb / faultline / emacs-jp / etc. 3 福岡Ruby会議02

Slide 4

Slide 4 text

4 福岡Ruby会議02

Slide 5

Slide 5 text

awspec   RSpec tests for your AWS resources.   https://github.com/k1LoW/awspec   AWS上に展開したリソースがあるべき状態になっている かどうかをテストするツール 5 福岡Ruby会議02

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

awspec written by Ruby 9 福岡Ruby会議02

Slide 10

Slide 10 text

10 福岡Ruby会議02

Slide 11

Slide 11 text

アジェンダ   なぜRubyを採⽤したのか   awspecがRubyのコミュニティでどのように成⻑し たのか、様々な問題をRubyの世界でどのように解決 したのか   どのようなPull Requestがあったのか   awspecのこれから 11 福岡Ruby会議02 awspec v0.x 初期 awspec v0.x 中期 awspec v0.x 後期

Slide 12

Slide 12 text

なぜRubyを採⽤したのか? 12 福岡Ruby会議02 awspec v0.x 初期

Slide 13

Slide 13 text

この頃の私にとってのRuby   Ruby on Rails   (挫折したまま   PHPにはない標準機能、構⽂、概念、世界   ⾔語⾃体が(Webな)PHPよりも広く⾒えた   豊富で羨ましいGem   Matzと多くの⽇本⼈のRubyコミッタ   その結果⽇本語で展開されるレベルの⾼い議論   難しい。。厳しい。。。⾃分にはできなさそう。。。 13 福岡Ruby会議02

Slide 14

Slide 14 text

それでいて、 なぜRubyを採⽤したのか? 14 福岡Ruby会議02

Slide 15

Slide 15 text

15 福岡Ruby会議02

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

なぜRubyを採⽤したのか?   ServerspecのようにAWSのリソースをテストしたかった   Rubyは書けないがツールとしてServerspecを利⽤していて、DSLという モノの強⼒さを初めて体感した   同じようなDSLで書きたかった   Serverspec本の存在(Serverspecのアーキテクチャの説明)   Serverspecのコードを参考に実現できるのではないか?   aws-sdk-rubyがAWS SDK for PHPよりも良くできているように⾒ えた   GitHubも活発だった 18 福岡Ruby会議02

Slide 19

Slide 19 text

awspec is inspired by Serverspec 19 福岡Ruby会議02

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

awspecはClientベース   Clientベースは基本的に全てのAWSリソースで実装されている   Resourceベースは⼀部にしかない   できるだけ多くのAWSリソースを実装できたほうがよいので awspecのバックエンドはClientベース   ⼀⽅でClientベースだと実装したAWSリソースの設定値の範囲しか テストができない 25 福岡Ruby会議02

Slide 26

Slide 26 text

26 福岡Ruby会議02

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

vpc 28 福岡Ruby会議02  describe vpc('vpc-ab123cde') do   it { should exist }   its('route_tables.first.route_table_id') { should eq 'rtb-a12bcd34' }  end

Slide 29

Slide 29 text

29 福岡Ruby会議02

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

Fukuoka.rb 31 福岡Ruby会議02

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

33 Awspec::ResourceReader 福岡Ruby会議02

Slide 34

Slide 34 text

Awspec::ResourceReader   method_missingの機構を利⽤して通常通りStructの値を返すかResource を呼び出すかをスイッチング   Resourceを呼び出すときは必ずAwspec::ResourceReaderを経由 する   Awspec::ResourceReaderでAWSリソースを操作しそうなメソッ ドを潰している   ブラックリスト⽅式   これで多少は安全にawspecでResourceベースが使えるように 34 福岡Ruby会議02

Slide 35

Slide 35 text

その他Rubyの機能で解決したこと   method_missing機構を使って、実⾏オブジェクトを変更   オープンクラス機構を使って、AWSからのレスポンスのチェ ック機構を実装   define_method機構を使って、同じようなAWS APIコールメ ソッドを⼀括定義   クラスメソッド機構を使って、DeprecatedなAPIの保持と Warn表⽰ 35 福岡Ruby会議02

Slide 36

Slide 36 text

コミュニティに助けられて 考えもしなかった機能が、 Rubyの機能で 想像もできなかった実装⽅法で実現されていく 36 福岡Ruby会議02

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

Add tag matching support. 39 福岡Ruby会議02

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

タグの活⽤   AWSリソースには⼤抵タグ(ラベルのようなイメー ジ)を付与できる   役割(ロール)でわけたり   設定を記述したり   AMIバックアップ頻度設定とか   タグが重要だからタグの保持のチェックをしたいので は? 41 福岡Ruby会議02

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

過不⾜ないかを確認したい   セキュリティグループの「ポートが開いている」だけ のテストでは⼼もとない   もともと、設定数のカウントのチェックとの組み合わせで上 記を満たすことはできていたが、⾒やすさという点で欲しか ったのでは? 44 福岡Ruby会議02

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

イベント通知のチェック   AWSから通知されるスケジュールイベント   メールを⾒過ごしていきなりリブートは怖い   イベント通知が「無いこと」を確認しておきたい   should_not 47 福岡Ruby会議02

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

EC2-Classicからの脱却   EC2-ClassicをEC2 on VPCへ   https://nulab-inc.com/ja/blog/backlog/move-vpc-ec2- classic/   コードで管理されていない⼿動で作られた構成にテス トの恩恵を 50 福岡Ruby会議02

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

そもそも   CloudTrailが動いていればAWSに対してのAPIコール を管理できる   「そもそも」そのCloudTrailが動いていなかったら?   ⼼配はつきない 53 福岡Ruby会議02

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

Tokyoリージョンにない(なかった)サービス   AWSのサービスのリリースはだいたい北⽶から   その時から稼働しているus-east-1のサービスとap- northeast-1のサービス両⽅共管理したい 56 福岡Ruby会議02

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

Backoff sleep for Errors::RequestLimitExceeded errors 58 福岡Ruby会議02   AWSのリクエスト制限に引っかかった時に再施⾏をす る機構   SDKに搭載されているリトライとは別に実装   #328 PR by craigmonson

Slide 59

Slide 59 text

⾼速かつ並列に実⾏   コンテナ上から⼤規模に状態テストで利⽤しているら しく、rate limitにすぐに引っかかってしまうらしい   Our tests are too fast, and we often get rate limiting errors. 59 福岡Ruby会議02

Slide 60

Slide 60 text

Pull Requestから想像するニーズ   より⼤きく複雑な構成のものがAWS上に展開されているイメージ   リソースの特定(何をテストするか)はIDではできないレベルになってい る   ワイルドカードや正規表現でのリソース特定の要望もある   Wildcard or array matching for subnets #270   Support resources with Regex #323   ⼀⽅でテストは厳密にできるように 60 福岡Ruby会議02

Slide 61

Slide 61 text

awspecのこれから 61 福岡Ruby会議02

Slide 62

Slide 62 text

GitHub Star History 62 福岡Ruby会議02

Slide 63

Slide 63 text

awspecのこれから   awspecは「どこかで使われているOSS」になった   現時点で求められる機能の⾻組みはもうできているはず   「安定」を第⼀としてメンテナンスしていきたい   「テストツールの変化はゆっくりがいい」 by t_wada   Semantic Versioning   ⼀部にニーズのある機能はできるだけ分離(柔軟なリソースファ インダなど) -> awsrm   しかしAWSのSDKの機能拡張には追従する   aws-sdk-ruby v3対応 63 福岡Ruby会議02

Slide 64

Slide 64 text

v0.88.2 64 福岡Ruby会議02

Slide 65

Slide 65 text

v1.0.0 65 福岡Ruby会議02

Slide 66

Slide 66 text

66 福岡Ruby会議02

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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