Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Infrastructure automation with gradle and puppet at Greach 2015

3 085 vues

Publié le

Infrastructure-as-code is becoming a mandatory part of any successful project. During this presentation we will show how to use Gradle plugins and Puppet manifests to provision and maintain consistent infrastructure configuration. We will also touch tools like Jenkins, Vagrant, Packer, VirtualBox and AWS.

Publié dans : Technologie
  • Soyez le premier à commenter

Infrastructure automation with gradle and puppet at Greach 2015

  1. 1. 01
  2. 2. About me 02
  3. 3. Andrey Adamovich Bio: Developer, coach, speaker, author Company: Aestas/IT (http://aestasit.com) E­mail: andrey@aestasit.com Linkedin: http://www.linkedin.com/in/andreyadamovich Lanyrd: http://lanyrd.com/profile/andrey­adamovich GitHub: https://github.com/aadamovich SO: http://stackoverflow.com/users/162792/andrey­adamovich Twitter: @codingandrey, @aestasit • • • • • • • • 03
  4. 4. Workshop structure Introduction, background, path, reasoning Demo and try­out of (biased) integration of Gradle + Puppet • • 04
  5. 5. Setup Dropbox: http://bit.ly/1ICkEOA Github: http://bit.ly/1D6tzDf • • 05
  6. 6. Tools Gradle VirtualBox Vagrant • • • 06
  7. 7. Background 07
  8. 8. Background Big projects built by Ant, Maven, and eventually Gradle Teams composed mostly of Java developers Complex (sometimes, over­engineered) architectures Many environments (DEV, TEST, QA, SIT, UAT, PRE­PROD, PROD) to support • • • • 08
  9. 9. Problems I Infrastructure is influenced by (relatively) frequent architecture changes (components, versions, layers) We want our environments to be the same (or at least quite similar) to avoid any side effects during development, testing and production We don't want to spend hours/days/weeks on configuring each and every new server and keeping them in­sync • • • 09
  10. 10. Problems II Operations guys are not always available (e.g. busy supporting production systems or just not skilled enough) Development infrastructure (Jenkins, Sonar, Version Control, Load Testing etc.) also needs maintenance We want to reuse experience available in our team and avoid throwing in too many various trendy technologies that will fail our expectations • • • 10
  11. 11. Automation is the key! 11
  12. 12. Questions How do I connect (ssh) to my server to perform actions required for deployment? How do I store my configuration for various servers? How do I store secrets? How do I ensure that remote server has everything on it to run my application? How do I verify that my automation works (prefferably without breaking anything important)? • • • • 12
  13. 13. Changing architecture 13
  14. 14. Local development 14
  15. 15. Splitting layers 15
  16. 16. Scaling out 16
  17. 17. Fail­over 17
  18. 18. Performance tuning 18
  19. 19. Maintaining system 19
  20. 20. What if? 20
  21. 21. Or even? 21
  22. 22. Splitting layers 22
  23. 23. Scaling out 23
  24. 24. Maintaining system 24
  25. 25. Late alignment issues 25
  26. 26. Similarity levels DEV << QA <<< PROD DEV < QA < PROD DEV ~ QA ~ PROD DEV = QA = PROD 1. 2. 3. 4. 26
  27. 27. Infrastructure as code 27
  28. 28. Keep it in version control 28
  29. 29. Connectivity 29
  30. 30. How do I connect to my server?30
  31. 31. First Blood 31
  32. 32. Ant + Gradle ant.taskdef(   name: 'scp',    classname: 'o.a.t.a.t.o.ssh.Scp',    classpath: configurations.secureShell.asPath)  ant.taskdef(   name: 'sshexec',    classname: 'o.a.t.a.t.o.ssh.SSHExec',    classpath: configurations.secureShell.asPath)  01. 02. 03. 04. 05.06. 07. 08. 09. 32
  33. 33. Simple call ant.sshexec(   host: host,    username: user,    password: password,    command: command,    trust: 'true',    failonerror: failOnError) 01. 02. 03. 04. 05. 06. 07. 33
  34. 34. Next step: wrapper function def ssh(String command,          Properties props,          boolean failOnError = false,          String suCommandQuoteChar = "'",          String outputProperty = null) {   ...  } 01. 02. 03. 04. 05. 06. 07. 34
  35. 35. Next step: wrapper function def scp(String file,          String remoteDir,          Properties props) {   ... } 01. 02. 03. 04. 05. 35
  36. 36. Task example I task installFonts << {   forAllServers { props ‐>     ssh('yes | yum install *font*', props)   } } 01. 02. 03. 04. 05. 36
  37. 37. Task example II task uninstallNginx  << {   forAllServers { props ‐>     ssh('/etc/init.d/nginx stop', props)     ssh('yes | yum remove nginx', props, true)     ssh('rm ‐rf /etc/yum.repos.d/nginx.repo', props)     ssh('rm ‐rf /var/log/nginx', props)     ssh('rm ‐rf /etc/nginx /var/nginx', props)   } } 01. 02. 03. 04. 05. 06. 07. 08. 09. 37
  38. 38. Drawbacks New connection each time Excplicit repeating parameters Complex scripts are hard to maintain Tasks are not idempotent • • • • 38
  39. 39. Libraries jsch sshj overthere sshoogr • • • • 39
  40. 40. Sshoogr 40
  41. 41. Sshoogr features Groovy­based SSH DSL for: Remote command execution File uploading/downloading Tunneling • • • 41
  42. 42. Sshoogr usage (import) @Grab(   group='com.aestasit.infrastructure.sshoogr',   module='sshoogr',   version='0.9.16') import static com.aestasit.ssh.DefaultSsh.* 01. 02. 03. 04. 05. 42
  43. 43. Sshoogr usage (defaults) defaultUser    = 'root' defaultKeyFile = new File('secret.pem') execOptions {   verbose      = true   showCommand  = true } 01. 02. 03. 04. 05. 06. 43
  44. 44. Sshoogr usage (connection) remoteSession {   url = 'user2:654321@localhost:2222'   exec 'rm ‐rf /tmp/*'   exec 'touch /var/lock/my.pid'   remoteFile('/var/my.conf').text = "enabled=true" } 01. 02. 03. 04. 05. 06. 44
  45. 45. Sshoogr usage (multi­line content) remoteFile('/etc/yum.repos.d/puppet.repo').text = '''   [puppet]   name=Puppet Labs Packages   baseurl=http://yum.puppetlabs.com/el/   enabled=0   gpgcheck=0 ''' 01. 02. 03. 04. 05. 06. 07. 45
  46. 46. Sshoogr usage (file copying) remoteSession {   scp {     from { localDir "$buildDir/application" }     into { remoteDir '/var/bea/domain/application' }   } } 01. 02. 03. 04. 05. 06. 46
  47. 47. Sshoogr usage (command result) def result = exec(command: '/usr/bin/mycmd',   failOnError: false, showOutput: false) if (result.exitStatus == 1) {   result.output.eachLine { line ‐>     if (line.contains('WARNING')) {       throw new RuntimeException("Execution failed with: ${line}")     }   } } 01. 02. 03. 04. 05. 06. 07. 08. 09. 47
  48. 48. Sshoogr usage (shortcuts) if (ok('/usr/bin/mycmd')) {   ... } if (fail('/usr/bin/othercmd')) {   ... } 01. 02. 03. 04. 05. 06. 48
  49. 49. Sshoogr usage (tunnels) tunnel('1.2.3.4', 8080) { int localPort ‐>   def url = "http://localhost:${localPort}/flushCache"   def result = new URL(url).text   if (result == 'OK') {     println "Cache is flushed!"   } else {     throw new RuntimeException(result)   } } 01. 02. 03. 04. 05. 06. 07. 08. 09. 49
  50. 50. Sshoogr usage (prefix/suffix) prefix('sudo ') {   exec 'rm ‐rf /var/log/abc.log'   exec 'service abc restart' } suffix(' >> output.log') {   exec 'yum ‐y install nginx'   exec 'yum ‐y install mc'   exec 'yum ‐y install links' } 01. 02. 03. 04. 05. 06. 07. 08. 09. 50
  51. 51. How do I verify that my automation works?51
  52. 52. Virtualization is the key! 52
  53. 53. Multi­core machine is a must!53
  54. 54. VirtualBox 54
  55. 55. VirtualBox Powerful virtualization product for enterprise as well as home use It has nice GUI and command line tools with tons of parameters It is open­source and free for personal use • • • 55
  56. 56. A bit of history Created by innotek GmbH Open­sourced in 2007 innotek was acquired by Sun in 2008 Sun was acquired by Oracle in 2010 • • • • 56
  57. 57. VirtualBox commands 57
  58. 58. Vagrant 58
  59. 59. Vagrant features Simplified VirtualBox management (networking, security, shared drives, etc.) Easy to read and share configuration Package virtual machines as reusable boxes • • • 59
  60. 60. As simple as...    vagrant init ubuntu/trusty64    vagrant up    vagrant ssh 01. 02. 03. 60
  61. 61. Image library 61
  62. 62. Vagrant cloud 62
  63. 63. What if there is no suitable box there?63
  64. 64. Create your own! 64
  65. 65. Packer 65
  66. 66. How to make an image Download ISO file with your (favorite) OS Download VirtualBox guest additions ISO to match VirtualBox version Free up local disk space (2x used virtual disk size + ISO size) Set­up environment variables Create Packer's JSON configuration Start Packer build Go somewhere for 30­40 minutes 1. 2. 3. 4. 5. 6. 7. 66
  67. 67. Packer command     packer build ‐force solaris11.json 01. 67
  68. 68. How to use the image vagrant box add my/solaris11 solaris11.box ‐‐force vagrant init my/solaris11 vagrant up 1. 2. 3. 68
  69. 69. Disk re­sizing I First resize the file inside VirtualBox Then resize partition in the guest OS Choose maximum size carefully • • • 69
  70. 70. Disk re­sizing II     VBoxManage modifyhd <absolute path to file>                          ‐‐resize <size in MB> 01. 02. 70
  71. 71. From scripts to declarations71
  72. 72. Puppet 72
  73. 73. Puppet example 73
  74. 74. Puppet provisioning 74
  75. 75. Puppet provisioning 75
  76. 76. Puppet provisioning 76
  77. 77. Puppet provisioning 77
  78. 78. Puppet state management 78
  79. 79. Puppet state management 79
  80. 80. Puppet state management 80
  81. 81. Puppet modules 81
  82. 82. Puppet modules 82
  83. 83. Puppet modules 83
  84. 84. Deployment vs. Infrastructure management84
  85. 85. Push vs. Pull 85
  86. 86. Pull 86
  87. 87. Push 87
  88. 88. Push imple­ mentation 88
  89. 89. Sshoogr + Gradle + Puppet89
  90. 90. Upload modules task uploadModules << {   remoteSession {     exec 'rm ‐rf /tmp/repo.zip'     scp {       from { localFile "${buildDir}/repo.zip" }       into { remoteDir "/root" }     }     ... 01. 02. 03. 04. 05. 06. 07. 08. 90
  91. 91. Upload modules     ...     exec 'rm ‐rf /etc/puppet/modules'     exec 'unzip /tmp/repo.zip ‐d /etc/puppet/modules'   } } 01. 02. 03. 04. 05. 91
  92. 92. Apply manifests task puppetApply(dependsOn: uploadModules) << {   remoteSession {     scp {       from { localFile "${buildDir}/setup.pp" }       into { remoteDir "/tmp" }     }     exec 'puppet apply /tmp/setup.pp'   } } 01. 02. 03. 04. 05. 06. 07. 08. 09. 92
  93. 93. What we solved? Separated infrastructure state description and operations tasks Scripts became more maintainable and idempotent • • 93
  94. 94. Declaration reuse 94
  95. 95. How do I store my configuration?95
  96. 96. Maven profiles 96
  97. 97. *.properties files 97
  98. 98. ConfigSlurper 98
  99. 99. Topology What to do if environment has more than 1 server? 99
  100. 100. Server roles 100
  101. 101. Hiera 101
  102. 102. External dependencies 102
  103. 103. Puppet module tool... 103
  104. 104. is not that good! 104
  105. 105. Puppet module repositories Puppet forge Pulp GitHub Maven as a repository • • • • 105
  106. 106. Dependencies managers Puppet module tool Puppet librarian r10k Puppet Module Installer • • • • 106
  107. 107. Demo / Playground 107
  108. 108. Summary 108
  109. 109. Configuration code coverage 109
  110. 110. Images, manifests, tasks 110
  111. 111. Questions? 111
  112. 112. Thank you! 112
  113. 113. Happy infrastructure management!113

×