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

Agile and DevOps with Ruby

Naoto Takai
November 04, 2016

Agile and DevOps with Ruby

『Rubyによるアジャイルとデブオプスを実現するチームづくり——みんなのウェディングの経験から』

RubyWorld Conference 2016発表資料

Naoto Takai

November 04, 2016
Tweet

More Decks by Naoto Takai

Other Decks in Technology

Transcript

  1. 3VCZח״׷،آٍ؎ٕהرـؔفأ׾
    㹋植ׅ׷ث٦يבֻ׶
    Ղ׫׿זךؐؑر؍ؚٝך穗꿀ַ׵

    View Slide

  2. ׫׿זךؐؑر؍ؚٝ
    ˖ 穠㭴䒭㜥稱➜〡؝ى؟٦ؽأ
    ˖ 剢꟦ِص٦ؙـٓؐؠ侧խ秈♰
    ˖ 穠㭴䒭㜥鼅ןדך➂ָ⿫罋ח

    ـٓ؎تٕ欵噟倜耀锃ץ

    View Slide

  3. 㡰♳넝䱿獳





    䎃 䎃 䎃 䎃 䎃
    ʢ୯Ґɿඦສԁʣ
    䎃剢 %F/"ך倜鋉✲噟ה׃גꟚ㨣
    䎃剢 ⠓爡鏣甧
    䎃剢 匌❨鏾ⵙ《䒷䨽وؠ٦ؤ♳㜥
    䎃剢 ؙحؙػحسה项劤噟⹡䲿䵿
    屟ꬠ
    吳䒭⠓爡׫׿זךؐؑر؍ؚٝ
    䨽㖈㖑 匌❨鿪⚥㣛⼒眠㖑

    ꋒ䏟匟畾أؙؒ،ꥡ
    项劤ꆃ 涰♰ⰼ䎃剢劣植㖈

    View Slide

  4. չؙحؙػحسպַ׵չ׫׿זךؐؑر؍ؚٝպפ

    View Slide

  5. 1FSM͸3VCZͷܑ͓͞Μ PS͓࢞͞Μ

    ŠŠ·ͭ΋ͱΏ͖ͻΖ

    View Slide

  6. .PCB4J'הכ
    ˖ %F/"ח״׏גꟚ涪ׁ׸׋չؖٓ؛٦պぢֽؿٖ٦يٙ٦ؙ
    ˖ 'BTU$(*ד⹛⡲׃ծ"QBDIF)5514FSWFS׾⵸䲿ה׃גְ׷
    ˖ ؔ٦فٝا٦أ晛כծ䎃剢ח剑䖓ךٔٔ٦أ

    View Slide

  7. sub pageDiaryView {
    my $func = shift;
    my $rhData = Common::cloneHash($_::F, '^[a-z]');
    my $dbh = DA::getHandle($_::DB_DIARY_R);
    my $sth = $dbh->prepare(<<'SQL');
    select
    diary_id, user_id, post_date, subject, content,
    comment_num, access_num, last_user
    from diary_data where diary_id=?
    SQL
    $sth->execute($rhData->{d});
    if (!$sth->rows) {
    MException::throw({ CHG_FUNC => '.404' });
    }
    Common::mergeHash($rhData, $sth->fetchrow_hashref());
    my $html = HTMLTemplate::insert("diary/dia_view", $rhData);
    Response::output(\$html);
    }

    View Slide

  8. def show
    @diary = Diary.find(prams[:id])
    end

    View Slide

  9. ׫׿זךؐؑر؍ؚٝꟚ涪⡤ⵖ䔲儗
    ˖ ؒٝآص،˘せ
    ˖ 㹀纏ׁ׸׋Ꟛ涪فٗإأװفٗآؙؑز盖椚䩛岀ָזְ
    ˖ ؒٝآص،כؽآطأ⩎ַ׵ך銲実דչ،؟؎ٝպׁ׸׷
    ˖ 荈⹛ذأزָזְ
    ˖ 㢌刿ח״׏גءأذيָ㠨׸ג׮ⴓַ׵זְ

    View Slide

  10. ׫׿זךؐؑر؍ؚٝꟚ涪橆㞮䔲儗
    ˖ Ⱏ欽ךꟚ涪欽؟٦غ٦ָ〴
    ˖ ا٦أ؝٦سر؍ؙٖزٔ׾TBNCBדⰟ剣
    ˖ 4VCWFSTJPOדغ٦آّٝ盖椚
    ˖ ➭ךꟚ涪罏ך㢌刿ָ幉ׂ׵זְ״ֲחծ㡮׾ַֽ֮׏ג

    ؿ؋؎ٕ׾؝ىحز
    ˖ ؝ىحزِ٦ؠ٦כⰋ㆞ずِׄ٦ؠ٦זךדծ؝ىحز

    ًحإ٦آחせ⵸׾ろ׭׷

    View Slide

  11. ׫׿זךؐؑر؍ؚٝ؎ٝؿٓ橆㞮䔲儗
    ˖ ⟎䟝㼔欽؟٦غ٦
    ˖ ؒٝآص،ך䩛⡲噟ח״׷鏣㹀盖椚
    ˖ ؟٦غ٦ך顤欽ָ넝ֻծ厫鮾ח锃麦דֹזְ
    ˖ מהאך؟٦غ٦ח醱侧ך䕵ⶴָず㽿
    ˖ ⽃♧ꥺ㹱挿410'ָ㶷㖈׃ծغحؙ،حفָ♶僇然
    ˖ 湊鋔⡤ⵖָ♶⼧ⴓדꥺ㹱׾嗚濼דֹזְ
    ˖ ؙٓ؎،ٝزַ׵ך鸬窃דءأذيꥺ㹱ָⴻ僇

    View Slide

  12. 䎃剢 3VCZⰕꟚ
    䎃剢 3VCZPO3BJMTⰕꟚ
    䎃剢 3VCZPO3BJMTⰕꟚ
    䎃剢 傈劤3VCZؕٝؿ؋ٖٝأ㛇锃闌怴%))
    䎃剢 傈劤3VCZ⠓陽㛇锃闌怴%BWF5IPNBT
    䎃剢 3VCZPO3BJMTⰕꟚ
    3VCZⰕꟚ
    䎃剢 (JU)VC؟٦ؽأꟚ㨣
    3VCZ٥3VCZPO3BJMTך娖〷

    View Slide

  13. ˖ ؽآطأ䧭ꞿך׋׭ך㖇⸂ָ䓼ֻծ䪮遭涸ז䫎项ָ

    זֶׂ׶חז׏גְ׋
    ˖ 竰竲涸ז何㊣׾׃גְֻ׋׭ךꟚ涪⡤ⵖָזַ׏׋

    View Slide

  14. ؒٝآص،ؚٔٝך顑⟣罏ה׃ג
    וך״ֲז䨌殛׾ה׷ַ

    View Slide

  15. ˖ ؝ٌر؍ذ؍׾ⵃ欽ׅ׷
    ˖ فٗإأך،آٔذ؍׾ぢ♳ׇׁ׷

    View Slide

  16. ίϞσΟςΟͱ͸
    ʲӳʳDPNNPEJUZ
    ίϞσΟςΟͱ͸ҰൠԽͨͨ͠ΊࠩผԽ͕ࠔ೉
    ͱͳͬͨ੡඼΍αʔϏεͷ͜ͱΛ͍͏ɻ
    ŠŠτϥΠϕοΫɾϒϥϯυઓུݚڀॴ

    View Slide

  17. ؝ٌر؍ذ؍ךًٔحز
    ˖ 㹋䨌ד嗚鏾ׁ׸גְ׷CBUUMFQSPWFO
    ˖ ِ٦ؠ٦؝ىُصذ؍ָ֮׶ظؐعָؐ崧鸐׃גְ׷
    ˖ 鞢ַזؒ؝ءأذيָ㶷㖈ׅ׷

    View Slide

  18. Ԩ 3VCZPO3BJMT
    Ԩ "NB[PO8FC4FSWJDFT "84

    View Slide

  19. فٗإأך،آٔذ؍

    View Slide

  20. View Slide

  21. A. Where do we want to be?
    B. Where are we?
    C. How do we improve our position?

    View Slide

  22. չאֻ׷׮ךպ׌ֽדכזֻ
    չאֻ׶ַ׋պ׮ؕ؎ئׅٝ׷

    View Slide

  23. Ԩ ،آٍ؎ٕꟚ涪
    Ԩ رـؔفأ

    View Slide

  24. DevOps is the practice of operations and
    development engineers participating
    together in the entire service lifecycle,
    from design through the development
    process to production support.
    IUUQTUIFBHJMFBENJODPNXIBUJTEFWPQT

    View Slide

  25. ˖ غ٦آّٝ盖椚
    ˖ 铬겗盖椚
    ˖ 圓䧭盖椚
    ˖ 竰竲涸؎ٝذؚٖ٦ءّٝ
    ˖ 湊鋔
    ˖ ذأز荈⹛⻉
    ˖ رفٗ؎

    View Slide

  26. Lowering risk of change

    through tools and culture
    — John Allspaw

    View Slide

  27. culture

    View Slide

  28. ΠσΦϩΪʔ͸ɺ෺࣭తͳΠσΦϩΪʔ૷ஔ
    ͷͳ͔ʹଘࡏ͠ɺ͜ͷ૷ஔ͸෺࣭తͳّࣜʹ
    Αͬͯௐ੔͞ΕΔ෺࣭తͳॾ࣮ફΛ໋ྩ͠ɺ
    ͜ΕΒͷॾ࣮ફ͸ࣗݾͷ৴ڼʹैͬͯશ͘ҙ
    ࣝతʹߦಈ͢Δओମͷ෺࣭తͳॾߦҝͷͳ͔
    ʹଘࡏ͢Δ
    ŠŠϧΠɾΞϧνϡηʔϧ

    View Slide

  29. ؒٝآص،ؚٔٝך顑⟣罏ה׃ג
    וך״ֲז䨌殛׾ה׷ַ
    ˖ "84הرـؔفأ
    ˖ 3VCZPO3BJMTה،آٍ؎ٕꟚ涪

    View Slide

  30. ➙תדך؎ٝؿٓ ֿ׸ַ׵ך؎ٝؿٓ

    View Slide

  31. ➙תדך؎ٝؿٓ ֿ׸ַ׵ך؎ٝؿٓ

    View Slide

  32. View Slide

  33. 3VCZח״׷؎ٝؿٓ盖椚
    ˖ ؟٦غ٦圓䧭盖椚خ٦ٕJUBNBFח״׷鏣㹀盖椚
    ˖ ؟٦ؽأ圓䧭盖椚خ٦ٕח״׷"84鏣㹀盖椚

    CVLFMBUUBFJQNBQLFMCJNQJDVMFUSPBEXPSLFS
    ˖ ر٦ةك٦أأؗ٦و盖椚SJEHFQPMF
    (JU)VCדךغ٦آّٝ盖椚ה؝٦سٖؽُ٦

    View Slide

  34. execute "hostname #{node[:ec2][:tags][:Name]}" do
    not_if "[ $(hostname) = \"#{node[:ec2][:tags][:Name]}\" ]"
    notifies :restart, 'service[rsyslog]'
    end
    file '/etc/sysconfig/network' do
    action :edit
    block do |content|
    unless content[node[:ec2][:tags][:Name]]
    content.sub!(/^HOSTNAME=.*$/,
    "HOSTNAME=#{node[:ec2][:tags][:Name]}")
    end
    end
    end

    View Slide

  35. $ bundle exec rake itamae:apply HOSTS=tools-001
    INFO: Apply /Users/alice/infra/itamae/roles/base/default.rb,/User
    itamae ssh -h 10.1.2.197 -j /var/folders/l7/16_nsg7s35b6f4_brh_pv
    infra/itamae/functions.rb /Users/alice/infra/itamae/roles/base/de
    infra/itamae/post-processing.rb
    INFO : Starting Itamae...
    INFO : Loading node data from /var/folders/l7/16_nsg7s35b6f4_brh
    /Users/alice/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/net-s
    Object#timeout is deprecated, use Timeout.timeout instead.
    /Users/alice/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/net-s
    Object#timeout is deprecated, use Timeout.timeout instead.
    INFO : Recipe: /Users/alice/infra/itamae/functions.rb
    INFO : Recipe: /Users/alice/infra/itamae/roles/base/default.rb
    INFO : Recipe: /Users/alice/infra/itamae/roles/base/disable-ip
    INFO : Recipe: /Users/alice/infra/itamae/roles/base/nofile.rb
    INFO : Recipe: /Users/alice/infra/itamae/roles/base/yum.rb

    View Slide

  36. View Slide

  37. View Slide

  38. View Slide

  39. 3VCZח״׷ؚٗך〳鋔⻉
    3FETIJGU
    MPH
    BQQ

    View Slide

  40. View Slide

  41. 湊鋔ך荈⹛⻉
    4MBDL
    5XJMJP
    $MPVE8BUDI -BNCEB

    View Slide

  42. ˖ 3BTQCFSSZ1J
    ˖ 64#أؾ٦ؕ٦

    ..416#,
    갈㡮ד؎ٝؿٓ؎كٝز׾
    鸐濼ׅ׷➬穈׫
    $7㩲ꅿאלׁ

    View Slide

  43. module Mina
    module Handlers
    class Announce < Ruboty::Handlers::Base
    BASE_DIR = File.join(__dir__, '../../../audio')
    on(/\A\[(High|Disaster)\]/i, name: 'alert', all: true)
    def alert(message)
    Thread.start { invoke_command("mpg123 -q #{BASE_DIR}/#{fi
    end
    end
    end
    end

    View Slide

  44. ➙תדךꟚ涪 ֿ׸ַ׵ךꟚ涪

    View Slide

  45. ➙תדךꟚ涪 ֿ׸ַ׵ךꟚ涪

    View Slide

  46. 3VCZPO3BJMTפך獳遤䨌殛
    ˖ .PCB4J'ה3VCZPO3BJMTדر٦ةك٦أ׾Ⱏ剣ׅ׷
    ˖ ٔغ٦أفٗؗء׾鏣縧׃ծ63-⽃⡘דⴖ׶剏ִגְֻ
    3FWFSTF1SPYZ
    SFQMBDFEQBUI
    PMEQBUI %BUBCBTF

    View Slide

  47. ؽٕسفٗإأך荈⹛⻉
    $PEF%FQMPZ
    TUBHJOH
    4MBDL
    $PEF%FQMPZ
    QSPEVDUJPO
    .JOB FTBJP
    鸐濼 鎸ꐮ

    View Slide

  48. View Slide

  49. View Slide

  50. View Slide

  51. View Slide

  52. ،آٍ؎ٕꟚ涪ךֶ秈勲
    ˖ 㡮׌׃גְֲֿ
    ˖ 秈勲׾ת׮׹ֲ

    View Slide

  53. 剢鎘歗 加ס׶ִַ׶ ꆃأفٔٝزٖؽُ٦
    嫣傈劉⠓
    Ꟛ涪

    View Slide

  54. (JU)VCفؙٕٔؒأز侧䱿獳








    ݄ ݄ ݄ ݄ ݄ ݄ ݄ ݄ ݄ ݄ ݄ ݄ ݄ ݄ ݄ ݄
    1FSM
    3VCZ

    View Slide

  55. ؒٝآص،ؚٔٝך顑⟣罏ה׃ג
    וך״ֲז䨌殛׾ה׷ַ
    ˖ "84הرـؔفأ
    ˖ 3VCZPO3BJMTה،آٍ؎ٕꟚ涪
    3VCZث٦ي

    View Slide

  56. View Slide