This repository has been archived by the owner on Jun 21, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4faecc9
Showing
16 changed files
with
599 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/.bundle/ | ||
/.yardoc | ||
/Gemfile.lock | ||
/_yardoc/ | ||
/coverage/ | ||
/doc/ | ||
/pkg/ | ||
/spec/reports/ | ||
/tmp/ | ||
|
||
# Adding bin and vendor as this should never be vendored in production | ||
/bin/ | ||
/vendor/ | ||
|
||
# Chef stuff | ||
.kitchen/ | ||
berks-cookbooks/ | ||
Berksfile.lock | ||
|
||
# Terraform | ||
.terraform | ||
terraform.tfstate | ||
terraform.tfstate.backup |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Copyright 2016 Chris Marchesi | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
source 'https://rubygems.org' | ||
|
||
gemspec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Packer and Terraform Pattern Example | ||
|
||
This repository houses a simple application that demonstrates an end-to-end | ||
infrastructure as code pattern using Packer and Terraform. | ||
|
||
This repository will serve as the basis for an accompanying article at | ||
http://vancluevertech.com (soon to follow). | ||
|
||
## The Components | ||
|
||
* A small ruby gem (`vancluever_hello`). This is built using rubygems tasks | ||
using `rake`. | ||
* A Chef recipe designed for deploying the applicatin (`packer_payload`). | ||
This is a single-purpose cookbook that is not intended to be shared in | ||
Supermarket, etc. It's only intended for use with Packer. With that said, | ||
having a cookbook allows you to port this functionality to a general-use | ||
cookbook if necessary - this can then be included from a fresh | ||
`packer_payload` cookbook. | ||
* A packer template located at `packer/ami.json` | ||
* Terraform infrastructure in the `terraform` directory, comprised of a single | ||
template for now, `main.tf`. | ||
|
||
You manage all of this with `rake`. | ||
|
||
## The `Rakefile` | ||
|
||
The `Rakefile` has tasks for managing the full lifecycle from building of the | ||
gem, to AMI, to deployment. The list is below: | ||
|
||
``` | ||
rake ami # Create an application AMI with Packer | ||
rake berks_cookbooks # Vendors dependent cookbooks in berks-cookbooks (for Packer) | ||
rake build # Build vancluever_hello-0.1.0.gem into the pkg directory | ||
rake clean # Remove any temporary products | ||
rake clobber # Remove any generated files | ||
rake infrastructure # Deploy infrastructure using Terraform | ||
``` | ||
|
||
In addition to that, the file also has helper functions for looking up | ||
AMI IDs to be used in the build process. | ||
|
||
## Using this Repository | ||
|
||
To prepare the repository for use, clone it and run | ||
|
||
``` | ||
bundle install --binstubs --path vendor/bundle | ||
``` | ||
|
||
You should then be good to start using `bundle exec rake`. | ||
|
||
You also need [Packer](https://www.packer.io/) and | ||
[Terraform](https://www.terraform.io/). | ||
|
||
Finally, valid AWS credentials will need to be available in your credential | ||
chain, either as environment variables (ie: AWS_ACCESS_KEY, | ||
AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN), or your credentials in your | ||
`~/.aws` directory. | ||
|
||
### Environment variables | ||
|
||
You can also control the build process through the following environment | ||
variables: | ||
|
||
* `DISTRO` To control the Ubuntu distribution to use (default `trusty`). | ||
* `REGION` To control the region to deploy to (default `us-east-1`). | ||
* `TF_CMD` To control the Terrafrom command (default `apply`). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# Copyright 2016 Chris Marchesi | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
require 'bundler/gem_tasks' | ||
require 'ubuntu_ami' | ||
require 'vancluever_hello/version' | ||
require 'aws-sdk' | ||
require 'date' | ||
|
||
# Return a default distro if not defined | ||
def distro | ||
if ENV.include?('DISTRO') | ||
ENV['DISTRO'] | ||
else | ||
'trusty' | ||
end | ||
end | ||
|
||
# Return a default region if not defined | ||
def region | ||
if ENV.include?('REGION') | ||
ENV['REGION'] | ||
else | ||
'us-east-1' | ||
end | ||
end | ||
|
||
# Return a default Terraform command if not defined | ||
def tf_cmd | ||
if ENV.include?('TF_CMD') | ||
ENV['TF_CMD'] | ||
else | ||
'apply' | ||
end | ||
end | ||
|
||
# Get an ubuntu AMI ID to build off of (for Packer) | ||
def ubuntu_ami_id | ||
Ubuntu.release(distro).amis.find do |ami| | ||
ami.arch == 'amd64' && | ||
ami.root_store == 'ebs-ssd' && | ||
ami.region == region | ||
end.name | ||
end | ||
|
||
# Timestamp conversion for AMI timestamp. | ||
def rfc3339_to_unix(timestamp) | ||
DateTime.rfc3339(timestamp).to_time.seconds | ||
end | ||
|
||
# Get the latest AMI ID that we have built (for Terraform) | ||
def app_ami_id | ||
ec2 = Aws::EC2::Client.new(region: region) | ||
resp = ec2.describe_images( | ||
filters: [ | ||
{ | ||
name: 'tag:app_name', | ||
values: ['vancluever_hello'] | ||
} | ||
] | ||
) | ||
fail 'No built application images found' if resp.images.length < 1 | ||
images = resp.images.sort do |a, b| | ||
rfc3339_to_unix(b.creation_date) <=> rfc3339_to_unix(a.creation_date) | ||
end | ||
images[0].image_id | ||
end | ||
|
||
# Make sure I don't release/push this to rubygems by mistake | ||
Rake::Task['release'].clear | ||
|
||
# Also no system install | ||
Rake::Task['install:local'].clear | ||
Rake::Task['install'].clear | ||
|
||
desc 'Vendors dependent cookbooks in berks-cookbooks (for Packer)' | ||
task :berks_cookbooks do | ||
sh 'rm -rf berks-cookbooks' | ||
sh 'berks vendor -b cookbooks/packer_payload/Berksfile' | ||
end | ||
|
||
desc 'Create an application AMI with Packer' | ||
task :ami => [:build, :berks_cookbooks] do | ||
sh "DISTRO=#{distro} \ | ||
SRC_AMI=#{ubuntu_ami_id} \ | ||
SRC_REGION=#{region} \ | ||
APP_VERSION=#{VanclueverHello::VERSION} \ | ||
packer build packer/ami.json" | ||
end | ||
|
||
desc 'Deploy infrastructure using Terraform' | ||
task :infrastructure do | ||
sh "DISTRO=#{distro} \ | ||
TF_VAR_ami_id=#{app_ami_id} \ | ||
TF_VAR_region=#{region} \ | ||
terraform #{tf_cmd} terraform" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Copyright 2016 Chris Marchesi | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
--- | ||
driver: | ||
name: ec2 | ||
|
||
driver_config: | ||
aws_ssh_key_id: chef-kitchen-test-aws | ||
instance_type: t2.medium | ||
|
||
transport: | ||
username: <%= ENV['AWS_KITCHEN_USER'] %> | ||
|
||
provisioner: | ||
name: chef_zero | ||
data_path: ../../pkg/ | ||
|
||
platforms: | ||
- name: aws | ||
driver: | ||
image_id: <%= ENV['AWS_KITCHEN_AMI_ID'] %> | ||
|
||
suites: | ||
- name: default | ||
run_list: | ||
- recipe[packer_payload::default] | ||
attributes: | ||
packer_payload: | ||
source_path: /tmp/kitchen/data | ||
app_version: <%= ENV['KITCHEN_APP_VERSION'] %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
source 'https://supermarket.chef.io/' | ||
|
||
metadata |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Copyright 2016 Chris Marchesi | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
default['packer_payload']['source_path'] = '/tmp/gem_pkg' | ||
default['packer_payload']['app_user'] = 'ubuntu' | ||
default['packer_payload']['app_path'] = '/home/ubuntu' | ||
default['packer_payload']['app_version'] = '0.1.0' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Copyright 2016 Chris Marchesi | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
name 'packer_payload' | ||
depends 'poise-ruby' | ||
depends 'poise-ruby-build' | ||
depends 'poise-service' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Copyright 2016 Chris Marchesi | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
SRC_PATH = node['packer_payload']['source_path'] | ||
APP_VERSION = node['packer_payload']['app_version'] | ||
|
||
ruby_runtime '2.1' do | ||
provider :ruby_build | ||
action :install | ||
end | ||
|
||
ruby_gem "#{SRC_PATH}/vancluever_hello-#{APP_VERSION}.gem" do | ||
action :install | ||
end | ||
|
||
poise_service 'vancluever_hello' do | ||
command '/opt/ruby_build/builds/2.1/bin/vancluever_hello' | ||
user node['packer_payload']['app_user'] | ||
directory node['packer_payload']['app_path'] | ||
end |
7 changes: 7 additions & 0 deletions
7
cookbooks/packer_payload/test/integration/default/serverspec/default_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
require 'serverspec' | ||
|
||
set :backend, :exec | ||
|
||
describe port(4567) do | ||
it { should be_listening.on('0.0.0.0') } | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/usr/bin/env ruby | ||
# | ||
# Copyright 2016 Chris Marchesi | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
require 'vancluever_hello' | ||
require 'socket' | ||
|
||
VanclueverHello::Server.run_server |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Copyright 2016 Chris Marchesi | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
require 'sinatra/base' | ||
require 'socket' | ||
|
||
module VanclueverHello | ||
# Run the test server. | ||
class Server < Sinatra::Base | ||
def self.run_server | ||
set :bind, '0.0.0.0' | ||
|
||
get '/' do | ||
"Hello from #{Socket.gethostname}!!!" | ||
end | ||
|
||
run! | ||
end | ||
end | ||
end |
Oops, something went wrong.