Download - Groovy DevOps in the Cloud
![Page 1: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/1.jpg)
Groovy DevOps in theCloud
01
![Page 2: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/2.jpg)
About us02
![Page 3: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/3.jpg)
Luciano Fiandesio
Bio: Developer, speaker, author, kitchen hacker
Company: Aestas/IT (http://aestasit.com)
E-mail: [email protected]
Linkedin: http://www.linkedin.com/in/lucianofiandesio
••••
03
![Page 4: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/4.jpg)
Andrey Adamovich
Bio: Developer, coach, speaker, author
Company: Aestas/IT (http://aestasit.com)
E-mail: [email protected]
Linkedin: http://www.linkedin.com/in/andreyadamovich
••••
04
![Page 5: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/5.jpg)
What's this presentation about?
Our take on:
DevOps
Software Provisioning
Continuous Integration
Continuous Delivery
••••
05
![Page 6: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/6.jpg)
Technologies
AWS - http://aws.amazon.com
Groovy - http://groovy.codehaus.org
Gradle - http://gradle.org
Jenkins - http://jenkins-ci.org
Puppet - http://puppetlabs.com
•••••
06
![Page 7: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/7.jpg)
Developers +Operations =
?07
![Page 8: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/8.jpg)
Silos
08
![Page 9: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/9.jpg)
Conflicts09
![Page 10: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/10.jpg)
Risk
10
![Page 11: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/11.jpg)
Agile
11
![Page 12: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/12.jpg)
What is DevOps?
12
![Page 13: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/13.jpg)
Infrastructure as Code
Automate the provisioning and maintenance of servers:
Build from source control
Utilize Open Source tools
Ensure testability
•••
13
![Page 14: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/14.jpg)
Configuration propagation
14
![Page 15: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/15.jpg)
Changes
No Manual Changes!
15
![Page 16: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/16.jpg)
Building a DevOps toolkit
Automation is key
We are JVM hackers
Fragmented ecosystem
Full-stack approach
••••
16
![Page 17: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/17.jpg)
Sshoogr
17
![Page 18: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/18.jpg)
Sshoogr Features
Remote command execution
File uploading/downloading
Tunneling
•••
18
![Page 19: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/19.jpg)
Sshoogr Example I
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.
19
![Page 20: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/20.jpg)
Sshoogr Example II
remoteSession {
scp {
from { localDir "$buildDir/application" }
into { remoteDir '/var/bea/domain/application' }
}
}
01.
02.
03.
04.
05.
06.
20
![Page 21: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/21.jpg)
Sshoogr Example III
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("Warning!!!")
}
}
}
01.
02.
03.
04.
05.
06.
07.
08.
09.21
![Page 22: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/22.jpg)
Why Groovy?
Groovy is perfect choice for scripting
Very mature, concise syntax
Extremely easy to produce DSL
We wrote a book about it!
••••
22
![Page 23: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/23.jpg)
Shameless plug
23
![Page 24: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/24.jpg)
Puppet24
![Page 26: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/26.jpg)
Why Puppet?
More mature than competition
Large community
Ruby-based DSL
No need to learn Ruby ;)
••••
26
![Page 27: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/27.jpg)
Puppet example
27
![Page 28: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/28.jpg)
Puppet provisioning
28
![Page 29: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/29.jpg)
Puppet provisioning
29
![Page 30: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/30.jpg)
Puppet provisioning
30
![Page 31: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/31.jpg)
Puppet provisioning
31
![Page 32: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/32.jpg)
Puppet state management
32
![Page 33: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/33.jpg)
Puppet state management
33
![Page 34: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/34.jpg)
Puppet state management
34
![Page 35: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/35.jpg)
Puppet modules
35
![Page 36: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/36.jpg)
Puppet modules
36
![Page 37: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/37.jpg)
Puppet modules
37
![Page 38: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/38.jpg)
Continuous Integration
38
![Page 39: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/39.jpg)
Why Jenkins?
De-facto standard
Stable
There is a plugin for that!
•••
39
![Page 40: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/40.jpg)
Services Partner
40
![Page 41: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/41.jpg)
Gradle Example I
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.
41
![Page 42: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/42.jpg)
Gradle Example I
...
exec 'rm -rf /etc/puppet/modules'
exec 'unzip /tmp/repo.zip -d /etc/puppet/modules'
}
}
01.
02.
03.
04.
05.
42
![Page 43: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/43.jpg)
Gradle Example II
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.43
![Page 44: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/44.jpg)
Jenkins example
44
![Page 45: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/45.jpg)
In the meanwhile...
We started developing complex Puppet modules
Modules needs proper testing
...on different platforms
•••
45
![Page 46: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/46.jpg)
Do you test, right?
How to test this stuff?
How to reuse a JUnit approach to testing?
We wanted things to be SIMPLE!
•••
46
![Page 47: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/47.jpg)
PuppetUnit
47
![Page 48: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/48.jpg)
PUnit
Simple testing tool for verifying remote server state
Uses sshoogr and JUnit
Reuse reporting features of JUnit and Jenkins
As simple as ...
••••
48
![Page 49: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/49.jpg)
PUnit Example I
class DerbyInstallTest
extends BasePuppetIntegrationTest {
@Before
void installDerby() {
apply("include derby")
}
...
}
01.
02.
03.
04.
05.
06.
07.
08.
49
![Page 50: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/50.jpg)
PUnit Example II
@Test
def void ensureDerbyRunning() {
command('service derby status > derbystatus.log')
assertTrue fileText("/root/derbystatus.log")
.contains('Derby')
assertTrue fileText("/root/derbystatus.log")
.contains('is running.')
}
01.
02.
03.
04.
05.
06.
07.
08.
50
![Page 51: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/51.jpg)
PUnit Example III
@Test
def void ensureCanConnect() {
Thread.sleep(10000)
uploadScript()
command('/opt/derby/db-derby-10.9.1.0-bin/bin/ij ' +
'testDataScript.sql > derbytest.log')
...
01.
02.
03.
04.
05.
06.
07.
51
![Page 52: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/52.jpg)
PUnit Example III
...
// Check if the log of the insert
// operation contains the word ERROR.
assertFalse(
"The script should returne at least one error",
fileText("/root/derbytest.log")
.contains('ERROR')
)
...
01.
02.
03.
04.
05.
06.
07.
08.
09.52
![Page 53: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/53.jpg)
PUnit Example III
...
// Check on data that was inserted into a table.
assertTrue(
"The log should contain a SELECT result",
fileText("/root/derbytest.log")
.contains('Grand Ave.')
)
}
01.
02.
03.
04.
05.
06.
07.
08.
53
![Page 54: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/54.jpg)
PUnit
54
![Page 55: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/55.jpg)
Nextproblem?
55
![Page 56: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/56.jpg)
Scalability
How do we test on different OS?
How do we run parallel tests on multiple architectures?
How do we avoid selling our houses?
•••
56
![Page 57: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/57.jpg)
Amazon WebServices
57
![Page 58: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/58.jpg)
Elastic Compute Cloud
Mature
Great API
Virtual hardware variety
OS variety
••••
58
![Page 59: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/59.jpg)
EC2 Console
59
![Page 60: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/60.jpg)
Gramazon
60
![Page 61: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/61.jpg)
Gramazon
Groovy based API for interacting with EC2
Integrates with the rest of the stack
••
61
![Page 62: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/62.jpg)
Gramazon Example I
task startInstance(type: StartInstance) {
keyName 'cloud-do'
securityGroup 'cloud-do'
instanceName 'gramazon/cloud-do'
stateFileName 'cloud-do.json'
ami 'ami-6f07e418'
instanceType 't1.micro'
waitForStart true
}
01.
02.
03.
04.
05.
06.
07.
08.
09.62
![Page 63: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/63.jpg)
Gramazon Example II
task terminateInstance(type: TerminateInstance) {
stateFileName 'cloud-do.json'
}
01.
02.
03.
63
![Page 64: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/64.jpg)
Costs considerations
Name Compute Units Memory Hourly Cost
t1.micro 2 0.60 GB $0.02
m1.small 1 1.70 GB $0.06
c1.medium 5 1.70 GB $0.14
m1.medium 2 3.75 GB $0.12
m1.large 4 7.50 GB $0.24
c1.xlarge 20 7.00 GB $0.58
m3.xlarge 13 15.00 GB $0.50
64
![Page 65: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/65.jpg)
Free tier
750 hours of Amazon EC2 Linux Micro Instance usage (613 MB of
memory and 32-bit and 64-bit platform support)
Enough hours to run continuously each month
•
•
65
![Page 66: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/66.jpg)
Security considerations
Host operating system
Individual SSH keyed logins
All accesses logged and audited
Customer-generated keypairs
Stateful firewall
Mandatory inbound firewall, default deny mode
Signed API Calls
Require X.509 certificate or secret AWS key
••••
••
••
66
![Page 67: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/67.jpg)
Imgr
67
![Page 68: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/68.jpg)
Imgr
A tool for building images
Inspired by Packer
••
68
![Page 69: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/69.jpg)
Images?
69
![Page 70: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/70.jpg)
Supports
Shell
Puppet
••
70
![Page 71: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/71.jpg)
Configuration Example
71
![Page 72: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/72.jpg)
The big picture
72
![Page 73: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/73.jpg)
Aetomation
73
![Page 74: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/74.jpg)
Conclusions
Reuse your existing Java knowledge
...to build a bridge between DEVs and OPs
Reuse development best practices for OPs
Don't be afraid to try new technologies
Automate!
•••••
74
![Page 75: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/75.jpg)
Readingmaterial
75
![Page 76: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/76.jpg)
Groovy 2 Cookbook
76
![Page 77: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/77.jpg)
The Phoenix Project
77
![Page 78: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/78.jpg)
Continuous Delivery
78
![Page 79: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/79.jpg)
Programming Amazon EC2
79
![Page 80: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/80.jpg)
Gradle in Action
80
![Page 81: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/81.jpg)
Technologies to follow
Vagrant - http://www.vagrantup.com/
Docker - https://www.docker.io/
Packer - http://www.packer.io/
Qemu - http://wiki.qemu.org/Main_Page
jclouds - http://jclouds.apache.org/
Cloudbees - http://www.cloudbees.com/
••••••
81
![Page 82: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/82.jpg)
One morething...
82
![Page 83: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/83.jpg)
It's all OpenSource!
83
![Page 84: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/84.jpg)
Source code
Sshoogr: https://github.com/aestasit/sshoogr
Sshoogr Gradle: https://github.com/aestasit/sshoogr-gradle
PUnit: https://github.com/aestasit/puppet-unit
Gramazon: https://github.com/aestasit/gramazon
Imgr: https://github.com/aestasit/imgr
•••••
84
![Page 85: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/85.jpg)
Seekingcontributors!
85
![Page 86: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/86.jpg)
Questions?86
![Page 87: Groovy DevOps in the Cloud](https://reader033.vdocuments.us/reader033/viewer/2022051323/548295b0b47959ce0c8b47e5/html5/thumbnails/87.jpg)
Paldies! Thank you!
87