SlideShare a Scribd company logo
1 of 66
Download to read offline
BATOU
multi-(component¦host¦environment¦.*)
deployment
Wednesday, 3.July 13
@theuni
Wednesday, 3.July 13
Wednesday, 3.July 13
Wednesday, 3.July 13
Wednesday, 3.July 13
AUTOMATING
DEPLOYMENTS IS
HARD
Wednesday, 3.July 13
HOW DOES
CONVERGENCE HELP?
Wednesday, 3.July 13
HOW DOES THIS
WORK WITH BATOU?
Wednesday, 3.July 13
SOME PERSPECTIVE
Wednesday, 3.July 13
Wednesday, 3.July 13
IT'S NOT THAT BAD.
Wednesday, 3.July 13
Wednesday, 3.July 13
service
deployment
Fabric,
Capistrano, ...
system
configuration
Puppet, Chef, ...
provisioning
kickstart, Razor,
imaging ...
Wednesday, 3.July 13
FTP
bash
mkzopeinstance
zc.buildout
fabric
Wednesday, 3.July 13
CONVERGENCE
Wednesday, 3.July 13
"Everything that follows is a
result of what you see here."
(Dr. Alfred Lanning; I, Robot)
Wednesday, 3.July 13
SIMPLE
os.mkdir('foo')
with open('foo/bar', 'w') as myfile:
myfile.write('asdf')
os.chmod('foo/bar', 0755)
Wednesday, 3.July 13
•unexpected system state
•can't resume
•unnecessary updates
os.mkdir('foo')
with open('foo/bar', 'w') as myfile:
myfile.write('asdf')
os.chmod('foo/bar', 0755)
SIMPLISTIC
Wednesday, 3.July 13
CORRECT(?)
if not os.path.isdir('foo'): os.unlink('foo')
if not os.path.exists('foo'): os.mkdir('foo')
try:
os.lstat('foo/bar')
except OSError: pass
else:
if os.path.isdir('foo/bar'):
shutil.rmtree('foo/bar')
else:
os.unlink('foo/bar')
if (os.path.exists('foo/bar') and
open('foo/bar', 'r').read() != 'asdf'):
open('foo/bar', 'w').write('asdf'):
current = os.stat('foo/bar').st_mode
if stat.S_IMODE(current) != 0755:
os.chmod('foo', 0755)
Wednesday, 3.July 13
SIMPLE
File('foo/bar',
content='asdf',
mode=0755,
leading=True)
Wednesday, 3.July 13
class File(Component):
namevar = 'path'
def configure(self):
self += Presence(
self.path, leading=self.leading)
self += Mode(self.path, self.mode)
self += Content(self.path, self.content)
File('foo/bar',
content='asdf',
mode=0755,
leading=True)
Wednesday, 3.July 13
class File(Component):
namevar = 'path'
def configure(self):
self += Presence(
self.path, leading=self.leading)
self += Mode(self.path, self.mode)
self += Content(self.path, self.content)
File('foo/bar',
content='asdf',
mode=0755,
leading=True)
compute target state
(no touching!)
Wednesday, 3.July 13
class File(Component):
namevar = 'path'
def configure(self):
self += Presence(
self.path, leading=self.leading)
self += Mode(self.path, self.mode)
self += Content(self.path, self.content)
File('foo/bar',
content='asdf',
mode=0755,
leading=True)
compute target state
(no touching!)
composition operator
Wednesday, 3.July 13
class File(Component):
namevar = 'path'
def configure(self):
self += Presence(
self.path, leading=self.leading)
self += Mode(self.path, self.mode)
self += Content(self.path, self.content)
File('foo/bar',
content='asdf',
mode=0755,
leading=True)
compute target state
(no touching!)
composition operator
order
matters
Wednesday, 3.July 13
class Presence(Component):
namevar = 'path'
leading = False
def configure(self):
if self.leading:
self += Directory(
os.path.dirname(self.path),
leading=self.leading)
def verify(self):
if not os.path.isfile(self.path):
raise batou.UpdateNeeded()
def update(self):
ensure_path_nonexistent(self.path)
with open(self.path, 'w'):
pass
Wednesday, 3.July 13
class Presence(Component):
namevar = 'path'
leading = False
def configure(self):
if self.leading:
self += Directory(
os.path.dirname(self.path),
leading=self.leading)
def verify(self):
if not os.path.isfile(self.path):
raise batou.UpdateNeeded()
def update(self):
ensure_path_nonexistent(self.path)
with open(self.path, 'w'):
pass
run "anywhere"
Wednesday, 3.July 13
class Presence(Component):
namevar = 'path'
leading = False
def configure(self):
if self.leading:
self += Directory(
os.path.dirname(self.path),
leading=self.leading)
def verify(self):
if not os.path.isfile(self.path):
raise batou.UpdateNeeded()
def update(self):
ensure_path_nonexistent(self.path)
with open(self.path, 'w'):
pass
run on target
run "anywhere"
Wednesday, 3.July 13
class Presence(Component):
namevar = 'path'
leading = False
def configure(self):
if self.leading:
self += Directory(
os.path.dirname(self.path),
leading=self.leading)
def verify(self):
if not os.path.isfile(self.path):
raise batou.UpdateNeeded()
def update(self):
ensure_path_nonexistent(self.path)
with open(self.path, 'w'):
pass
run on target
run "anywhere"
after all sub-
components
Wednesday, 3.July 13
class Presence(Component):
namevar = 'path'
leading = False
def configure(self):
if self.leading:
self += Directory(
os.path.dirname(self.path),
leading=self.leading)
def verify(self):
if not os.path.isfile(self.path):
raise batou.UpdateNeeded()
def update(self):
ensure_path_nonexistent(self.path)
with open(self.path, 'w'):
pass
run on target
only if needed
run "anywhere"
after all sub-
components
Wednesday, 3.July 13
class Presence(Component):
namevar = 'path'
leading = False
def configure(self):
if self.leading:
self += Directory(
os.path.dirname(self.path),
leading=self.leading)
def verify(self):
if not os.path.isfile(self.path):
raise batou.UpdateNeeded()
def update(self):
ensure_path_nonexistent(self.path)
with open(self.path, 'w'):
pass
run on target
only if needed
run "anywhere"
after all sub-
components
keep
delegating!
Wednesday, 3.July 13
class Directory(Component):
namevar = 'path'
leading = False
def verify(self):
if not os.path.isdir(self.path):
raise batou.UpdateNeeded()
def update(self):
ensure_path_nonexistent(self.path)
if self.leading:
os.makedirs(self.path)
else:
os.mkdir(self.path)
Wednesday, 3.July 13
class Directory(Component):
namevar = 'path'
leading = False
def verify(self):
if not os.path.isdir(self.path):
raise batou.UpdateNeeded()
def update(self):
ensure_path_nonexistent(self.path)
if self.leading:
os.makedirs(self.path)
else:
os.mkdir(self.path)
could be done with
recursive
composition
Wednesday, 3.July 13
class Directory(Component):
namevar = 'path'
leading = False
def verify(self):
if not os.path.isdir(self.path):
raise batou.UpdateNeeded()
def update(self):
ensure_path_nonexistent(self.path)
if self.leading:
os.makedirs(self.path)
else:
os.mkdir(self.path)
could be done with
recursive
composition
refactor with
sub-components if too
complex
Wednesday, 3.July 13
class Directory(Component):
namevar = 'path'
leading = False
def verify(self):
if not os.path.isdir(self.path):
raise batou.UpdateNeeded()
def update(self):
ensure_path_nonexistent(self.path)
if self.leading:
os.makedirs(self.path)
else:
os.mkdir(self.path)
all methods
optional: no
configure()
could be done with
recursive
composition
refactor with
sub-components if too
complex
Wednesday, 3.July 13
class Directory(Component):
namevar = 'path'
leading = False
def verify(self):
if not os.path.isdir(self.path):
raise batou.UpdateNeeded()
def update(self):
ensure_path_nonexistent(self.path)
if self.leading:
os.makedirs(self.path)
else:
os.mkdir(self.path)
all methods
optional: no
configure()
could be done with
recursive
composition
pattern: just wipe
out what's wrong
refactor with
sub-components if too
complex
Wednesday, 3.July 13
CONVERGENCE
resume where
needed
handle many
system states
transparently
avoid
unnecessary
updates
Wednesday, 3.July 13
COMPONENTS
composition of
simple components
no magic bullet, just a
lot easier to factor
your code
configure - verify - update
Wednesday, 3.July 13
Wednesday, 3.July 13
SINGLE-
COMMAND
Wednesday, 3.July 13
REPEATABLE
RELIABLE
Wednesday, 3.July 13
SIMPLE
Wednesday, 3.July 13
ENTROPY
Wednesday, 3.July 13
EXPRESSIVENESS
READABILITY
Wednesday, 3.July 13
REUSABLE
Wednesday, 3.July 13
PLATFORM
INDEPENDENCE
Wednesday, 3.July 13
DOMAIN
AGNOSTIC
Wednesday, 3.July 13
NO ADDITIONAL
RUNTIME
DEPENDENCIES
Wednesday, 3.July 13
CONTINUITY
Wednesday, 3.July 13
MINIMAL
DOWNTIMES
Wednesday, 3.July 13
Wednesday, 3.July 13
PRACTICAL USAGE
Wednesday, 3.July 13
REQUIREMENTS
Python 2.7
SSH
virtualenv
Mercurial
Wednesday, 3.July 13
ENVIRONMENTS
[environment]
service_user = myservice
host_domain = flyingcircus.io
branch = production
[hosts]
multikarl00 = nginx, haproxy
multikarl01 = postgres, redis, memcached, crontab
multikarl12 = supervisor, logrotate, doctotext, myapp
multikarl13 = supervisor, logrotate, doctotext, myapp
Wednesday, 3.July 13
LOCAL
$ bin/batou-local dev localhost
Updating Hello > File(hello) > Presence(hello)
Updating Hello > File(hello) > Content(hello)
$ bin/batou-local dev localhost
$
Wednesday, 3.July 13
REMOTE
$ bin/batou-remote prod
test02.gocept.net: connecting
test01.gocept.net: connecting
test01.gocept.net: bootstrapping
test02.gocept.net: bootstrapping
OK
OK
Deploying test01.gocept.net/hello
Updating Hello > File(hello) > Presence(hello)
Updating Hello > File(hello) > Content(hello)
OK
Deploying test02.gocept.net/hello
Updating Hello > File(hello) > Presence(hello)
Updating Hello > File(hello) > Content(hello)
OK
Wednesday, 3.July 13
OVERRIDES
class Hello(Component):
hostname = "foo"
[environment]
...
[component:hello]
hostname = bar
Wednesday, 3.July 13
SECRETS
class Hello(Component):
db_password = none
secrets/production.cfg
[hello]
db_password = reallysecretstuff
Wednesday, 3.July 13
SECRETS
class Hello(Component):
db_password = none
secrets/production.cfg
[hello]
db_password = reallysecretstuff
SciFi
but
close
Wednesday, 3.July 13
PROVIDE/REQUIRE
class MyApp(Component):
def configure(self):
self.provide('appserver',
self.host.fqdn)
class HAProxy(Component):
def configure(self):
self.backends = 
self.require('appserver')
Wednesday, 3.July 13
PLATFORMS
class HAProxy(Component):
...
@platform('flyingcircus.io', HAProxy)
class SystemWideHAProxy(Component):
def configure(self):
self += File('/etc/haproxy',
ensure='symlink',
link_to=self.parent.haproxy_cfg.path)
Wednesday, 3.July 13
VFS MAPPING
./
...
./work
./work/_/etc/haproxy.cfg
class HAProxy(Component):
def configure(self):
self += File('/etc/haproxy')
[environment]
...
[vfs]
sandbox = Developer
Wednesday, 3.July 13
FEATURES
class MyApp(Component):
features = ['instance', 'jobrunner']
def configure(self):
if 'instance' in self.features:
...
[hosts]
hosta = myapp:instance
hostb = myapp:jobrunner
hostc = myapp:instance, myapp:jobrunner
hostd = myapp
Wednesday, 3.July 13
Wednesday, 3.July 13
CONVERGENCE
COMPOSITION
DETAILS
Wednesday, 3.July 13
QUESTIONS?
Wednesday, 3.July 13
batou.readthedocs.org
pypi.python.org/pypi/batou
bitbucket.org/gocept/batou
Wednesday, 3.July 13

More Related Content

Similar to batou - multi(component|host|environment|.*) deployment

Symfony2 and MongoDB - MidwestPHP 2013
Symfony2 and MongoDB - MidwestPHP 2013   Symfony2 and MongoDB - MidwestPHP 2013
Symfony2 and MongoDB - MidwestPHP 2013 Pablo Godel
 
Workers of the web - BrazilJS 2013
Workers of the web - BrazilJS 2013Workers of the web - BrazilJS 2013
Workers of the web - BrazilJS 2013Thibault Imbert
 
Taming Pythons with ZooKeeper
Taming Pythons with ZooKeeperTaming Pythons with ZooKeeper
Taming Pythons with ZooKeeperJyrki Pulliainen
 
Clojure basics
Clojure basicsClojure basics
Clojure basicsKyle Oba
 
Web directions code 13 notes
Web directions code 13 notesWeb directions code 13 notes
Web directions code 13 notesjaredau
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkJeremy Kendall
 
Lost in o auth? learn velruse and get your life back
Lost in o auth? learn velruse and get your life backLost in o auth? learn velruse and get your life back
Lost in o auth? learn velruse and get your life backAndrew Mleczko
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...Oursky
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...Jane Chung
 
Wordpress Plugin Development Practices
Wordpress Plugin Development PracticesWordpress Plugin Development Practices
Wordpress Plugin Development Practicesserversideup
 
