This commit is contained in:
Jeff Mendoza 2014-01-30 12:06:08 -08:00
Коммит fa1eb2cf58
11 изменённых файлов: 568 добавлений и 0 удалений

220
README.md Normal file
Просмотреть файл

@ -0,0 +1,220 @@
Description
===========
This cookbook provides resources and providers to create an manage
Windows Azure components. Currently supported resources are:
* Storage Accounts ('azure_storage_account')
* Blob Storage Containers ('azure_storage_container')
* SQL Azure Servers ('azure_sql_db_server')
**Note** This cookbook uses the `azure` RubyGem to interact with the
Azure API. This gem requires `nokogiri` which requires compiling
native extensions, which means build tools are required.
Requirements
============
Requires Chef 0.7.10 or higher for Lightweight Resource and Provider
support. Chef 0.8+ is recommended. While this cookbook can be used in
`chef-solo` mode, to gain the most flexibility, we recommend using
`chef-client` with a Chef Server.
A Windows Azure account is required. The Management Certificate and
Subscriptoin ID are used to authenticate with Azure.
Azure Credentials
===============
In order to manage Azure components, authentication credentials need
to be available to the node. There are a number of ways to handle
this, such as node attributes or roles. We recommend storing these in
a databag (Chef 0.8+), and loading them in the recipe where the
resources are needed.
DataBag recommendation:
% knife data bag show azure main
{
"id": "main",
"management_certificate": "YOUR PEM FILE CONTENTS",
"subscription_id": "YOUR SUBSCRIPTION ID"
}
This can be loaded in a recipe with:
azure = data_bag_item("azure", "main")
And to access the values:
azure['management_certificate']
azure['subscription_id']
We'll look at specific usage below.
Recipes
=======
default.rb
----------
The default recipe installs the `azure` RubyGem, which this cookbook
requires in order to work with the Azure API. Make sure that the azure
recipe is in the node or role `run_list` before any resources from
this cookbook are used.
"run_list": [
"recipe[azure]"
]
The `gem_package` is created as a Ruby Object and thus installed
during the Compile Phase of the Chef run.
Resources and Providers
=======================
This cookbook provides three resources and corresponding providers.
## storage_account.rb
Manage Azure Storage Accounts with this resource.
Actions:
* `create` - create a new storage account
* `delete` - delete the specified storage account
Attribute Parameters:
* `management_certificate` - PEM file contents of Azure management
certificate, required.
* `subscription_id` - ID of Azure subscription, required.
* `management_endpoint` - Endpoint for Azure API, defaults to
`management.core.windows.net`.
* `location` - Azure location to create storate account. Either
location or affinity group are required.
* `affinity_group_name` - Affinity group to create account in. Either
location or affinity group are required.
* `geo_replication_enabled` - True or false, defaults to true.
## storage_container.rb
Manage Azure Blob Containers with this resource
Actions:
* `create` - create a new container
* `delete` - delete the specified container
Attribute Parameters:
* `storage_account` - Account to create container in, required.
* `access_key` - Access key for storage account, required.
## sql_db_server.rb
Actions:
* `create` - create a new server. Use the Azure location as the `name`
of the storage account. The server name is autogenerated.
Attribute Parameters:
* `management_certificate` - PEM file contents of Azure management
certificate, required.
* `subscription_id` - ID of Azure subscription, required.
* `management_endpoint` - Endpoint for Azure API, defaults to
`management.database.windows.net`.
* `login` - Desired admin login for db server, required.
* `password` - Desired admin password for db server, required.
* `server_name` - This attribute is set by the provider, and can be
used by consuming recipies.
Usage
=====
The following examples assume that the recommended data bag item has
been created and that the following has been included at the top of
the recipe where they are used.
include_recipe "azure"
azure = data_bag_item("azure", "main")
## azure_storage_accouint
This will create an account named `new-account` in the `West US`
location.
azure_storage_account 'new-account' do
management_certificate azure['management_certificate']
subscription_id azure['subscription_id']
location 'West US'
action :create
end
This will create an account named `new-account` in the existing
`my-ag` affinity group.
azure_storage_account 'new-account' do
management_certificate azure['management_certificate']
subscription_id azure['subscription_id']
affinity_group_name 'my-ag'
action :create
end
## azure_storage_container
This will create a container named `my-node` within the storage
account `my-account`.
azure_storage_container 'my-node' do
storage_account 'my-account'
access_key azure['access_key']
action :create
end
## azure_sql_db_server
This will create a db server in the location `West US` with the login
`admin` and password `password`.
azure_sql_db_server 'West US' do
management_certificate azure['management_certificate']
subscription_id azure['subscription_id']
login 'admin'
password 'password'
action :create
end
Here is an example of how you might retrieve the generated server
name.
file '/etc/db_server_info' do
content lazy {
db2 = resources("azure_sql_db_server[West US]")
"Url: https://#{db2.server_name}.database.windows.net"
}
mode 0600
action :create
end
License and Author
==================
* Author:: Jeff Mendoza (<jemendoz@microsoft.com>)
Copyright (c) Microsoft Open Technologies, Inc.
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.

17
attributes/default.rb Normal file
Просмотреть файл

@ -0,0 +1,17 @@
# Author Jeff Mendoza (jemendoz@microsoft.com)
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
#
# 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['azure']['azure_gem_version'] = "0.6.0"

51
libraries/azure.rb Normal file
Просмотреть файл

@ -0,0 +1,51 @@
# Author Jeff Mendoza (jemendoz@microsoft.com)
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
#
# 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.
#--------------------------------------------------------------------------
module Azure
module Cookbook
def setup_management_service
begin
require 'azure'
rescue LoadError
Chef::Log.error("Missing gem 'azure'. Use the default azure recipe to install it first.")
end
mc = Tempfile.new(['mc', '.pem'])
mc.chmod(0600)
mc.write(new_resource.management_certificate)
mc.close
Azure.configure do |config|
config.management_certificate = mc.path
config.subscription_id = new_resource.subscription_id
config.management_endpoint = new_resource.management_endpoint
end
mc
end
def setup_storage_service
begin
require 'azure'
rescue LoadError
Chef::Log.error("Missing gem 'azure'. Use the default azure recipe to install it first.")
end
Azure.configure do |config|
config.storage_account_name = new_resource.storage_account
config.storage_access_key = new_resource.access_key
end
end
end
end

24
metadata.rb Normal file
Просмотреть файл

@ -0,0 +1,24 @@
# Author Jeff Mendoza (jemendoz@microsoft.com)
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
#
# 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 "azure"
maintainer "Microsoft Open Technologies, Inc."
maintainer_email "jemendoz@microsoft.com"
license "Apache 2.0"
description "LWRPs for managing Azure resources"
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version "0.1.0"
recipe "azure", "Installs the azure gem during compile time"

Просмотреть файл

@ -0,0 +1,42 @@
# Author Jeff Mendoza (jemendoz@microsoft.com)
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
#
# 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.
#--------------------------------------------------------------------------
include Azure::Cookbook
action :create do
mc = setup_management_service
sms = Azure::SqlDatabaseManagementService.new
locs = []
sms.list_servers.each { |srv| locs.push(srv.location) }
if locs.include?(new_resource.location)
Chef::Log.debug("DB in #{new_resource.location} already exists.")
sms.list_servers.each do |srv|
if srv.location == new_resource.location
@new_resource.server_name(srv.name)
end
end
else
Chef::Log.debug("Creating DB in #{new_resource.location}.")
server = sms.create_server(new_resource.login, new_resource.password, new_resource.location)
@new_resource.server_name(server.name)
Chef::Log.debug("Created DB #{server.name}.")
sms.set_sql_server_firewall_rule(server.name, 'chef-node')
end
mc.unlink
end

Просмотреть файл

@ -0,0 +1,56 @@
# Author Jeff Mendoza (jemendoz@microsoft.com)
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
#
# 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.
#--------------------------------------------------------------------------
include Azure::Cookbook
action :create do
mc = setup_management_service
sms = Azure::StorageManagementService.new
if sms.get_storage_account(new_resource.name)
Chef::Log.debug("Storage account #{new_resource.name} already exists.")
else
if new_resource.location.nil? && new_resource.affinity_group_name.nil?
raise "Must provide either location or affinity group."
end
#otherwise create
sa_opts = { :location => new_resource.location,
:affinity_group_name => new_resource.affinity_group_name,
:geo_replication_enabled => new_resource.geo_replication_enabled, };
Chef::Log.debug("Creating storage account #{new_resource.name}.")
sms.create_storage_account(new_resource.name, sa_opts)
end
mc.unlink
end
action :delete do
mc = setup_management_service
sms = Azure::StorageManagementService.new
unless sms.get_storage_account(new_resource.name)
Chef::Log.debug("Storage account #{new_resource.name} already deleted.")
else
#otherwise delete
Chef::Log.debug("Deleting storage account #{new_resource.name}.")
sms.delete_storage_account(new_resource.name)
end
mc.unlink
end

Просмотреть файл

@ -0,0 +1,51 @@
# Author Jeff Mendoza (jemendoz@microsoft.com)
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
#
# 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.
#--------------------------------------------------------------------------
include Azure::Cookbook
action :create do
setup_storage_service
bms = Azure::BlobService.new
cont_names = []
bms.list_containers.each do |cont|
cont_names.push(cont.name)
end
if cont_names.include?(new_resource.name)
Chef::Log.debug("Blob container #{new_resource.name} already exists.")
else
Chef::Log.debug("Creating blob container #{new_resource.name}.")
bms.create_container(new_resource.name)
end
end
action :delete do
setup_storage_service
bms = Azure::BlobService.new
cont_names = []
bms.list_containers.each do |cont|
cont_names.push(cont.name)
end
if cont_names.include?(new_resource.name)
Chef::Log.debug("Deleting blob container #{new_resource.name}.")
bms.delete_container(new_resource.name)
else
Chef::Log.debug("Blob container #{new_resource.name} does not exist.")
end
end

22
recipes/default.rb Normal file
Просмотреть файл

@ -0,0 +1,22 @@
# Author Jeff Mendoza (jemendoz@microsoft.com)
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
#
# 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.
#--------------------------------------------------------------------------
chef_gem 'azure' do
version node['azure']['azure_gem_version']
action :install
end
require 'azure'

Просмотреть файл

@ -0,0 +1,31 @@
# Author Jeff Mendoza (jemendoz@microsoft.com)
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
#
# 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.
#--------------------------------------------------------------------------
actions :create
attribute :management_certificate, :kind_of => String, :required => true
attribute :subscription_id, :kind_of => String, :required => true
attribute :management_endpoint, :kind_of => String, :default => 'https://management.database.windows.net:8443/'
attribute :location, :kind_of => String, :name_attribute => true
attribute :login, :kind_of => String, :required => true
attribute :password, :kind_of => String, :required => true
attribute :server_name, :kind_of => String
def initialize(*args)
super
@action = :create
end

Просмотреть файл

@ -0,0 +1,29 @@
# Author Jeff Mendoza (jemendoz@microsoft.com)
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
#
# 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.
#--------------------------------------------------------------------------
actions :create, :delete
attribute :management_certificate, :kind_of => String, :required => true
attribute :subscription_id, :kind_of => String, :required => true
attribute :management_endpoint, :kind_of => String, :default => 'management.core.windows.net'
attribute :location, :kind_of => String
attribute :affinity_group_name, :kind_of => String
attribute :geo_replication_enabled, :kind_of => [TrueClass, FalseClass], :default => true
def initialize(*args)
super
@action = :create
end

Просмотреть файл

@ -0,0 +1,25 @@
# Author Jeff Mendoza (jemendoz@microsoft.com)
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
#
# 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.
#--------------------------------------------------------------------------
actions :create, :delete
attribute :storage_account, :kind_of => String, :required => true
attribute :access_key, :kind_of => String, :required => true
def initialize(*args)
super
@action = :create
end