pupistry 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []