pupistry 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +296 -0
  3. data/bin/pupistry +177 -0
  4. data/lib/pupistry.rb +8 -0
  5. metadata +89 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2c47a743b2bf72dc35a18a04e4c907029773f9cd
4
+ data.tar.gz: 0ffd31d0773fac92db4989fcd52bafb4b25e2215
5
+ SHA512:
6
+ metadata.gz: 36fa8ed2a0f3b0fc34d548649582143193fa78e29420bda0f69d5a0c27488c93e4f96a4c102cdcc533cdf9f2414ba8bbb75c28da8363822c59ff8b386987a750
7
+ data.tar.gz: 715fa89d66398222226527be295da1532d17c9f32a35e2d1d878ac7564a5f3cb5a3632f819cdd6a052d1e3fefed4e6de6381549591904a8014b411219baa29ee
data/README.md ADDED
@@ -0,0 +1,296 @@
1
+ # WORK IN PROGRESS
2
+
3
+ This project is currently in progress and not all of this documentation reflects
4
+ where it is really at. Use this at your own peril/madness.
5
+
6
+ # pupistry
7
+
8
+ Pupistry (puppet + artistry) is a solution for implementing reliable and secure
9
+ masterless puppet deployments by taking Puppet modules assembled by r10k and
10
+ generating compresed and signed archives for distribution to the masterless
11
+ servers.
12
+
13
+ Pupistry builds on the functionality offered by the r10k workflow but rather
14
+ than requiring the implementing of site-specific custom bootstrap and custom
15
+ workflow mechanisms, Pupistry executes r10k, assembles the combined modules
16
+ and then generates a compress artifact file. It then signs the artifact with
17
+ GPG and uploads it into an Amazon S3 bucket along with a manifest file.
18
+
19
+ The masterless Puppet machines then just run a Pupistry job which checks for a
20
+ new version of the manifest file. If there is, it downloads the new artifact
21
+ and does a GPG validation before applying it and running Puppet. To make life
22
+ even easier, Pupistry will even spit out bootstrap files for your platform
23
+ which sets up each server from scratch to pull and run the artifacts.
24
+
25
+ Essentially Pupistry is intended to be a robust solution for masterless Puppet
26
+ deployments and makes it trivial for beginners to get started with Puppet.
27
+
28
+
29
+ # Why Pupistry?
30
+
31
+ Masterless Puppet is a great solution for anyone wanting to avoid scaling issues
32
+ and risk of centralised failure due to a central Puppet master, but it does bring
33
+ a number of issues with it.
34
+
35
+ 1. Having to setup deployer keys to every git repo used is a maintainance headache. Pupistry means only your workstation needs access, which presumably will have access to most/all repos already.
36
+ 2. Your system build success is dependent on all the git repos you've used, including any third parties that could vanish. A single missing or broken repo could prevent autoscaling or new machine builds at a critical time. Pupistry's use of artifact files prevents surprises - if you can hit S3, you're sorted.
37
+ 3. It is easy for malicious code in the third party repos to slip in without noticing. Even if the author themselves is honest, not all repos have proper security like two-factor. Pupistry prevents surprise updates of modules and also has an easy diff feature to see what changed since you last generated an artifact.
38
+ 4. Puppet masterless tends to be implemented in many different ways using everyone's own hacky scripts. Pupistry's goal is to create a singular standard/approach to masterless, in the same way that r10k created a standard approach to git-based Puppet workflows. And this makes things easy - install Pupistry, add the companion Puppet module and run the bootstrap script. Easy!
39
+ 5. No dodgy cronjobs running r10k and Puppet in weird ways. A simple clean agent with daemon or run-once functionality.
40
+ 6. Performance - Go from 30+ seconds r10k update checks to 2 second Pupistry update checks. And when there is a change, it's a fast efficent compressed file download from S3 rather than pulling numerious git repos.
41
+
42
+
43
+
44
+ # Usage
45
+
46
+ ## Building new artifacts
47
+
48
+ Build a new artifact:
49
+
50
+ pupistry build
51
+
52
+ Note that artifact builds are done from the upstream git repos, so if you
53
+ have made changes, remember to git push first before generating. The tool will
54
+ remind you if it detects nothing has changed since the last run.
55
+
56
+ Once your artifact is built, you can double check what has changed in the
57
+ Puppet modules since the last run with:
58
+
59
+ pupistry diff
60
+
61
+
62
+ Finally when you're happy, push it to S3 to be delivered to all your servers.
63
+ If you have gpg signing enabled, it will ask you to sign here.
64
+
65
+ pupistry push
66
+
67
+
68
+ ## Bootstrapping nodes
69
+
70
+ You need to bootstrap your masterless nodes, which involves installing Pupistry
71
+ and setting up Puppet configuration accordingly.
72
+
73
+ pupistry bootstrap
74
+
75
+ pupistry boostrap --template rhel7
76
+
77
+
78
+ You generally can run this on a new non-Puppetised machine, or into the user
79
+ data field of most cloud providers like AWS or Digital Ocean.
80
+
81
+
82
+ ## Running Puppet on target nodes
83
+
84
+ Check what is going to be applied (Puppet in --noop mode)
85
+
86
+ pupistry apply --noop
87
+
88
+
89
+ Apply the current Puppet manifests:
90
+
91
+ pupistry apply
92
+
93
+ Specify an alternative environment:
94
+
95
+ pupistry apply --environment staging
96
+
97
+
98
+ Run pupistry as a system daemon. When you use the companion Puppet module, a
99
+ system init file gets installed that sets this daemon up for you automatically.
100
+
101
+ pupistry apply --daemon
102
+
103
+
104
+
105
+ # Installation
106
+
107
+ ## 1. Application
108
+
109
+ First install Pupistry onto your workstation. You can make pupistry generate
110
+ you a config file if you've never used it before
111
+
112
+ gem install pupistry
113
+ pupistry setup
114
+
115
+ Alternatively if you like living on the edge, download this repository and run:
116
+
117
+ gembuild pupistry.gemspec
118
+ gem install pupistry-VERSION.gem
119
+ pupistry setup
120
+
121
+
122
+ ## 2. S3 Bucket
123
+
124
+ Pupistry uses S3 for storing and pulling the artifact files. You need to
125
+ configure the following:
126
+
127
+ * A *private* S3 bucket (you'll get this by default).
128
+ * An IAM account with access to write that bucket (for your build workstation)
129
+ * An IAM account with access to read that bucket (for your servers)
130
+
131
+ If you're not already using IAM with your AWS account you want to be - your
132
+ servers should only ever have read access to the bucket and only your build
133
+ workstation should be permitted to write new artifacts. IE, don't share your
134
+ AWS root account around the place. :-)
135
+
136
+ Note that if you're running EC2 instances and using IAM roles, you can avoid
137
+ needing to create explicit IAM credentials for the agents/servers.
138
+
139
+
140
+
141
+ ## 3. Helper Puppet Module
142
+
143
+ Whilst you can use Pupistry to roll out any particular design of Puppet
144
+ manifests, you will save yourself a lot of pain by also including the Pupistry
145
+ companion Puppet module in your manifests.
146
+
147
+ The companion Puppet module will configure Pupistry for you, including setting
148
+ up the system service and configuring Puppet and Hiera correctly for masterless
149
+ operation.
150
+
151
+ You can fetch the module from:
152
+ https://github.com/jethrocarr/pupistry-puppet
153
+
154
+ If you're doing r10k and Puppet masterless from scratch, this is probably
155
+ something you want to make life easy.
156
+
157
+
158
+ ## 4. Bootstrapping Nodes
159
+
160
+ No need for manual configuration of your servers/nodes, you just need to build
161
+ your first artifact with Pupistry (`pupistry build && pupistry push`) and then
162
+ generate a bootstrap script for your particular OS with `pupistry bootstrap`
163
+
164
+ The bootstrap script will:
165
+ 1. Install Puppet and Pupistry for the particular OS.
166
+ 2. Download the latest artifact
167
+ 3. Trigger a Puppet run to build your server.
168
+
169
+ Once done, it's up to your Puppet manifests to build your machine how you want
170
+ it - enjoy!
171
+
172
+
173
+
174
+ # Tutorials
175
+
176
+ If you're looking for a more complete introduction to doing masterless Puppet
177
+ and want to use Pupistry, check out a tutorial by the author:
178
+
179
+ TUTORIAL LINK HERE
180
+
181
+ By following this tutorial you can go from nothing, to having a complete up
182
+ and running masterless Puppet environment using Pupistry. It covers the very
183
+ basics of setting up your r10k environment.
184
+
185
+
186
+
187
+
188
+ # Caveats & Future Plans
189
+
190
+ ## Use r10k
191
+
192
+ Currently only an r10k workflow is supported. Pull requests for others (eg
193
+ Librarian Puppet) are welcome, but it's not a priority for this author as r10k
194
+ is working nicely.
195
+
196
+
197
+ ## Bootstrap Functionality
198
+
199
+ Currently Pupistry only supports generation of bootstrap for CentOS 7 & Ubuntu
200
+ 14.04. Other distributions will be added, but it may take time to get to your
201
+ particular favourite distribution.
202
+
203
+ Note that it isn't a show stopper if support for your platform of choice
204
+ doesn't yet exist - you can use pupistry with pretty much any nix platform,
205
+ you'll just not have the handy advantage of automatically generated bootstrap
206
+ for your servers.
207
+
208
+ If you do customise it for a different platform, pull requests are VERY
209
+ welcome, I'll add pretty much any OS if you write a decent bootstrap template
210
+ for it.
211
+
212
+
213
+ ## Continious Deployment
214
+
215
+ A lot of what Pupistry does can also be accomplished by various home-grown
216
+ Continious Deployment (CD) solutions using platforms like Jenkins or Bamboo. CD
217
+ is an excellent approach for larger organisations, but Pupistry has been
218
+ designed for both large and small users so does not mandate it.
219
+
220
+ It would be possible to use Pupistry as part of your CD process and if you
221
+ decide to do so, a pull request to better support CD systems out-of-the-box
222
+ would be welcome.
223
+
224
+
225
+ ## Hiera Security Still Sucks
226
+
227
+ In a standard Puppet master situation, the Puppet master parses the Hiera data
228
+ and then passes only the values that apply to a particular host to it. But with
229
+ masterless Puppet, all machines get a full copy of Hiera data, which could be a
230
+ major issue if one box gets expoited and the contents leaked. Generally it goes
231
+ against good practise and damanges the isolation ability of VMs if you give all
232
+ the VMs enough information to do some serious damage to themselves.
233
+
234
+ Pupistry does not yet have any solution for it and it remains a fundamental
235
+ limitation of the Puppet masterless approach. Longer term, we could potentially
236
+ craft a solution that customises the artifacts per-machine to fix this security
237
+ gap, but there's no proper solution currently.
238
+
239
+ If you have an environment where you need to send lots of sensitive values to
240
+ your servers, a traditional master-full Puppet environment may be a better
241
+ solution for this reason. But if you can architect to avoid this or have no
242
+ critical secrets in Hiera, Pupistry should be good for you.
243
+
244
+
245
+ ## PuppetDB
246
+
247
+ There's nothing stopping you from using PuppetDB other than Pupistry has no
248
+ automatic setup hooks in the bootstrap config. Pull requests to support
249
+ PuppetDB for masterless machines are welcome, although masterless users tend
250
+ to want to avoid dependencies on a central point.
251
+
252
+
253
+ ## Windows
254
+
255
+ No idea whether this works under Windows, or what would be required to make it
256
+ do so. Again, pull requests always welcome but it's not a priority for the
257
+ author.
258
+
259
+
260
+
261
+ # Developing
262
+
263
+ When developing Pupistry, you can run the git repo copy with:
264
+
265
+ ruby -Ilib/ -r rubygems bin/pupistry
266
+
267
+ By default Pupistry will try to load a settings.yaml file in the current
268
+ working directory, before then trying ~/.pupistry/settings.yaml and then
269
+ finally /etc/pupistry/settings.yaml. You can also override with --config.
270
+
271
+ Add --verbose for additional debugging information.
272
+
273
+
274
+ # Contributions
275
+
276
+ Pull requests are very welcome. Pupistry is a very young app and there is
277
+ plenty of work that can be done to improve it's code quality, enhance existing
278
+ features and add handy new features. Constructive feedback/requests via the
279
+ issue tracker is fine, but pull requests speak louder than words. :-)
280
+
281
+ If you find a bug or need support, please use the issue tracker rather than
282
+ personal emails to the author.
283
+
284
+
285
+ # Author
286
+
287
+ Pupistry is developed by Jethro Carr. Blog posts about Pupistry and new
288
+ features can be found at http://www.jethrocarr.com/tag/pupistry
289
+
290
+ Beer welcome.
291
+
292
+
293
+ # License
294
+
295
+ Pupistry is licensed under the Apache License, Version 2.0.
296
+
data/bin/pupistry ADDED
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env ruby
2
+ # Lancher for Pupistry CLI
3
+
4
+ require 'rubygems'
5
+ require 'thor'
6
+ require 'logger'
7
+ require 'pupistry'
8
+
9
+ # Ensure all output is real time - this is a long running process with
10
+ # continual output, we want it to sync ASAP
11
+ STDOUT.sync = true
12
+
13
+ # Logging - STDOUT only
14
+ $logger = Logger.new(STDOUT)
15
+
16
+
17
+ # Thor is a toolkit for producing command line applications, see http://whatisthor.com/
18
+ class CLI < Thor
19
+ class_option :verbose, :type => :boolean
20
+ class_option :config, :type => :string
21
+
22
+ desc "build", "Build a new archive file"
23
+ def build
24
+
25
+ # Thor seems to force class options to be defined repeatedly? :-/
26
+ if options[:verbose]
27
+ $logger.level = Logger::DEBUG
28
+ else
29
+ $logger.level = Logger::INFO
30
+ end
31
+
32
+ if options[:config]
33
+ Pupistry::Config.load(options[:config])
34
+ else
35
+ Pupistry::Config.find_and_load
36
+ end
37
+
38
+
39
+ begin
40
+ # Fetch the latest data with r10k
41
+ artifact = Pupistry::Artifact.new
42
+
43
+ artifact.fetch_r10k
44
+ artifact.build_artifact
45
+
46
+ puts "--"
47
+ puts "Tip: Run pupistry diff to see what changed since the last artifact version"
48
+
49
+ rescue Exception => e
50
+ $logger.fatal "An unexpected error occured when trying to generate the new artifact file"
51
+ raise e
52
+ end
53
+
54
+
55
+ end
56
+
57
+
58
+ desc "diff", "Show what has changed between now and the current live artifact"
59
+ def diff
60
+
61
+ # Thor seems to force class options to be defined repeatedly? :-/
62
+ if options[:verbose]
63
+ $logger.level = Logger::DEBUG
64
+ else
65
+ $logger.level = Logger::INFO
66
+ end
67
+
68
+ if options[:config]
69
+ Pupistry::Config.load(options[:config])
70
+ else
71
+ Pupistry::Config.find_and_load
72
+ end
73
+
74
+ # Fetch the latest artifact
75
+ artifact_upstream = Pupistry::Artifact.new
76
+ artifact_upstream.checksum = artifact_upstream.fetch_latest
77
+
78
+ unless artifact_upstream.checksum
79
+ $logger.error "There is no upstream artifact to compare to."
80
+ exit 0
81
+ end
82
+
83
+ artifact_upstream.fetch_artifact
84
+
85
+ # Fetch the current artifact
86
+ artifact_current = Pupistry::Artifact.new
87
+ artifact_current.checksum = artifact_current.fetch_current
88
+
89
+ unless artifact_current.checksum
90
+ $logger.error "There is no current artifact to compare to, run \"pupistry build\" first to generate one with current changes"
91
+ exit 0
92
+ end
93
+
94
+ artifact_current.fetch_artifact
95
+
96
+ # Unpack the archives
97
+ artifact_current.unpack
98
+ artifact_upstream.unpack
99
+
100
+ # Diff the contents. This is actually bit of a pain, there's no native way
101
+ # of diffing an entire directory and a lot of the gems out there that promise
102
+ # to do diffing a) can't handle dirs and b) generally exec out to native diff
103
+ # anyway. :-(
104
+ #
105
+ # So given this, we might as well go native and just rely on the system
106
+ # diff command to do the job.
107
+
108
+ Dir.chdir("#{$config["general"]["app_cache"]}/artifacts/") do
109
+ unless system "diff -Nuar unpacked.#{artifact_upstream.checksum} unpacked.#{artifact_current.checksum}"
110
+ end
111
+ end
112
+
113
+
114
+ # Cleanup
115
+ artifact_current.clean_unpack
116
+ artifact_upstream.clean_unpack
117
+
118
+ puts "--"
119
+ puts "Tip: Run pupistry push to GPG sign & upload if happy to go live"
120
+ end
121
+
122
+
123
+ desc "push", "Sign & Upload a new artifact version"
124
+ def push
125
+
126
+ # Thor seems to force class options to be defined repeatedly? :-/
127
+ if options[:verbose]
128
+ $logger.level = Logger::DEBUG
129
+ else
130
+ $logger.level = Logger::INFO
131
+ end
132
+
133
+ if options[:config]
134
+ Pupistry::Config.load(options[:config])
135
+ else
136
+ Pupistry::Config.find_and_load
137
+ end
138
+
139
+ # Push the artifact to S3
140
+ artifact = Pupistry::Artifact.new
141
+ artifact.push_artifact
142
+ end
143
+
144
+
145
+ desc "bootstrap", "Generate a user-data bootstrap script for a node"
146
+ method_option :template, :type => :string
147
+ def bootstrap
148
+
149
+ # Thor seems to force class options to be defined repeatedly? :-/
150
+ if options[:verbose]
151
+ $logger.level = Logger::DEBUG
152
+ else
153
+ $logger.level = Logger::INFO
154
+ end
155
+
156
+ if options[:config]
157
+ Pupistry::Config.load(options[:config])
158
+ else
159
+ Pupistry::Config.find_and_load
160
+ end
161
+
162
+
163
+ if options[:template]
164
+ $logger.info "Generating bootstrap template #{options[:template]}"
165
+ else
166
+ puts "Listing all avaible templates"
167
+ Pupistry::Bootstrap.templates_list
168
+
169
+
170
+ end
171
+
172
+ end
173
+ end
174
+
175
+ CLI.start(ARGV)
176
+
177
+ # vim:shiftwidth=2:tabstop=2:softtabstop=2:expandtab:smartindent
data/lib/pupistry.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'pupistry/config'
2
+ require 'pupistry/bootstrap'
3
+ require 'pupistry/artifact'
4
+ require 'pupistry/storage_aws'
5
+
6
+
7
+
8
+ # vim:shiftwidth=2:tabstop=2:softtabstop=2:expandtab:smartindent
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pupistry
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jethro Carr
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-v1
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: r10k
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Provides security, reliability and consistency to Puppet masterless environments
56
+ email: jethro.carr@jethrocarr.com
57
+ executables:
58
+ - pupistry
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - bin/pupistry
63
+ - lib/pupistry.rb
64
+ - README.md
65
+ homepage: https://github.com/jethrocarr/pupistry
66
+ licenses:
67
+ - Apache
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.0.14
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: A workflow tool for Puppet Masterless Deployments
89
+ test_files: []