Skip to content

Instantly share code, notes, and snippets.

@jasonwbarnett
Last active August 29, 2015 14:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasonwbarnett/155484ef1c821631512c to your computer and use it in GitHub Desktop.
Save jasonwbarnett/155484ef1c821631512c to your computer and use it in GitHub Desktop.
NGINX config LWRP for Chef Opscode.
# [15:02:56 CDT] jbarnett@r225 [~]$ rvmsudo chef-client --once -o 'recipe[nginx::spigit_engage]'
---
mindjet:
engage:
maintenance: false
maintenance_title: Site Maintenance in Progress
maintenance_msg: Site is offline for scheduled maintence
ip_restricted: false
allowed_ips: ['25.25.25.25', '22.22.0.0/16']
ip_restrict_msg: Access to the specified resource has been forbidden.<br/>Contact your Administrator if you believe this is a mistake.
nginx:
configs:
qa356:
type: engage
server_names: ['qa356.domain.com', '*.qa356.domain.com']
root: /opt/nginx/qa356
tomcat_host_ip: 192.168.3.5
tomcat_ssl_port: 8081
proxy_connect_timeout: 5s
proxy_read_timeout: 35s
proxy_read_timeout_long: 1800s
ssl_enabled: true
ssl_protocols: SSLv3 TLSv1 TLSv1.1 TLSv1.2
ssl_forced: false
ssl_server_names: ['qa356.domain.com', '*.qa356.domain.com']
ssl_ipaddress: 192.168.3.5
ssl_ciphers: ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH
ssl_certificate: /opt/certs/pem/*.qa356.domain.com.crt
ssl_certificate_key: /opt/certs/pem/*.qa356.domain.com.key
proxy_intercept_errors: true
spigit_only: false
qa356_redirect:
type: redirect
redirect_to: www.qa356.domain.com
# Good base point (file should live: /opt/webapps/<webapp_dir>/.site_config.yaml):
# /spigit/operations-scripts/tomcatTools/update_connectors.rb -i
---
nginx:
site_name: qa356
server_names: ['qa356.spigit.com', '*.qa356.spigit.com']
tomcat_host_ip: 192.168.100.194
ssl_enabled: true
ssl_servernames: ['*.qa356.spigit.com']
ssl_ipaddress: 192.168.100.194
ssl_certificate: /opt/certs/pem/*.qa356.spigit.com.crt
ssl_certificate_key: /opt/certs/pem/*.qa356.spigit.com.key
$ rvmsudo chef-client --once -o 'recipe[nginx::spigit_engage]'
$ /spigit/operations-scripts/tomcatTools/update_connectors.rb -i
$ iptables -L -t nat -n | egrep '192.168.100.194'
$ vim /etc/rc.d/rc.local ## Comment out IP
$ service iptables restart; /etc/rc.d/rc.local ## Restart iptables
$ iptables -L -t nat -n | egrep '192.168.100.194' ## confirm IP is no longer in iptables
$ sudo /sbin/service nginx restart; sudo /sbin/service tomcat restart
# Support whyrun
def whyrun_supported?
true
end
use_inline_resources
action :create do
set_defaults(new_resource)
template new_resource.site_name do
path "/etc/nginx/conf.d/fronting_tomcat/#{new_resource.site_name}.conf"
source 'fronting_tomcat.erb'
mode '0644'
owner 'root'
group 'root'
variables({resource: new_resource})
end
directory "#{new_resource.root}/public_html" do
recursive true
mode '0775'
owner 'nginx'
owner 'spigit'
end
template "#{new_resource.root}/public_html/robots.txt" do
source 'robots.txt.erb'
mode '0644'
owner 'nginx'
group 'spigit'
variables({resource: new_resource})
action :create
end
template "#{new_resource.root}/public_html/403.html" do
source '403.html.erb'
mode '0644'
owner 'nginx'
group 'spigit'
variables({resource: new_resource})
action :create
end
maintenance_action = new_resource.maintenance ? :create : :delete
template "#{new_resource.root}/public_html/maintenance.html" do
source 'maintenance.html.erb'
mode '0644'
owner 'nginx'
group 'spigit'
variables({resource: new_resource})
action maintenance_action
end
ip_restrictions_action = new_resource.ip_restricted ? :create : :delete
template "/etc/nginx/conf.d/ip_restrictions/#{new_resource.site_name}.conf" do
source 'allowed_ips.erb'
mode '0644'
owner 'nginx'
group 'spigit'
variables({resource: new_resource})
action ip_restrictions_action
end
end
def set_defaults(resource)
root = resource.root ? resource.root : "/opt/nginx/#{resource.site_name}"
resource.root(root)
ssl_server_names = resource.ssl_server_names ? resource.ssl_server_names : [ resource.site_name ]
resource.ssl_server_names(ssl_server_names)
end
#
# Cookbook Name:: nginx
# Recipe:: spigit_engage
#
# Author:: Jason Barnett <J@sonBarnett.com>
#
# Copyright 2014, Mindjet LLC
#
# 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.
#
site_configs = Dir.glob("/opt/webapps/*/.site_config.yaml")
site_configs.each do |site|
config = YAML.load_file(site)
nginx_fronting_tomcat config['nginx']['site_name'] do
site_name config['nginx']['site_name']
server_names config['nginx']['server_names']
root config['nginx']['root']
tomcat_host_ip config['nginx']['tomcat_host_ip']
tomcat_ssl_port config['nginx']['tomcat_ssl_port']
proxy_connect_timeout config['nginx']['proxy_connect_timeout']
proxy_read_timeout config['nginx']['proxy_read_timeout']
proxy_read_timeout_long config['nginx']['proxy_read_timeout_long']
ssl_enabled config['nginx']['ssl_enabled']
ssl_protocols config['nginx']['ssl_protocols']
ssl_forced config['nginx']['ssl_forced']
ssl_server_names config['nginx']['ssl_server_names']
ssl_ipaddress config['nginx']['ssl_ipaddress']
ssl_ciphers config['nginx']['ssl_ciphers']
ssl_certificate config['nginx']['ssl_certificate']
ssl_certificate_key config['nginx']['ssl_certificate_key']
redirect_base_to config['nginx']['redirect_base_to']
proxy_intercept_errors config['nginx']['proxy_intercept_errors']
ip_restricted config['nginx']['ip_restricted']
allowed_ips config['nginx']['allowed_ips']
ip_restrict_msg config['nginx']['ip_restrict_msg']
spigit_only config['nginx']['spigit_only']
maintenance config['nginx']['maintenance']
maintenance_title config['nginx']['maintenance_title']
maintenance_msg config['nginx']['maintenance_msg']
end
end
require 'resolv'
actions :create
default_action :create
attribute :site_name, name_attribute: true, kind_of: String, required: true
attribute :server_names, kind_of: Array, required: true
attribute :root, kind_of: String
attribute :tomcat_host_ip, kind_of: String, required: true, regex: Resolv::IPv4::Regex
attribute :tomcat_ssl_port, kind_of: Fixnum, default: 8081
attribute :proxy_connect_timeout, kind_of: String, default: '5s'
attribute :proxy_read_timeout, kind_of: String, default: '35s'
attribute :proxy_read_timeout_long, kind_of: String, default: '1800s'
attribute :ssl_enabled, kind_of: [ TrueClass, FalseClass ], default: false
attribute :ssl_protocols, kind_of: String, default: 'SSLv3 TLSv1 TLSv1.1 TLSv1.2'
attribute :ssl_forced, kind_of: [ TrueClass, FalseClass ], default: false
attribute :ssl_server_names, kind_of: Array
attribute :ssl_ipaddress, kind_of: String, regex: Resolv::IPv4::Regex
attribute :ssl_ciphers, kind_of: String, default: 'ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH'
attribute :ssl_certificate, kind_of: String
attribute :ssl_certificate_key, kind_of: String
attribute :redirect_base_to, kind_of: [ TrueClass, FalseClass ], default: false
attribute :proxy_intercept_errors, kind_of: [ TrueClass, FalseClass ], default: true
attribute :ip_restricted, kind_of: [ TrueClass, FalseClass ], default: false
attribute :allowed_ips, kind_of: Array
attribute :ip_restrict_msg, kind_of: String, default: "Access to the specified resource has been forbidden.<br/>Contact your Administrator if you believe this is a mistake."
attribute :spigit_only, kind_of: [ TrueClass, FalseClass ], default: false
attribute :maintenance, kind_of: [ TrueClass, FalseClass ], default: false
attribute :maintenance_title, kind_of: String, default: 'Site Maintenance in Progress'
attribute :maintenance_msg, kind_of: String, default: 'Site is offline for scheduled maintence.'
@fujin
Copy link

fujin commented Jul 31, 2014

so set_defaults is kind of weird. it looks like you're generating a value based on another attribute, which is cool, I see that in the resource it has no default value.

using the internal apis _set_or_return() is probably inadvisable. maybe?

you're jamming a lot of deploy-time-state through Chef. I would probably consider using something more suited to adhoc command execution for the Maintenance-related functionality. Enterprise Chef's Pushy tool, Consul or Serfdom, or something more old-school like fab/cap/..

do the bootstrap (create/destroy) w/ chef, leave the app mgmt/deployment up to something designed for running commands based on operator events.

consul.io / https://github.com/hashicorp/envconsul
serfdom.io

the whole provider body is repeating a lot of content (templates). I would maybe consider factoring it into two loops: directories and templates. assign stuff like mode/owner/group to local vars, pull them out of the resource once. refer to the locals in the loop.

yoou've specified why_run enabled without adding any of the functionality (converge_by(), assertions, etc) that are generally associated with it, afaict, because all of the embedded resources are whyrun-supported.

consider using 'use_inline_resources' to trigger new_resource.updated_by_last_action(true) when the sub-resource action fires.

@jasonwbarnett
Copy link
Author

  • I didn't see any way to set an attribute's default value based upon another resource's value (hope that isn't too confusing) so that's why I opted for the set_defaults hack.
  • I am using those internal APIs simply out of not knowing a better option. What do you suggest?
  • I pack a ton of deploy-time-state into Chef because of our app. It's a nightmare, trust me.
  • I'm going to leave the repeated content for now for maintainability.
  • Yeah, I specified whyrun_supported? because I'm using the built-in types that support it. Does this make sense and is there any reason for me to surround my code in converge_by()?
  • So I can specify new_resource.updated_by_last_action(true) multiple times within the action block(s)?

@fujin
Copy link

fujin commented Aug 1, 2014

with 'use_inline_resources' you don't have to litter new_resources.updated_by_last_action(true) to trigger notifications. any of the resources inside of the block will fire the update. I think that's probably what you want. without it 'use_inline_resources', you have to specify it.

you'll want to use converge_by & friends when you are writing/calling custom functionality in the provider blocks, e.g. raw ruby code, libraries.

the rest of your choices are okay. the reason I'm iffy on using the internal LWRP API is they may change at any time (maybe!). that is a decision you are going to have to make.

@jasonwbarnett
Copy link
Author

I had no idea what you meant by use_inline_resources until I just saw this lwrp documentation. Thank you!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment