SlideShare a Scribd company logo
The life and times of


PuppetDB
                    Clojure/West 2013
deepak
giridharagopal
deepak@puppetlabs.com
@grim_radical [github twitter freenode]
Let’s talk about...
PuppetDB: Sneaking Clojure into Operations
Immutability
  is great!
Immutability allows
for invariants, which
help you reason about
correctness
Immutability prevents
spooky action at a
distance
Immutability fosters
modular, composable
abstractions
(not a tough sell
  to Clojurists*)

               *clojurians?
That’s great for
develoment, but how
 about operations?
Immutability for
infrastructure?
Because operations is in the
same boat as development
Everyone who’s got
their app running on
a fleet of servers has
experienced spooky
action at a distance
Known, good state is
critical for reliable
upgrades
A lack of predictability
in your systems
ruins automation and
abstraction
The problem is that:

         Systems are inherently
                       mutable!

But ideally:

      Systems should behave as
           though they weren’t!
façade of immutability. Immutability
Computer systems are in many ways
open systems, providing the keys to
the vault if one is so inclined to grab
them. But in order to foster an air of
immutability in our own systems,
it's of utmost importance to create a
façade of immutability. Immutability




                                          -- The Joy of Clojure
requires that we layer over and
abstract the parts of our system that
provide unrestrained mutability.
PuppetDB: Sneaking Clojure into Operations
Describe how you’d
like your systems to
look, and Puppet
does all the hard
work for you!
file { “/etc/issue”:
  content => “Got an issue? Here’s a tissue!”,
}

file { “/etc/motd”:
  content => template(“Welcome to $hostname!”),
}
file { "/etc/sudoers":
  owner => root,
  group => root,
  mode   => 440,
  source => "puppet:///modules/sudo/sudoers"
}
package { 'ntp':
  ensure => installed,
}

service { 'ntpd':
  ensure    => running,
  enable    => true,
  subscribe => File['/etc/ntp.conf'],
}

file { '/etc/ntp.conf':
  ensure => file,
  require => Package['ntp'],
  source => "puppet:///modules/ntp/ntp.conf",
}
class ntp {

    package { 'ntp':
      ensure => installed,
    }

    service { 'ntpd':
      ensure    => running,
      enable    => true,
      subscribe => File['/etc/ntp.conf'],
    }

    file { '/etc/ntp.conf':
      ensure => file,
      require => Package['ntp'],
      source => "puppet:///modules/ntp/ntp.conf",
    }

}
node “webserver.mydomain.com” {
  include ntp
}

node “appserver.mydomain.com” {
  include ntp
}

node “database.mydomain.com” {
  include ntp
}
class ssh {

    @@sshkey { $hostname:
      type => dsa,
      key => $sshdsakey
    }

    Sshkey <<| |>>

}
File “/tmp/foo/bar”
   User “deepak”
   Dir “/tmp/foo”
    Dir “/tmp”
Dir “/tmp”    User “deepak”

      Dir “/tmp/foo”


   File “/tmp/foo/bar”
Dir “/tmp”    User “deepak”

      Dir “/tmp/foo”


   File “/tmp/foo/bar”
PuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into Operations
Idempotent, and
only does what’s
necessary
Compensates for the
inherent mutability
of systems
Combats spooky
action at a distance
with automatic
repair
Brings predictability
to your systems
A foundation of
predictability and
reliability lets you
perform higher-level
operations on your
infrastructure
V    UME
    OL
every resource
   every parameter
  every relationship
          every fact
     for every node
updated all the time
Users leverage this
data to do higher-
order things with
their infrastructure
key distribution
      monitoring
  clustered services
master/slave replication
    load balancers
  shared filesystems
     firewall rules
           ...
Infrastructure as
code
Infrastructure as
data
User demand:

 Store as much data as we can!
     Much better queryability!

Oh yeah, but:

  Don’t slow down the system!
  Don’t compromise reliability!
We can rebuild it, we
have the technology!
Speed is important
       Parsing, validating, and
  manipulating incoming data is
    computationally expensive
Speed is important
The slower central storage is, the
less agile sysadmins can be. That
      can cost money and uptime!
Reliability is
important
 If it’s a critical part of managing
infrastructure, it’s got to be solid!
Deployment is
important
      Should be easy to package,
  install, configure, use, monitor,
                     and upgrade.
Wait, isn’t Puppet
written in Ruby?
Lessons learned from
writing the rest of
our software in Ruby
It’s...not speedy. Object creation,
method calls, garbage collection,
       etc. “Magical” APIs amplify
                      the problem.
Lessons learned from
writing the rest of
our software in Ruby
       Can only use one core!
    Workarounds compromise
    performance or simplicity
Lessons learned from
writing the rest of
our software in Ruby
       Mutable state all over
           the damn place!
Lessons learned from
writing the rest of
our software in Ruby
      Many struggles with the
                  runtime. :(
-- Jeff Gagliardi
PuppetDB: Sneaking Clojure into Operations
1. It’s fast
2. JVM libraries &
   Tools
3. State &
   Parallelism
PuppetDB
PuppetDB
     Definitely Better!
Fast, safe storage
of catalogs, facts,
and events
           like, *way* faster!
HTTP APIs
for resource, fact,
node, report retrieval
          plenty of data, just
              a “curl” away!
Storage &
Querying
Storage &
Querying
CQRS
Command
Query
Responsibility
Separation
  use a different model to update
 information than the model you
          use to read information
Writes
CQRS
write pipeline
 async, parallel, MQ-based, with
                  automatic retry
{
    :command "replace catalog"
    :version 2
    :payload {...}
}
Delayed




UUID




   /commands   MQ     Parse       Process




                    Dead Letter
                      Office
(defmulti process-command!
  (fn [{:keys [command version] :or {version 1}} _]
    [command version]))

(defmethod process-command! ["replace catalog" 1]
  [command options]
  (replace-catalog* command options))
(defmulti process-command!
  (fn [{:keys [command version] :or {version 1}} _]
    [command version]))

(defmethod process-command! ["replace catalog" 2]
  [command options]
  (replace-catalog* command options))

(defmethod process-command! ["replace catalog" 1]
  [command options]
   (-> command
       (update-in [:payload] catalog-v1->v2)
       (replace-catalog* options))
Command
processors must be
retry-aware
      expect failure, because
            it *will* happen.
(demo)
Reads
Queries
are expressed in their
own “language”
    domain specific, AST-based
              query language
["and",
  ["=", "type", "User"],
  ["=", "title", "nick"]]
["and",
  ["=", ["fact", "operatingsystem"], "Debian"],
  ["<", ["fact", "uptime_seconds"], 10000]]
["and",
  ["=", "name", "ipaddress"],
  ["in", "certname",
    ["extract", "certname", ["select-resources",
                              ["and",
                                ["=", "type", "Class"],
                                ["=", "title", "Apache"]]]]
["or",
  ["=", "certname", "foo.com"],
  ["=", "certname", "bar.com"],
  ["=", "certname", "baz.com"]]
We use core.match
to walk the tree,
compiling it to SQL
AST-based API lets
users write their own
languages
       ah, you’ve got to love
                open source!
(Package[httpd] and country=fr)
or country=us


Package["mysql-server"]
and architecture=amd64




                         Erik Dalén, Spotify
             https://github.com/dalen/puppet-puppetdbquery
AST-based API lets
us more safely
manipulate queries
(def query-app
  (app
    [&]
    {:get (fn [{:keys [params] :as request}]
             (perform-query (params "query")))}))

(def resources-app
  (app
   []
   query-app

   [type title &]
   (comp query-app
         (partial http-q/restrict-resource-query-to-type type)
         (partial http-q/restrict-resource-query-to-title title))

   [type &]
   (comp query-app
         (partial http-q/restrict-resource-query-to-type type))))
(defn restrict-resource-query-to-type
  [type query]
  (conj ["and"
          ["=" "type" type]]
        query))
Storage
Relational Database,
embedded or
PostgreSQL
 because they’re actually pretty
    fantastic at ad-hoc queries,
  aggregation, windowing, etc.
      while maintaining safety
PuppetDB: Sneaking Clojure into Operations
Relational Database,
embedded or
PostgreSQL
we use arrays, recursive queries,
       indexing inside complex
                       structures
Relational Database,
embedded or
PostgreSQL
 schema is oriented towards the
  types of queries we encounter
Deployment
PuppetDB Server          DLO



     DB           Workers



    HTTP            MQ
PuppetDB Server
   Workers    DLO
                         DB


    HTTP            MQ
PuppetDB Server
           Workers    DLO
HTTP                             DB
Proxy
(SSL)
            HTTP            MQ
Codez
(defn process-commands!
  "Connect to an MQ an continually, sequentially process commands.

  If the MQ consumption timeout is reached without any new data, the
  function will terminate."
  [connection endpoint discarded-dir options-map]
  (let [producer   (mq-conn/producer connection)
        publish    (partial mq-producer/publish producer endpoint)
        on-message (produce-message-handler publish discarded-dir options-map)
        mq-error   (promise)
        consumer   (mq-conn/consumer connection
                                     {:endpoint   endpoint
                                      :on-message on-message
                                      :transacted true
                                      :on-failure #(deliver mq-error (:exception %))})]
    (mq-cons/start consumer)

    ;; Block until an exception is thrown by the consumer thread
    (try
      (deref mq-error)
      (throw @mq-error)
      (finally
        (mq-cons/close consumer)))))
(defmacro with-error-delivery
  "Executes body, and delivers an exception to the provided promise if one is
  thrown."
  [error & body]
  `(try
     ~@body
     (catch Exception e#
       (deliver ~error e#))))
(defn filter-mbean
  "Converts an mbean to a map. For attributes that can't be converted to JSON,
  return a string representation of the value."
  [mbean]
  {:post [(map? %)]}
  (into {} (for [[k v] mbean]
             (cond
              ;; Nested structures should themselves be filtered
              (map? v)
              [k (filter-mbean v)]

              ;; Cheshire can serialize to JSON anything that
              ;; implements the JSONable protocol
              (satisfies? JSONable v)
              [k v]

              :else
              [k (str v)]))))
(defmacro with-test-broker
  "Constructs and starts an embedded MQ, and evaluates `body` inside a
  `with-open` expression that takes care of connection cleanup and MQ
  tear-down.

  `name` - The name to use for the embedded MQ

  `conn-var` - Inside of `body`, the variable named `conn-var`
  contains an active connection to the embedded broker.

  Example:

      (with-test-broker "my-broker" the-connetion
        ;; Do something with the connection
        (prn the-connection))
  "
  [name conn-var & body]
  `(let [dir#                     (fs/absolute-path (fs/temp-dir))
         broker-name#             ~name
         conn-str#                (str "vm://" ~name)
         ^BrokerService broker#   (mq/build-embedded-broker broker-name# dir#)]

     (.setUseJmx broker# false)
     (.setPersistent broker# false)
     (mq/start-broker! broker#)

     (try
       (with-open [~conn-var (mq/connect! conn-str#)]
         ~@body)
       (finally
         (mq/stop-broker! broker#)
         (fs/delete-dir dir#)))))
Results
Thousands of
production
deployments
Small shops with a dozen hosts,
large shops with thousands of
hosts, intercontinental
deployments...
PuppetDB: Sneaking Clojure into Operations
Thousands of deployments,
Hundreds of threads per install,
Zero deadlocks,
Zero bugs involving clojure state

          companion Ruby code has
              ~10x the defect rate
Users dig the uberjar,
makes deployment
straightforward and
less error-prone
Nobody cares that it’s
Clojure. Users just
want stuff to work.
Monitoring and
instrumentation is a
big deal. Users want
easy ways to
consume metrics.
If you build it, they
will come.
Open source

http://github.com/
puppetlabs/puppetdb
deepak
giridharagopal
deepak@puppetlabs.com
@grim_radical [github twitter freenode]


        We’re hiring!

More Related Content

KEY
Making Your Capistrano Recipe Book
Tim Riley
 
PPTX
Puppet_training
Afroz Hussain
 
PDF
Introduction to Apache ZooKeeper | Big Data Hadoop Spark Tutorial | CloudxLab
CloudxLab
 
PDF
Practicing Continuous Deployment
zeeg
 
PDF
Managing PostgreSQL with Ansible - FOSDEM PGDay 2016
Gulcin Yildirim Jelinek
 
PPTX
Ansible
Afroz Hussain
 
PDF
Ansible not only for Dummies
Łukasz Proszek
 
PDF
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
DECK36
 
Making Your Capistrano Recipe Book
Tim Riley
 
Puppet_training
Afroz Hussain
 
Introduction to Apache ZooKeeper | Big Data Hadoop Spark Tutorial | CloudxLab
CloudxLab
 
Practicing Continuous Deployment
zeeg
 
Managing PostgreSQL with Ansible - FOSDEM PGDay 2016
Gulcin Yildirim Jelinek
 
Ansible
Afroz Hussain
 
Ansible not only for Dummies
Łukasz Proszek
 
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
DECK36
 

What's hot (20)

PDF
Take control of your Jenkins jobs via job DSL.
Łukasz Proszek
 
PDF
Apache Zookeeper
Nguyen Quang
 
PPTX
Introduction to Apache ZooKeeper
Saurav Haloi
 
PPT
Zookeeper Introduce
jhao niu
 
PDF
Новый InterSystems: open-source, митапы, хакатоны
Timur Safin
 
PDF
Distributed system coordination by zookeeper and introduction to kazoo python...
Jimmy Lai
 
KEY
Puppet for dummies - ZendCon 2011 Edition
Joshua Thijssen
 
PPTX
Introduction to apache zoo keeper
Omid Vahdaty
 
PDF
Getting started with Ansible
Ivan Serdyuk
 
PPTX
Herd your chickens: Ansible for DB2 configuration management
Frederik Engelen
 
PDF
Apache ZooKeeper TechTuesday
Andrei Savu
 
PDF
Ansible 實戰:top down 觀點
William Yeh
 
PPTX
Building and Deploying Application to Apache Mesos
Joe Stein
 
PPTX
Learning Puppet basic thing
DaeHyung Lee
 
PDF
20090514 Introducing Puppet To Sasag
garrett honeycutt
 
PPTX
Zookeeper big sonata
Anh Le
 
PPTX
DevOpsDays Warsaw 2015: Running High Performance And Fault Tolerant Elasticse...
PROIDEA
 
PDF
Puppet Camp Dallas 2014: Puppet Keynote
Puppet
 
PDF
Introduction to PowerShell
Boulos Dib
 
PPT
Scalable Systems Management with Puppet
Puppet
 
Take control of your Jenkins jobs via job DSL.
Łukasz Proszek
 
Apache Zookeeper
Nguyen Quang
 
Introduction to Apache ZooKeeper
Saurav Haloi
 
Zookeeper Introduce
jhao niu
 
Новый InterSystems: open-source, митапы, хакатоны
Timur Safin
 
Distributed system coordination by zookeeper and introduction to kazoo python...
Jimmy Lai
 
Puppet for dummies - ZendCon 2011 Edition
Joshua Thijssen
 
Introduction to apache zoo keeper
Omid Vahdaty
 
Getting started with Ansible
Ivan Serdyuk
 
Herd your chickens: Ansible for DB2 configuration management
Frederik Engelen
 
Apache ZooKeeper TechTuesday
Andrei Savu
 
Ansible 實戰:top down 觀點
William Yeh
 
Building and Deploying Application to Apache Mesos
Joe Stein
 
Learning Puppet basic thing
DaeHyung Lee
 
20090514 Introducing Puppet To Sasag
garrett honeycutt
 
Zookeeper big sonata
Anh Le
 
DevOpsDays Warsaw 2015: Running High Performance And Fault Tolerant Elasticse...
PROIDEA
 
Puppet Camp Dallas 2014: Puppet Keynote
Puppet
 
Introduction to PowerShell
Boulos Dib
 
Scalable Systems Management with Puppet
Puppet
 
Ad

Viewers also liked (20)

PDF
Слайды седьмого вещания ИБ
Intellectics
 
PDF
НвЗ Слайды седьмого вещания
Intellectics
 
PPTX
10 Ways to Succeed as a Copywriter
Bob Cargill
 
PDF
Методика Черная кобра
Intellectics
 
PDF
НвЗ Слайды третьего вещания
Intellectics
 
PDF
НвЗ Слайды второго вещания
Intellectics
 
PDF
Fórmulas de copywriting - Aprende a escribir de forma estratégica
SEMrush_es
 
PDF
Слайды шестого вещания
Intellectics
 
PDF
Слайды восьмого вещания
Intellectics
 
PDF
Слайды девятого вещания
Intellectics
 
PDF
НвЗ Слайды шестого занятия
Intellectics
 
PDF
НвЗ Методика Раскадровка
Intellectics
 
PDF
НвЗ Слайды первого вещания
Intellectics
 
PDF
ТЛ - слайды четвертого вещания
Intellectics
 
PDF
Визуальное мышление - Слайды занятий 5 и 6
Intellectics
 
PDF
ТЛ - слайды девятого вещания
Intellectics
 
PDF
ТЛ - слайды седьмого вещания
Intellectics
 
PDF
ТЛ - слайды пятого вещания
Intellectics
 
PDF
Слайды второго занятия
Intellectics
 
PDF
Слайды четвертого вещания
Intellectics
 
Слайды седьмого вещания ИБ
Intellectics
 
НвЗ Слайды седьмого вещания
Intellectics
 
10 Ways to Succeed as a Copywriter
Bob Cargill
 
Методика Черная кобра
Intellectics
 
НвЗ Слайды третьего вещания
Intellectics
 
НвЗ Слайды второго вещания
Intellectics
 
Fórmulas de copywriting - Aprende a escribir de forma estratégica
SEMrush_es
 
Слайды шестого вещания
Intellectics
 
Слайды восьмого вещания
Intellectics
 
Слайды девятого вещания
Intellectics
 
НвЗ Слайды шестого занятия
Intellectics
 
НвЗ Методика Раскадровка
Intellectics
 
НвЗ Слайды первого вещания
Intellectics
 
ТЛ - слайды четвертого вещания
Intellectics
 
Визуальное мышление - Слайды занятий 5 и 6
Intellectics
 
ТЛ - слайды девятого вещания
Intellectics
 
ТЛ - слайды седьмого вещания
Intellectics
 
ТЛ - слайды пятого вещания
Intellectics
 
Слайды второго занятия
Intellectics
 
Слайды четвертого вещания
Intellectics
 
Ad

Similar to PuppetDB: Sneaking Clojure into Operations (20)

PDF
Puppet: Eclipsecon ALM 2013
grim_radical
 
KEY
Puppet for dummies - PHPBenelux UG edition
Joshua Thijssen
 
PDF
PuppetDB: A Single Source for Storing Your Puppet Data - PUG NY
Puppet
 
PDF
Developing IT infrastructures with Puppet
Alessandro Franceschi
 
PPT
Puppet
csrocks
 
PDF
Test driven infrastructure development (2 - puppetconf 2013 edition)
Tomas Doran
 
PDF
Immutant
Norman Richards
 
PDF
Incrementalism: An Industrial Strategy For Adopting Modern Automation
Sean Chittenden
 
PDF
Creating a mature puppet system
rkhatibi
 
PDF
Creating a Mature Puppet System
Puppet
 
PDF
SCM Puppet: from an intro to the scaling
Stanislav Osipov
 
KEY
20100425 Configuration Management With Puppet Lfnw
garrett honeycutt
 
KEY
Puppet for Java developers - JavaZone NO 2012
Carlos Sanchez
 
PDF
Systems Automation with Puppet
elliando dias
 
PDF
Taking devops to the Next Level - Max Martin
Devopsdays
 
PPT
State of Puppet 2013 - Puppet Camp DC
Puppet
 
PDF
Using Puppet - Real World Configuration Management
James Turnbull
 
PDF
Writing and Sharing Great Modules with the Puppet Forge
Puppet
 
PDF
Writing & Sharing Great Modules on the Puppet Forge
Puppet
 
PDF
Build Automation 101
Martin Jackson
 
Puppet: Eclipsecon ALM 2013
grim_radical
 
Puppet for dummies - PHPBenelux UG edition
Joshua Thijssen
 
PuppetDB: A Single Source for Storing Your Puppet Data - PUG NY
Puppet
 
Developing IT infrastructures with Puppet
Alessandro Franceschi
 
Puppet
csrocks
 
Test driven infrastructure development (2 - puppetconf 2013 edition)
Tomas Doran
 
Immutant
Norman Richards
 
Incrementalism: An Industrial Strategy For Adopting Modern Automation
Sean Chittenden
 
Creating a mature puppet system
rkhatibi
 
Creating a Mature Puppet System
Puppet
 
SCM Puppet: from an intro to the scaling
Stanislav Osipov
 
20100425 Configuration Management With Puppet Lfnw
garrett honeycutt
 
Puppet for Java developers - JavaZone NO 2012
Carlos Sanchez
 
Systems Automation with Puppet
elliando dias
 
Taking devops to the Next Level - Max Martin
Devopsdays
 
State of Puppet 2013 - Puppet Camp DC
Puppet
 
Using Puppet - Real World Configuration Management
James Turnbull
 
Writing and Sharing Great Modules with the Puppet Forge
Puppet
 
Writing & Sharing Great Modules on the Puppet Forge
Puppet
 
Build Automation 101
Martin Jackson
 

Recently uploaded (20)

PDF
GYTPOL If You Give a Hacker a Host
linda296484
 
PDF
Accelerating Oracle Database 23ai Troubleshooting with Oracle AHF Fleet Insig...
Sandesh Rao
 
PDF
Make GenAI investments go further with the Dell AI Factory - Infographic
Principled Technologies
 
PPT
L2 Rules of Netiquette in Empowerment technology
Archibal2
 
PPTX
C Programming Basics concept krnppt.pptx
Karan Prajapat
 
PDF
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
codernjn73
 
PPTX
AI and Robotics for Human Well-being.pptx
JAYMIN SUTHAR
 
PDF
Chapter 2 Digital Image Fundamentals.pdf
Getnet Tigabie Askale -(GM)
 
PPTX
How to Build a Scalable Micro-Investing Platform in 2025 - A Founder’s Guide ...
Third Rock Techkno
 
PDF
Why Your AI & Cybersecurity Hiring Still Misses the Mark in 2025
Virtual Employee Pvt. Ltd.
 
PDF
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
PDF
Google’s NotebookLM Unveils Video Overviews
SOFTTECHHUB
 
PDF
Event Presentation Google Cloud Next Extended 2025
minhtrietgect
 
PDF
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
PDF
CIFDAQ's Token Spotlight: SKY - A Forgotten Giant's Comeback?
CIFDAQ
 
DOCX
Top AI API Alternatives to OpenAI: A Side-by-Side Breakdown
vilush
 
PDF
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
PDF
Using Anchore and DefectDojo to Stand Up Your DevSecOps Function
Anchore
 
PPTX
Smart Infrastructure and Automation through IoT Sensors
Rejig Digital
 
PDF
REPORT: Heating appliances market in Poland 2024
SPIUG
 
GYTPOL If You Give a Hacker a Host
linda296484
 
Accelerating Oracle Database 23ai Troubleshooting with Oracle AHF Fleet Insig...
Sandesh Rao
 
Make GenAI investments go further with the Dell AI Factory - Infographic
Principled Technologies
 
L2 Rules of Netiquette in Empowerment technology
Archibal2
 
C Programming Basics concept krnppt.pptx
Karan Prajapat
 
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
codernjn73
 
AI and Robotics for Human Well-being.pptx
JAYMIN SUTHAR
 
Chapter 2 Digital Image Fundamentals.pdf
Getnet Tigabie Askale -(GM)
 
How to Build a Scalable Micro-Investing Platform in 2025 - A Founder’s Guide ...
Third Rock Techkno
 
Why Your AI & Cybersecurity Hiring Still Misses the Mark in 2025
Virtual Employee Pvt. Ltd.
 
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
Google’s NotebookLM Unveils Video Overviews
SOFTTECHHUB
 
Event Presentation Google Cloud Next Extended 2025
minhtrietgect
 
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
CIFDAQ's Token Spotlight: SKY - A Forgotten Giant's Comeback?
CIFDAQ
 
Top AI API Alternatives to OpenAI: A Side-by-Side Breakdown
vilush
 
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
Using Anchore and DefectDojo to Stand Up Your DevSecOps Function
Anchore
 
Smart Infrastructure and Automation through IoT Sensors
Rejig Digital
 
REPORT: Heating appliances market in Poland 2024
SPIUG
 

PuppetDB: Sneaking Clojure into Operations