F*cking with fizz buzz
F*cking with fizz buzzF*cking with fizz buzz
F*cking with fizz buzzScott Windsor
 
Deploying Heterogeneous Artifacts to the Cloud with OSGi - Neil Bartlett
Deploying Heterogeneous Artifacts to the Cloud with OSGi - Neil BartlettDeploying Heterogeneous Artifacts to the Cloud with OSGi - Neil Bartlett
Deploying Heterogeneous Artifacts to the Cloud with OSGi - Neil Bartlettmfrancis
 
Pragmatic JavaScript
Pragmatic JavaScriptPragmatic JavaScript
Pragmatic JavaScriptJohn Hann
 
Seattle.rb 6.4
Seattle.rb 6.4Seattle.rb 6.4
Seattle.rb 6.4deanhudson
 
Continuous Delivery for the Web Platform
Continuous Delivery for the Web PlatformContinuous Delivery for the Web Platform
Continuous Delivery for the Web PlatformJarrod Overson
 

Similar to batou - multi(component|host|environment|.*) deployment (20)

Symfony2 and MongoDB - MidwestPHP 2013
Symfony2 and MongoDB - MidwestPHP 2013   Symfony2 and MongoDB - MidwestPHP 2013
Symfony2 and MongoDB - MidwestPHP 2013
 
Intro tobackbone
Intro tobackboneIntro tobackbone
Intro tobackbone
 
Workers of the web - BrazilJS 2013
Workers of the web - BrazilJS 2013Workers of the web - BrazilJS 2013
Workers of the web - BrazilJS 2013
 
Taming Pythons with ZooKeeper
Taming Pythons with ZooKeeperTaming Pythons with ZooKeeper
Taming Pythons with ZooKeeper
 
RequireJS
RequireJSRequireJS
RequireJS
 
Rails Intro & Tutorial
Rails Intro & TutorialRails Intro & Tutorial
Rails Intro & Tutorial
 
Clojure basics
Clojure basicsClojure basics
Clojure basics
 
Web directions code 13 notes
Web directions code 13 notesWeb directions code 13 notes
Web directions code 13 notes
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro framework
 
Storyplayer
StoryplayerStoryplayer
Storyplayer
 
Lost in o auth? learn velruse and get your life back
Lost in o auth? learn velruse and get your life backLost in o auth? learn velruse and get your life back
Lost in o auth? learn velruse and get your life back
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...
 
Wordpress Plugin Development Practices
Wordpress Plugin Development PracticesWordpress Plugin Development Practices
Wordpress Plugin Development Practices
 
F*cking with fizz buzz
F*cking with fizz buzzF*cking with fizz buzz
F*cking with fizz buzz
 
Deploying Heterogeneous Artifacts to the Cloud with OSGi - Neil Bartlett
Deploying Heterogeneous Artifacts to the Cloud with OSGi - Neil BartlettDeploying Heterogeneous Artifacts to the Cloud with OSGi - Neil Bartlett
Deploying Heterogeneous Artifacts to the Cloud with OSGi - Neil Bartlett
 
Pragmatic JavaScript
Pragmatic JavaScriptPragmatic JavaScript
Pragmatic JavaScript
 
Seattle.rb 6.4
Seattle.rb 6.4Seattle.rb 6.4
Seattle.rb 6.4
 
Engines
EnginesEngines
Engines
 
Continuous Delivery for the Web Platform
Continuous Delivery for the Web PlatformContinuous Delivery for the Web Platform
Continuous Delivery for the Web Platform
 

Recently uploaded

SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 

Recently uploaded (20)

SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 

batou - multi(component|host|environment|.*) deployment