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

Inside of awspec

Inside of awspec

JAWS-UG福岡:3度目の濃い目にAWSの話をしてみよう

69b93af68320a590f607c296e8edff73?s=128

Ken’ichiro Oyama

June 11, 2016
Tweet

Transcript

  1. Inside  of  awspec Kenʼ’ichiro  Oyama Fusic  Co.,Ltd. 2016.6.11 1 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  2. Who 2 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

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

      CakePHP/AWS/さくらVPS   GitHub  organizations   fukuokarb  /  dotcake  /  emacs-‐‑‒jp  /  etc.   好きなAWSサービス 3 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  4. 4 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  5. awspec •  AWSリソースの構成テストツール •  http://github.com/k1LoW/awspec •  構築したAWSリソースをRSpecなDSLでテストが可能 5 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  6. 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 6 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  7. 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 7 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  8. Resource  Types  (v.0.40.0) •  ami •  autoscaling_̲group •  cloudwatch_̲alarm • 

    directconnect_̲virtual_̲i nterface •  ebs •  ec2 •  elasticache •  elasticache_̲cache_̲para meter_̲group •  elb •  iam_̲group •  iam_̲policy •  iam_̲role •  iam_̲user •  lambda •  launch_̲configuration •  nat_̲gateway •  network_̲acl •  network_̲interface •  rds •  rds_̲db_̲parameter_̲gro up •  route53_̲hosted_̲zone •  route_̲table •  s3_̲bucket •  security_̲group •  ses_̲identity •  subnet •  vpc •  cloudfront_̲distribution 8 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  9. has  28  resource  types 9 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  10. awspec  generate  ~ > awspec generate   awspec generate cloudwatch_alarm

    # Generate cloudwatch_alarm 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 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 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) 10 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  11. can  generate  20  type  spec 11 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  12. Inside  of  awspec 12 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  13. 13 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  14. awspec  written  by  Ruby •  aws-‐‑‒sdk-‐‑‒rubyの開発が活発だった •  re:Invent中の発表とSDKの新機能リリースがほぼリアル タイム • 

    Serverspecの良良さを感じていた •  Serverspec本も相当勉強になる •  同じようなDSLでテストをしたかった •  Fukuoka.rbがあった •  事実、内部実装でかなり助けてもらった •  http://k1low.hatenablog.com/entry/2015/12/11/185728 •  (本⼈人は忘れているだろうけど)udzuraさんはawspecのコミッ ト権を持っている 14 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  15. tree  -‐‑‒d  awspec/ !"" bin !"" doc # $"" _resource_types

    !"" exe !"" lib # $"" awspec # !"" command # !"" ext # !"" generator # # !"" doc # # # $"" type # # $"" spec # !"" helper # # $"" finder # !"" matcher # !"" stub # $"" type $"" spec 15
  16. awspec  toolbox 16 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  17. bundle  exec  bin/toolbox  template  ec2 17 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  18. bundle  exec  bin/toolbox  template   •  awspecに新しいリソースタイプを追加するときに利利⽤用 するコマンド •  $

     bundle  exec  bin/toolbox  template  redshift •  リソースタイプ作成に最低限必要なファイルが⽣生成される •  ⽣生成されたファイルを他のリソースタイプの書き⽅方をマネて 修正すればだいたいOK 18 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  19. bundle  exec  bin/toolbox  docgen 19 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  20. bundle  exec  bin/toolbox  docgen •  awspecのソースコードからドキュメントを作成するコ マンド •  awspecはドキュメントジェネレータまで内包している っ!!

    •  Awspec::Generator::Doc::Type:* •  doc/_̲resource_̲types/*.md •  ドキュメントをプログラムで⽣生成することでaws-‐‑‒sdk-‐‑‒ rubyのリリーススピードについていく 20 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  21. つまり 21 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  22. I  want  your  contribution!! 22 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  23. aws-‐‑‒sdk-‐‑‒ruby 23 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  24. 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のほうがリソースをオブジェクトとして綺麗麗に操作 できる 24 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  25. awspecはClientベース •  できるだけ多くのAWSリソースを実装できたほうがよい •  awspecはリソースのREADが基本なのでそこまで難しいこ とはしていないのでいける •  でも、Resourceも使いたいよね •  でも、Resourceにはリソースの操作(READ以外)もあるの

    で安易易に組み込めない •  「awspec使ったら書き⽅方間違えてインスタンスが削除され た」は洒落落にならない 25 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  26. 26 Awspec::ResourceReader JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  27. Awspec::ResourceReader •  awspecは内部でResourceを呼び出すときは必ず Awspec::ResourceReaderを経由する •  Awspec::ResourceReaderでAWSリソースを操作しそ うなメソッドを潰している •  ブラックリスト⽅方式 • 

    これでほぼ安全にawspecが使える •  Resourceが使えるawspecのリソースタイプはドキュメント に”Advanced  Use”の節がある 27 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  28. 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 28 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  29. aws-‐‑‒cliとかのprofileの管理理 •  .aws/configと.aws/credentialsに分かれている •  なぜ?歴史的な理理由? •  環境変数も使える •  awspecもaws-‐‑‒cliと同じようにprofileやENVを利利⽤用したい • 

    AWSなコマンドを⾃自作する際もaws-‐‑‒cliと同じようにprofile やENVを利利⽤用したい 29 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  30. awsecrets 30 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  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が上がっていたはず 31 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう  #!/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
  32. 今後やりたいこと 32 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  33. AWSアカウント⾃自体のspec •  awspecは基本的に1つのインスタンス、1つのVPCなどAWS リソース1つ1つに対してテストが可能 •  最近はさらに上位のレベルでテストを書いておきたいことが 多発 •  「このリージョンで起動しているRDSインスタンスは5台」 • 

    「EC2のスケジュールドイベントは現在0件」 •  「このアカウントではIAMの数は4つ」 •  なぜ作らないのか? •  具体的な実装デザインが決まっていない •  リソースタイプ名が決まらない(aws?  account?  resources?) •  だれか決めて欲しい 33 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  34. なぜawspecなのか 34 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  35. awspecの存在意義 •  Codenize.toolsやTerraformなど、使いやすい構成管理理 ツールが出てきたため、AWSリソース⾃自体がコードで管 理理されるようになってきた •  わざわざ別にテストいらない •  「⼿手作業で構築したAWSリソースの管理理にはawspecが 良良い」

    •  あれ?どこかで聞いたことが。。。 •  が、それ以外では? 35 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  36. さらに今後やりたいこと 36 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  37.  $ 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 37 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  38. 22MB 38 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  39. わかりますよね? 39 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  40. 40 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  41. awspec  on  AWS  Lambda(未定) •  RubyがAWS  Lambdaで動けばawspecも動くはず •  CloudTrail  -‐‑‒>

     S3  -‐‑‒>  AWS  Lambda  -‐‑‒>  awspec •  Rubyistにとって使いやすいAWS  Config  ConfigRule •  CIとしてのawspecがAWSの上だけで 41 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう
  42. まとめ •  awspecを作っています 42 JAWS-‐‑‒UG福岡:3度度⽬目の濃い⽬目にAWSの話をしてみよう

  43. Thank  you!  Fusicはテクノロジーが  好きなエンジニアを募集しています  https://fusic.github.io 43