Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Inside of awspec -AWSをテストする方法。そしてその中のはなし-

Inside of awspec -AWSをテストする方法。そしてその中のはなし-

JAWS Festa 東海道 2016

Ken’ichiro Oyama

October 22, 2016
Tweet

More Decks by Ken’ichiro Oyama

Other Decks in Technology

Transcript

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

      基盤ユニット テックリード   フクオカ カラ キマシタ   JAWS-UG福岡に出没します   GitHub organizations   fukuokarb / dotcake / emacs-jp / etc.   好きなAWSサービス 3 JAWS Festa 2016
  2. ec2  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 belong_to_subnet('subnet-1234a567') }   it { should have_eip('123.0.456.789') }   it { should be_disabled_api_termination }  end 12 JAWS Festa 2016
  3. route53_hosted_zone  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) }   ns = 'ns-123.awsdns-45.net.  ns-6789.awsdns-01.org.  ns-2345.awsdns-67.co.uk.  ns-890.awsdns-12.com.'   it { should have_record_set('example.com.').ns(ns) }   it { should have_record_set('s3.example.com.').alias('s3-website-us- east-1.amazonaws.com.', 'Z2ABCDEFGHIJKL') }  end 13 JAWS Festa 2016
  4. Resource Types (v.0.57.1)   ami   autoscaling_group   cloudtrail  

    cloudwatch_alarm   cloudwatch_event   directconnect_virtual   nterface   ebs   ec2   elasticache   elasticache_cache_par ameter_group   elasticsearch   elb   iam_group   iam_policy   iam_role   iam_user   kms   lambda   launch_configuration   nat_gateway   network_acl   network_interface   rds   rds_db_cluster_para meter_group   rds_db_parameter_gr oup   route53_hosted_zone   route_table   s3_bucket   security_group   ses_identity   subnet   vpc   cloudfront_distributio n   elastictranscoder_pipe line   waf_web_acl 14 JAWS Festa 2016
  5. awspec generate  ~ > awspec generate  Commands:   awspec generate

    cloudwatch_alarm # Generate cloudwatch_alarm spec   awspec generate cloudwatch_event # Generate cloudwatch_event spec   awspec generate directconnect # Generate directconnect spec   awspec generate ebs # Generate attached ebs spec   awspec generate ec2 [vpc_id] # Generate ec2 spec from VPC ID (or VPC "Name" tag)   awspec generate elasticsearch # Generate elasticsearch spec   awspec generate elb [vpc_id] # Generate elb spec from VPC ID (or VPC "Name" tag)   awspec generate help [COMMAND] # Describe subcommands or one specific subcommand   awspec generate iam_group # Generate iam_group spec   awspec generate iam_policy # Generate attached iam_policy spec   awspec generate iam_role # Generate iam_role spec   awspec generate iam_user # Generate iam_user spec   awspec generate kms # Generate kms spec   awspec generate lambda # Generate lambda spec   awspec generate nat_gateway [vpc_id] # Generate nat_gateway spec from VPC ID (or VPC "Name" tag)   awspec generate network_acl [vpc_id] # Generate network_acl spec from VPC ID (or VPC "Name" tag)   awspec generate network_interface [vpc_id] # Generate network_interface spec from VPC ID (or VPC "Name" tag)   awspec generate rds [vpc_id] # Generate rds spec from VPC ID (or VPC "Name" tag)   awspec generate route53_hosted_zone [example.com.] # Generate route53_hosted_zone spec from Domain name   awspec generate route_table [vpc_id] # Generate route_table spec from VPC ID (or VPC "Name" tag)   awspec generate s3_bucket [backet_name] # Generate s3_bucket spec from S3 bucket name. if NO args, Generate all.   awspec generate security_group [vpc_id] # Generate security_group spec from VPC ID (or VPC "Name" tag)   awspec generate subnet [vpc_id] # Generate subnet spec from VPC ID (or VPC "Name" tag)   awspec generate vpc [vpc_id] # Generate vpc spec from VPC ID (or VPC "Name" tag) 16 JAWS Festa 2016
  6. awspec written by Ruby   aws-sdk-rubyの開発が活発だった   re:Invent中の発表とSDKの新機能リリースがほぼリアル タイム  

    Serverspecの良さを感じていた   Serverspec本も相当勉強になる   同じようなDSLでテストをしたかった   Fukuoka.rbがあった   事実、内部実装でかなり助けてもらった   http://k1low.hatenablog.com/entry/2015/12/11/185728 20 JAWS Festa 2016
  7. tree -d awspec/ !"" bin !"" doc # $"" _resource_types

    !"" exe !"" lib # $"" awspec # !"" command # !"" ext # !"" generator # # !"" doc # # # $"" type # # $"" spec # !"" helper # # $"" finder # !"" matcher # !"" stub # $"" type $"" spec 21 JAWS Festa 2016
  8. bundle exec bin/toolbox template   awspecに新しいリソースタイプを追加するときに利⽤ するコマンド   $ bundle

    exec bin/toolbox template redshift   リソースタイプ作成に最低限必要なファイルが⽣成される   ⽣成されたファイルを他のリソースタイプの書き⽅をマネて 修正すればだいたいOK 24 JAWS Festa 2016
  9. bundle exec bin/toolbox docgen   awspecのソースコードからドキュメントを作成するコ マンド   awspecはドキュメントジェネレータまで内包している っ!!

      Awspec::Generator::Doc::Type:*   doc/_resource_types/*.md   ドキュメントもプログラムで⽣成することでaws-sdk- rubyのリリーススピードについていく 26 JAWS Festa 2016
  10. “AWS”をテストするわけではない   “AWS上で⾃分たちが構築したリソース構成”をテスト する   意図した構成で構築できているか?   リソース構成   セキュリティ

      運⽤中も意図した構成のままでいるか?   リソース構成に対しての外形監視に近い   チェック 30 JAWS Festa 2016
  11. AWS Config / AWS Config Rules AWS Config は完全マネージド型のサービスで、セキュリティとガバナンス のため、AWS

    リソースインベントリ、設定履歴、および設定変更通知とい った機能が⽤意されています。Config Rules を使⽤して、AWS Config によ って記録された AWS リソース設定を⾃動的にチェックするルールを作成で きます。(AWS公式サイトより)   AWS謹製!   AWS Configの対応リソース   ALB、ACM、EC2、RDS、S3、VPC、IAM、EBS、 CloudTrail   アカウントにつき最⼤25のルール 33 JAWS Festa 2016
  12. Codenize.tools   “Codenize.tools manege any services by DSL.”   独⾃のDSLでべき等性を担保した形で構成を構築・管

    理できる   リソースの種類ごとにツールが分かれている   チェックだけではなく、構築ができる。むしろ構築⽤   --dry-runでDSLの内容と構築済の構成を⽐較チェック   AWS版のChefやAnsibleに近い   既存の構成からDSLをエクスポートができる   対応リソース   Route53、Security Groups、ELB、IAM、CloudFormation、EIP、 CloudWatch Alarm、CloudWatch Logs、VPC Route table、S3 Bucket Policy、ECR Repository Policy、CloudFront 35 JAWS Festa 2016
  13. Terraform   HashiCorp社が提供するオーケストレーションツール   対象はAWSだけではない   チェックだけではなく、構築ができる。むしろ構築⽤   terraform planでDSLの内容と構築済の構成を⽐較チェッ

    ク   既存の構成からDSLをエクスポートができる   さらにterraformingという強⼒なexport gemもある   対応リソース   多すぎて数えたくない 37 JAWS Festa 2016
  14. 私的使い分け表 ※個⼈の⾒解です! 38 JAWS Festa 2016 ⽤途 エクスポー ト AWSリソー

    スを操作す るか AWS Config AWS Config Rules AWSマネージドで監視したいとき。 構成変更のイベントトリガーで動か したいとき - しない Codenize.tools AWSリソース1種類について⼀括し て管理したいとき(特にIAM、 Route53など) ◯ する Terraform 構成新規構築時(リソースの種類が 全てある場合) ◯ する awspec ⼿動で作った環境のチェック リソース構成が多い環境での外形監 視 ◯ しない
  15. Pull Request   Pull Request(PR)… (ざっくり⾔うと)機能追加申請   AWSリソース構成のテスト⽬的を主とするawspecの PRを⾒れば「どういうところで使いたいのか」「どう いうユースケースで使っているのか」が⾒えてくるの

    ではないか?   PRをウォッチしているとできそう   あ、ちょうどawspecの作者でした   awspecの中(機能追加)と使う⼈の頭の中(ユースケ ース)(想像)を同時にご紹介 42 JAWS Festa 2016
  16. Add tag matching support 44 JAWS Festa 2016   各リソースにおいて、タグの保持をテストするマッチ

    ャの追加   #119 PR by igorlg  describe ec2('my-ec2') do   it { should have_tag('Name').value('my-ec2') }  end
  17. Add ability to search for network interface by name 46

    JAWS Festa 2016   Network Interfaceリソースでもタグの保持をできるよ うにする修正   #191 PR by mdolian  describe network_interface(’eni-12ab3cde') do   it { should have_tag('Name').value('my-eni') }  end
  18. タグの活⽤   みんなタグを活⽤しているっぽい   役割(ロール)でわけたり   設定を記述したり   AMIバックアップ頻度設定とか  

    network_interfaceのhave_tagとか忘れていた   タグが重要だからタグの保持のチェックをしたいので は? 47 JAWS Festa 2016
  19. Add opened_only matcher for security groups. JAWS Festa 2016 49

      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
  20. Add ec2 `have_event()` and `have_events()` 52 JAWS Festa 2016  

    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
  21. Add ec2 `have_classiclink_security_group()` 55 JAWS Festa 2016   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
  22. Add CloudTrail support to check if logging is enabled. 58

    JAWS Festa 2016   CloudTrailでロギングが有効になっているかをテストす るマッチャの追加   #164 PR by arimbun  describe cloudtrail('my-trail') do   it { should be_logging }  end
  23. Add shared_context to specify region by context 61 JAWS Festa

    2016   複数のリージョンをまたいだテストができるようにす る修正   #187 PR by takaishi  describe ec2('my-ec2’), region: 'us-east-1' do   it { should exist }  end
  24. AWSアカウント⾃体のテスト •  awspecは基本的に1つのインスタンス、1つのVPCなどAWS リソース1つ1つに対してテストが可能 •  最近はさらに上位のレベルでテストを書いておきたいことが 多発している •  「このリージョンで起動しているRDSインスタンスは5台」 • 

    「EC2のスケジュールドイベントは現在0件」 •  「このアカウントではIAMの数は4つ」 •  なぜ作らないのか? •  具体的な実装デザインが決まっていない •  リソースタイプ名が決まらない(aws? account? resources?) •  だれか決めて欲しい 65 JAWS Festa 2016
  25. awspecの存在意義 •  Codenize.toolsやTerraformなど、使いやすい構成管理 ツールが出てきたため、AWSリソース⾃体がコードで管 理されるようになってきた •  わざわざ別にテストいらない •  「⼿作業で構築したAWSリソースの管理にはawspecが 良い」

    •  http://inokara.hateblo.jp/entry/2016/02/21/120657 •  AWSのリソース構成をいじらないという安⼼感で、カジ ュアルにspecをgenerateしてチェック •  Yet Another AWS Config Rules 67 JAWS Festa 2016
  26.  $ cat <<EOF > Gemfile  source "https://rubygems.org"  gem "awspec"  EOF

     $ bundle install --path=vendor/bundle --binstubs=bundle_bin  ...  Bundle complete! 1 Gemfile dependency, 25 gems now installed.  Bundled gems are installed into ./vendor/bundle.  $ du -mcs ./  22 ./  22 total 69 JAWS Festa 2016
  27. awspec on AWS Lambda(切望)   RubyがAWS Lambdaで動けばawspecも動くはず   CloudTrail ->

    S3 -> AWS Lambda -> awspec   Rubyistにとって使いやすいAWS Config Rules   CI for AWS on AWS   2回⽬の訴え 73 JAWS Festa 2016
  28. aws-sdk-ruby •  リソースを操作するクラスは、以下の2種類 •  Seahorse::Client::Baseを継承したAws::*::Client •  (Aws::EC2::Clientなど) •  Resources::Resourceを継承したAws::*::Somename • 

    (Aws::EC2::Instanceなど) •  Clientはaws-cliのコマンド名とメソッド名が似ている •  Clientのほうが早くSDKに実装される •  Resourceのほうがリソースをオブジェクトとして綺麗に操作 できる 78 JAWS Festa 2016
  29. Awspec::ResourceReader •  awspecは内部でResourceを呼び出すときは必ず Awspec::ResourceReaderを経由する •  Awspec::ResourceReaderでAWSリソースを操作しそ うなメソッドを潰している •  ブラックリスト⽅式 • 

    これでほぼ安全にawspecが使える •  Resourceが使えるawspecのリソースタイプはドキュメント に”Advanced Use”の節がある 81 JAWS Festa 2016
  30. vpc  describe vpc('vpc-ab123cde') do   it { should exist }

      its(:resource) { should be_an_instance_of(Awspec::ResourceReader) }   its('resource.route_tables.first.route_table_id') { should eq 'rtb-a12bcd34' }   its('route_tables.first.route_table_id') { should eq 'rtb-a12bcd34' }  end 82 JAWS Festa 2016
  31. awsecrets •  Ruby製コマンドラインツール内でaws-cliと同じように認証 情報をAws.configに設定することを⽬指しているgem •  awspecとkumomeで利⽤ •  kumome: CloudWatchメトリクスをCLIでみれるツール • 

    http://k1low.hatenablog.com/entry/2016/02/01/083747 •  正直aws-sdk-rubyでやって欲しいし、Issueが上がっていたはず 85 JAWS Festa 2016  #!/usr/bin/env ruby  require 'awsecrets'  Awsecrets.load  ec2_client = Aws::EC2::Client.new  puts ec2_client   .describe_instances({ instance_ids: [ARGV.first] })   .reservations.first.instances.first