<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>Wordpress - Cognizant Transmutation</title>
	<atom:link href="https://www.ibd.com/tag/wordpress/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.ibd.com</link>
	<description>Internet Bandwidth Development: Composting the Internet for over Two Decades</description>
	<lastBuildDate>Thu, 05 Aug 2021 05:45:17 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.1.1</generator>

<image>
	<url>https://i0.wp.com/www.ibd.com/wp-content/uploads/2019/01/fullsizeoutput_7ae8.jpeg?fit=32%2C32&#038;ssl=1</url>
	<title>Wordpress - Cognizant Transmutation</title>
	<link>https://www.ibd.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="https://pubsubhubbub.superfeedr.com"/><atom:link rel="hub" href="https://websubhub.com/hub"/><site xmlns="com-wordpress:feed-additions:1">156814061</site>	<item>
		<title>Deploy WordPress to Amazon EC2 Micro Instance with Opscode Chef</title>
		<link>https://www.ibd.com/howto/deploy-wordpress-to-amazon-ec2-micro-instance-with-opscode-chef/</link>
					<comments>https://www.ibd.com/howto/deploy-wordpress-to-amazon-ec2-micro-instance-with-opscode-chef/#comments</comments>
		
		<dc:creator><![CDATA[Robert J Berger]]></dc:creator>
		<pubDate>Mon, 03 Jan 2011 07:08:16 +0000</pubDate>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Opscode Chef]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[Wordpress]]></category>
		<guid isPermaLink="false">http://blog2.ibd.com/?p=599</guid>

					<description><![CDATA[<p>Updates September 9, 2011 Included the latest Chef Knife ec2 server create argument that sets the EBS Volume to not be deleted on the termination of the EC2 Instance Intro Up until recently a friend lent me a Virtual Machine in he Cloud for my Blog. I didn&#8217;t have to do anything to manage it. But his company is no&#8230;</p>
<p>The post <a href="https://www.ibd.com/howto/deploy-wordpress-to-amazon-ec2-micro-instance-with-opscode-chef/">Deploy WordPress to Amazon EC2 Micro Instance with Opscode Chef</a> first appeared on <a href="https://www.ibd.com">Cognizant Transmutation</a>.</p>]]></description>
										<content:encoded><![CDATA[<h2>Updates</h2>
<h3>September 9, 2011</h3>
<p>Included the latest Chef Knife ec2 server create argument that sets the EBS Volume to not be deleted on the termination of the EC2 Instance</p>
<h2>Intro</h2>
<p>Up until recently a friend lent me a Virtual Machine in he Cloud for my Blog. I didn&#8217;t have to do anything to manage it. But his company is no longer supporting those machines so I had to move my blog.<br />
Right around that time Amazon announced their Micro Instances at a very low price. I also wanted to try out the new Opscode Chef knife commands that bootstrap an EC2 instance from scratch as well as their Chef Server SaaS. So this was a good reason to combine all these to create my new Blog Instance. And now Amazon even offers the ability to have a single micro instance free for a year! (You still have to pay for I/O charges but they are really cheap compared to the instance charges, unless you have a blog that is too popular, but then you&#8217;ll need a bigger server anyway)<br />
<strong>Spoiler Alert:</strong> It was way too easy and no problem at all! (Though I did end up having to write a few support cookbooks like <em>vsftpd</em>, but now you don&#8217;t have to)</p>
<h3>Some Assumptions for this post</h3>
<ul>
<li>You are using a *nix platform for your local development (ie your laptop is a Mac, Linux, *BSD or equivalent) and that your target server you want to deploy to is a relatively recent Ubuntu Linux.</li>
<li>You have or will install git client on your local development box</li>
<li>You followed the directions or have done the equivalent of the instructions in the Opscode <a href="http://help.opscode.com/faqs/start/how-to-get-started" target="_blank" rel="noopener">How to Get Started</a> pages as noted below</li>
</ul>
<h2>Set up an Account on Amazon Web Services</h2>
<p>If you don&#8217;t already have an Amazon EC2 Account, go to the <a href="http://aws.amazon.com/" target="_blank" rel="noopener">Amazon Web Services</a> page and click on the <a href="http://www.amazon.com/gp/aws/registration/registration-form.html" target="_blank" rel="noopener">Sign Up Now button</a>. Create all your user info and then Sign Up for Amazon EC2. You&#8217;ll need to put in  credit card info at this point since you&#8217;ll need to pay for the EC2 instance you&#8217;ll be using shortly. After you complete your signup, you&#8217;ll need to get your credentials at the <a href="http://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key" target="_blank" rel="noopener">AWS Security Credentials page</a>.  Copy down your Access Key ID and click on Show under the Secret Access Key and get that as well. You will need these values to put into your knife.rb file that you will get to in the following steps.</p>
<h2>Get an Opscode Platform Account</h2>
<p>Its free and easy. Just go to the <a href="https://cookbooks.opscode.com/users/new" target="_blank" rel="noopener">Opscode Platform Signup page</a>. Fill in your information and submit. There is no cost for up to 5 client nodes. Once you set up and confirm your account you can go thru the <a href="http://help.opscode.com/faqs/start/how-to-get-started" target="_blank" rel="noopener">How to Get Started</a> pages which includes how to set up your client development machine (installing Chef Client, Knife and various dependencies) as well as downloading your private key, organization key and your Knife Configuration File. You should go thru all 5 steps of the Getting Started section. And please do follow their examples of using git. The rest of this post assumes you have git installed and will use it for your own repository even if you don&#8217;t push it to an upstream git repository.</p>
<p>Once you have completed that you will be ready to use the remaining steps of this blog post. The remaining steps will assume you put your chef-repo in the same location as the Opscode instructions suggested (~/chef-repo). If you put it somewhere else, just adjust your path to your chef-repo as appropriate.</p>
<p>It also assumes you got your private user key (<em>your_user_name.pem</em>) and organization validator key (<em>your_organization-validator.pem</em>) and knife.rb in Section 3 of How to Get Started: <a href="http://help.opscode.com/faqs/start/chef-client" target="_blank" rel="noopener">Setting Up a Chef Client</a>. In that section you ran the command <code>knife configure client ./client-config</code> inside your ~/chef-repo/ directory. That will have created ~/chef-repo/.chef and put the keys and knife.rb in that directory.</p>
<p>For the use of this blog post, we will use the username: <em>rberger_test</em> and organization name: <em>install_wordpress</em>. So the private user key name for this example will be: <em>rberger_test.pem</em> and the organization validator key will be called <em>install_wordpress-validator.pem.</em> You should copy your keys someplace that you will not loose outside of ~/chef-repo. There are ways to <a title="Create a new private user key" href="http://help.opscode.com/faqs/account/getting-a-new-private-key-for-your-opscode-user" target="_blank" rel="noopener">create new ones</a>, but its always easier not to have to. Bottom line, is its expected that your keys and the knife.rb will be in your <em>~/chef-repo/.chef </em>directory at this point.</p>
<h2>Set up your Development Environment</h2>
<p>Your development environment is your home or work computer/laptop. Its the machine that is local to you. It is on this machine that you put together your Cookbooks. From here you push your cookbooks to the Opscode Chef Server, issue the commands to configure AWS and launch your AWS instances.</p>
<h3>Tweak up your chef-repo</h3>
<p>I like to keep the &#8220;standard&#8221; chef recipes that get downloaded from git or from cookbook.opscode.com in their own directory (called <em>cookbooks</em>) and all the cookbooks I create or highly modify in another directory (<em>site-cookbooks</em>). In Step 2 of the How to Get Started: <a href="http://help.opscode.com/faqs/start/user-environment" target="_blank" rel="noopener">Setting Up Your User Environment</a>, they had you create a <em>~/chef-repo</em> directory and populate it from git or from a tar ball. You should add the <em>site-cookbooks</em> directory to your <em>~/chef-repo</em>. We&#8217;re also going to add an empty <em>README.md</em> to the <em>site-cookbooks </em>directory so when we create our own git repository that directory will be there (an empty directory will not be added to a git repository)</p>
<pre><pre class="brush: bash; title: ; notranslate">
cd ~/chef-repo
mkdir site-cookbooks
echo &quot;Directory for customized cookbooks&quot; &amp;amp;gt; site-cookbooks/README.md
</pre>
<p>You will probably also not want to include your <em>.chef </em>directory with all your keys in what gets uploaded to any outside chef repository. If you are just keeping things local, you can skip this step. Edit <em>~/chef-repo/.gitignore</em> and add .<em>chef </em>to the file on its own line. You might also want to add <em>client-config</em> to <em>.gitignore</em> as well as any temporary or backup file suffixes you might have. For instance if you use Emacs, you would add <em>~*</em> (emacs backup files suffix), the .DS_Store which is something left by the Mac filesystem,  .rake_test_cache which is left around by Rake and metadata.json which is a file generated by chef. My <em>.gitignore</em> looks like:</p>
<pre><pre class="brush: bash; title: ; notranslate">
.chef
client-config
*~
.DS_Store
.rake_test_cache
metadata.json
</pre>
<p>If you created the <em>~chef-repo</em> from the git clone of the Opscode repository, you&#8217;ll want to get rid of the git configuration and history from the cloning of the Opscode chef-repo and create your own git repository:</p>
<pre><pre class="brush: bash; title: ; notranslate">
rm -rf .git
git init
git add -A
git commit -a -m &quot;Created my own basic chef-repo&quot;
</pre>
<p>The above commands will have removed the old git config that came when you did the git clone <em>http://github.com/opscode/chef-repo.git</em> command as part of the Opscode <a href="http://help.opscode.com/faqs/start/how-to-get-started" target="_blank" rel="noopener">How to Get Started</a> pages. The git init, add and commit will create a new local git repository for your own use not connected to the opscode repository. You can then add a remote repository if you want to be able to push your repository and future changes to another git repository such as github.com.</p>
<h3>Updating your knife.rb file with Amazon Credentials</h3>
<p>Add the following lines to the end of your ~/chef-repo/.chef/knife.rb file. You should have gotten your AWS Access Key and Secret Access key when you signed up to Amazon Web Services, but you can always go back and get it at <a href="http://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key" target="_blank" rel="noopener">AWS Security Credentials page</a>. Your final knife.rb should look something like this, except the various items that are customized to your setup. In the example below <em>rberger_test</em> would be replaced by your Opscode User name and <em>install_wordpress</em> would be replaced by your Opscode Organization name that was used when you went thru the Section 3 of the Opscode How to Get Started: <a href="http://help.opscode.com/faqs/start/chef-client" target="_blank" rel="noopener">Setting Up a Chef Client</a>.</p>
<pre><pre class="brush: ruby; highlight: [12,13]; title: ; notranslate">
current_dir = File.dirname(__FILE__)
log_level                :info
log_location             STDOUT
node_name                &quot;rberger_test&quot;
client_key               &quot;#{current_dir}/rberger_test.pem&quot;
validation_client_name   &quot;install_wordpress-validator&quot;
validation_key           &quot;#{current_dir}/install_wordpress-validator.pem&quot;
chef_server_url          &quot;https://api.opscode.com/organizations/install_wordpress&quot;
cache_type               'BasicFile'
cache_options( :path =&amp;amp;gt; &quot;#{ENV['HOME']}/.chef/checksums&quot; )
cookbook_path            [&quot;#{current_dir}/../cookbooks&quot;,&amp;amp;nbsp;&quot;#{current_dir}/../site-cookbooks&quot;]
knife[:aws_access_key_id]     = &quot;Your Access Key&quot;
knife[:aws_secret_access_key] = &quot;Your Secret Access Key&quot;
</pre>
<p>You can test that your knife.rb is setup enough to access AWS by issuing the command</p>
<pre><pre class="brush: bash; title: ; notranslate">knife ec2 server list</pre>
<p>And you should see something like this (just the heading and no instances unless you&#8217;ve launched some EC2 instances earlier:</p>
<pre><pre class="brush: bash; title: ; notranslate">
Instance ID &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;Public IP &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;Private IP &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; Flavor &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;Image &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;Security Groups &amp;amp;nbsp;State
</pre>
<h3>Get the Appropriate Cookbooks</h3>
<p>We&#8217;ll get cookbooks using the <a href="http://wiki.opscode.com/display/chef/Knife" target="_blank" rel="noopener">knife command</a> and the <a href="http://cookbooks.opscode.com/" target="_blank" rel="noopener">cookbooks.opscode.com</a> web service. We&#8217;ll be using the following cookbooks:</p>
<ul>
<li>chef</li>
<li>apache2</li>
<li>mysql</li>
<li>openssl</li>
<li>php</li>
<li>postfix</li>
<li>sudo</li>
<li>users</li>
<li>vsftpd</li>
<li>wordpress</li>
</ul>
<p>Use the knife command on your local development machine to pull down the cookbooks you need. The command we&#8217;re using (knife cookbook site vendor COOKBOOK) will automatically download the cookbooks and install them in the ~/chef-repo/cookbooks directory. It will also check them into your git repository as a vendor branch (Stay on the master branch at least until you have installed all the cookbooks).</p>
<pre><pre class="brush: bash; title: ; notranslate">
cd ~/chef-repo
knife cookbook site vendor chef -d
knife cookbook site vendor apache2 -d
knife cookbook site vendor mysql -d
knife cookbook site vendor openssl -d
knife cookbook site vendor php -d
knife cookbook site vendor postfix -d
knife cookbook site vendor sudo -d
knife cookbook site vendor users -d
knife cookbook site vendor vsftpd -d
knife cookbook site vendor wordpress -d
</pre>
<p>Those commands will download all the cookbooks and any other cookbook dependencies they may have into your ~/chef-repo/cookbooks directory and check each one in as a git branch in your repo. If you do an ls on your ~/chef-repo/cookbooks directory you should see:</p>
<pre><pre class="brush: plain; title: ; notranslate">
README.md &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; bluepill &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;couchdb &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; java &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;php &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; runit &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; users &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; xml
apache2 &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; build-essential daemontools &amp;amp;nbsp; &amp;amp;nbsp; mysql &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; postfix &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; sudo &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;vsftpd &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;zlib
apt &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; chef &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;erlang &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;openssl &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; rabbitmq_chef &amp;amp;nbsp; ucspi-tcp &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; wordpress
</pre>
<p>And if you do a git branch you should see your master branch as the current and a chef-vendor- for each of the cookbooks you installed:</p>
<pre><pre class="brush: plain; title: ; notranslate">
  chef-vendor-apache2
  chef-vendor-apt
  chef-vendor-bluepill
  chef-vendor-build-essential
  chef-vendor-chef
  chef-vendor-couchdb
  chef-vendor-daemontools
  chef-vendor-erlang
  chef-vendor-java
  chef-vendor-mysql
  chef-vendor-openssl
  chef-vendor-php
  chef-vendor-postfix
  chef-vendor-rabbitmq_chef
  chef-vendor-runit
  chef-vendor-sudo
  chef-vendor-ucspi-tcp
  chef-vendor-users
  chef-vendor-vsftpd
  chef-vendor-wordpress
  chef-vendor-xml
  chef-vendor-zlib
* master
</pre>
<p>If you ever want to update these standard cookbooks,  you can just redo the <code>knife cookbook site vendor Cookbook</code> command.</p>
<h2>Create site-cookbooks to extend standard cookbooks</h2>
<p>It is standard practice to put the official cookbooks in the <em>~chef-repo/cookbooks</em> directory, as we just did in the previous step. Any cookbook overrides, extensions or custom cookbooks go into the <em>~chef-repo/site-cookbooks</em> directory. If you create a cookbook directory in ~chef-repo/site-cookbooks with the same name as a cookbook in the <em>~chef-repo/cookbooks</em> directory, the files, templates and/or recipes in the <em>~chef-repo/site-cookbook</em> directory will override the matching files, templates and/or recipes in the cookbook of the same name in the <em>~chef-repo/cookbooks</em> directory. We will now extend two of the cookbooks; users and wordpress.</p>
<h3>Extend the Sudo cookbook so its suitable for EC2</h3>
<p>The standard sudo cookbook creates a sudoers file that requires passwords to activate sudo. Most EC2 environments do not allow passwords for logins and require that you login only with ssh keys. So we need to modify the Sudo cookbook to create the sudoers file with the NOPASSWORD flag set for all the users we want to have sudo powers. We just need to override the template file used in the standard sudo cookbook.</p>
<p>First have to make a directory for the new template in your site-cookbooks directory:</p>
<pre><pre class="brush: plain; title: ; notranslate">
mkdir -p site-cookbooks/sudo/templates/default
</pre>
<p>Copy the following into site-cookbooks/sudo/templates/default/sudoers.erb:</p>
<pre><pre class="brush: plain; title: ; notranslate">
#
# /etc/sudoers
#
# Generated by Chef for
#

Defaults !lecture,tty_tickets,!fqdn

# User privilege specification
root  ALL=(ALL) ALL

 ALL=(ALL) NOPASSWD:ALL

# Members of the sysadmin group may gain root privileges
%sysadmin ALL=(ALL) NOPASSWD:ALL

# Members of the group '' may gain root privileges
% ALL=(ALL) NOPASSWD:ALL

</pre>
<h3>Fix a bug in the latest version of the Standard Mysql Cookbook</h3>
<p>As I was writing this post, Opscode came out with a new version of the Mysql Cookbook that seems to have a bug with the Chef Client version 0.9.12. It may be fixed by the time you read this. If you are running Chef 0.9.12, check for line 59 of cookbooks/mysql/recipes/client.rb. Change</p>
<pre><pre class="brush: plain; title: ; notranslate">
if platform_version.to_f &amp;amp;gt;= 5.0
</pre>
<p>to:</p>
<pre><pre class="brush: plain; title: ; notranslate">
if node.platform_version.to_f &amp;amp;gt;= 5.0
</pre>
<h3>Extend the WordPress cookbook to do some custom actions</h3>
<p>We need to do a few custom actions after we install wordpress. The main one being to change the onwnership of the wordpress directory and most of the files to the user blog.</p>
<p>We need to add a user named <em>blog</em> that has its home directory the same as the wordpress directory. We will use this <em>blog</em> user to do automatic updates to wordpress. It will use vsftpd for secure ftp and will have only access to the wordpress directory.</p>
<p>We also need to add a swap file to the server. We could create a new cookbook to hold this as its not really wordpress related, but because this is such a simple system, we will just add a new recipe to wordpress to handle these miscellaneous actions.</p>
<h4>Create a recipe to add the blog user and change ownership of the wordpress directory</h4>
<p>First make the directories in site-cookbooks for extending the wordpress cookbook:</p>
<pre><pre class="brush: plain; title: ; notranslate">
mkdir -p site-cookbooks/wordpress/recipes
mkdir -p site-cookbooks/wordpress/attributes
mkdir -p site-cookbooks/wordpress/templates/default
</pre>
<p>Create and edit the file site-cookbooks/wordpress/attributes/wordpress.rb and put the following in it (note, this must have a different name than the one used in the standard wordpress cookbook templates directory):</p>
<pre><pre class="brush: plain; title: ; notranslate">
default[:wordpress][:blog_updater][:username] = &quot;blog&quot;

::Chef::Node.send(:include, Opscode::OpenSSL::Password)

default[:wordpress][:blog_updater][:password] = secure_password
# hash set by recipe or manually using makepasswd
default[:wordpress][:blog_updater][:hash] = nil

# For creating the swap partition. Swap_size is in GB
default[:wordpress][:gb_swap_size] = 2
default[:wordpress][:swap_file] = &quot;/swap_file&quot;
</pre>
<p>This will set the <em>[:wordpress][:blog_updater]</em> to be the name &#8220;blog&#8221;. This is the default for the username that will have the ability to use vsftpd to update wordpress and its plugins. We actually override this in the wordpress.rb role file. But we put a default here as well for good practice (ie. the cookbook will work even if someone doesn&#8217;t override the value in a role).</p>
<p>The <em>::Chef::Node.send(:include, Opscode::OpenSSL::Password)</em> line is there so we can use the Chef mechanism to create an auto-generated password (<em>secure_password</em>). We then use that mechanism to set the default password for the <em>blog_updater</em>.</p>
<p>Create and edit site-cookbooks/wordpress/recipes/blog_user.rb. put the following as the contents:</p>
<pre><pre class="brush: plain; title: ; notranslate">
# Get the password cryptographic hash for node[:wordpress][:blog_updater][:password
package &quot;makepasswd&quot;
package &quot;libshadow-ruby1.8&quot;
if node[:wordpress][:blog_updater][:hash].nil? || node[:wordpress][:blog_updater][:hash].empty?
  cmd = &quot;echo #{node[:wordpress][:blog_updater][:password]} | /usr/bin/makepasswd --clearfrom=- --crypt-md5 |awk '{ print $2 }'&quot;
  ruby_block &quot;create_blog_updater_pw&quot; do
    block do
      node.set[:wordpress][:blog_updater][:hash] = `#{cmd}`.chomp
    end
    action :create
  end
end

# Create the blog_updater user with their home directory being the wordpress directory and the group as the same group as the Apache runtime group
user &quot;#{node[:wordpress][:blog_updater][:username]}&quot; do
  home &quot;#{node[:wordpress][:dir]}&quot;
  gid &quot;#{node[:apache][:user]}&quot;
  shell &quot;/bin/bash&quot;
  supports :manage_home =&amp;amp;gt; true
  unless node[:wordpress][:blog_updater][:hash].nil? || node[:wordpress][:blog_updater][:hash].empty?
    password &quot;#{node[:wordpress][:blog_updater][:hash]}&quot;
  end
end

# Change the ownership of the wordpress directory so that the blog user can update
execute &quot;chown wordpress home for blog user&quot; do
  cwd &quot;#{node[:wordpress][:dir]}&quot;
  user &quot;root&quot;
  command &quot;chown -R #{node[:wordpress][:blog_updater][:username]}:#{node[:apache][:user]} #{node[:wordpress][:dir]}&quot;
  not_if { node[:wordpress][:dir].nil? || node[:wordpress][:dir].empty? || (not File.exists?(node[:wordpress][:dir])) }
end
</pre>
<p>The above code will create the blog_user as a Linux user on the target system and set its home directory to be the wordpress directory. This is to make it work with vsftpd.</p>
<h4>Create a template to override the default wordpress apache config</h4>
<p>The standard WordPress cookbook sets the Apache Server Name the FQDN of the EC2 Public DNS and sets the Server Aliases to the EC2 FQDN Private DNS name. This is pretty useless. We would like to have the cookbook set the Server Alias to the FQDN&#8217;s based on our own DNS names. To do this without overriding the whole standard WordPress cookbook, we can override one template and name it: <em>site-cookbooks/wordpress/templates/default/wordpress.conf.erb</em>.</p>
<pre><pre class="brush: plain; title: ; notranslate">

  ServerName
  ServerAlias
  DocumentRoot

  &amp;amp;gt;
    Options FollowSymLinks
    AllowOverride FileInfo
    Order allow,deny
    Allow from all

    Options FollowSymLinks
    AllowOverride None

  LogLevel info
  ErrorLog /-error.log
  CustomLog /-access.log combined

  RewriteEngine On
  RewriteLog /-rewrite.log
  RewriteLogLevel 0

</pre>
<p>The key changes are the ServerAlias line where we now add the <code>@node[:wordpress][:server_aliases]</code> will add any aliases specified by this attribute which we set in the wordpress.rb role file. We also change the AllowOverride to FileInfo for the docroot</p>
<h4>Create a recipe to add a swap file to the server</h4>
<p>The t1.micro instance only has 612MB of RAM. You can easily run out of that with a WordPress blog. So we have a recipe to add a swap file system utilizing some space the EBS  disk Volume. This recipe creates a 2GB file called /swap_file  using dd and then uses the mkswap and swapon commands to make that file into a swap partition. The recipe also updates the /etc/fstab file so that the swap file will be mounted again if the instance reboots.</p>
<p>Create and edit the file site-cookbooks/wordpress/recipes/add_swap.rb with the following content:</p>
<pre><pre class="brush: plain; title: ; notranslate">
mb_block_size = 100
count = (node[:wordpress][:gb_swap_size] * 1024) / mb_block_size
bash &quot;add_swap&quot; do
  user &quot;root&quot;
  code &amp;amp;lt; &quot;#{node[:wordpress][:swap_file]}&quot;
  )
end
</pre>
<p>Create and edit the file site-cookbooks/wordpress/templates/default/fstab.erb and put the following content:</p>
<pre><pre class="brush: plain; title: ; notranslate">
# /etc/fstab: static file system information.
#
proc                   /proc           proc   nodev,noexec,nosuid     0       0
      none            swap   sw                      0       0
/dev/sda1              /               ext3   defaults                0       0
/dev/sda2              /mnt            auto   defaults,nobootwait,comment=cloudconfig 0       0
</pre>
<h3>Create WordPress Role</h3>
<p>This example will use a single role named <em>wordpress</em>. Use your favorite editor to create a file in your repo with the path roles/wordpress.rb with the following contents (Substitute your domain for ibd.com and change the hostnames such as test and wordpress-test to names appropriate for your blog. Replace <em>rberger_test </em>with the userid you want to use to log into your server via ssh):</p>
<pre><pre class="brush: ruby; title: ; notranslate">
name &quot;wordpress&quot;
description &quot;Blog using wordpress&quot;
recipes &quot;apt&quot;, &quot;build-essential&quot;, &quot;chef::client_service&quot;, &quot;users::sysadmins&quot;,
        &quot;sudo&quot;, &quot;postfix&quot;, &quot;mysql::server&quot;, &quot;wordpress&quot;, &quot;wordpress::blog_user&quot;,
        &quot;wordpress::add_swap&quot;, &quot;vsftpd&quot;

override_attributes(
  &quot;postfix&quot; =&amp;amp;gt; {&quot;myhostname&quot; =&amp;amp;gt; &quot;test.ibd.com&quot;, &quot;mydomain&quot; =&amp;amp;gt; &quot;ibd.com&quot;},
  &quot;authorization&quot; =&amp;amp;gt; {
    &quot;sudo&quot; =&amp;amp;gt; {
      &quot;groups&quot; =&amp;amp;gt; [],
      &quot;users&quot; =&amp;amp;gt; [&quot;rberger_test&quot;, &quot;ubuntu&quot;]
    }
  },
  &quot;wordpress&quot; =&amp;amp;gt; {
     &quot;server_aliases&quot; =&amp;amp;gt; %w(test.ibd.com wordpress-test.ibd.com),
     &quot;version&quot; =&amp;amp;gt; &quot;3.0.4&quot;,
     &quot;checksum&quot; =&amp;amp;gt; &quot;c68588ca831b76ac8342d783b7e3128c9f4f75aad39c43a7f2b33351634b74de&quot;,
     &quot;blog_updater&quot; =&amp;amp;gt; {
       &quot;username&quot; =&amp;amp;gt; &quot;blog&quot;,
       &quot;password&quot; =&amp;amp;gt; &quot;big-secret&quot;
     }
   },
   &quot;vsftpd&quot; =&amp;amp;gt; {&quot;chroot_users&quot; =&amp;amp;gt; %w(blog)}
)
</pre>
<p>The recipes line will be used to determine which cookbook/recipes (order is important) should be loaded by Chef when the chef-client is run on your new server.</p>
<ul>
<li><strong>apt: </strong>Configures various APT components on Debian-like systems.</li>
<li><strong>build-essential: </strong>Installs C compiler / build tools</li>
<li><strong>chef::client_service:</strong> Sets up a Chef client daemon to run periodically</li>
<li><strong>users::sysadmins:</strong> Creates users with ssh authorized keys. Requires a databag to be configured with users info</li>
<li><strong>sudo:</strong> Installs sudo and configures the /etc/sudoers file</li>
<li><strong>postfix: </strong>Installs and configures postfix for outgoing email</li>
<li><strong>mysql::server: </strong>Installs &amp; configures packages required for mysql servers</li>
<li><strong>wordpress:</strong> Installs and configures WordPress according to the instructions at http://codex.wordpress.org/Installing_WordPress</li>
<li><strong>wordpress::blog_user:</strong> Custom add-on recipe to add a user named &#8220;blog&#8221; to use with vsftpd for automatic wordpress and plugin updates</li>
<li><strong>wordpress::add_swap:</strong> Custom add-on recipe to add a swap partition to the instance</li>
<li><strong>vsftpd:</strong> Very Basic installation and configuration of vsftpd to support Secure (SSL) SFTP</li>
</ul>
<p>The <em>override_attributes</em> are used to configure various cookbooks.</p>
<ul>
<li><strong>postfix</strong> &#8211; Parameters for the postfix cookbook. Mainly sets the host and domain name to be meaningful</li>
<li><strong>authorization</strong> &#8211; Configures the sudo cookbook. Tells which users and groups should have sudo capability</li>
<li><strong>wordpress </strong>Some of these override values in the base cookbook and others for the site-cookbook version
<ul>
<li><strong>server-aliases</strong> &#8211; Sets aliases for the blog name. Will be used as serveralias names in the apache config.</li>
<li><strong>version</strong> &#8211; The version of wordpress to download.</li>
<li><strong>checksum</strong> &#8211; The checksum of the tar image of the wordpress download.</li>
<li><strong>blog_updater</strong>&#8211; Info needed to create a user that will do auto updates to wordpress via vsftps
<ul>
<li><strong>username</strong> &#8211; The username of the user</li>
<li><strong>password</strong> &#8211; The password to create for the user</li>
</ul>
</li>
</ul>
</li>
<li><strong>vsftpd</strong> &#8211; Sets what user should be allowed to access via ftp and have their home directory chroot&#8217;d (should be the same as wordpress-blog_updater).</li>
</ul>
<h3>Upload the cookbooks and roles to Opscode Chef Platform</h3>
<p>Run the following commands while you are in ~/chef-repo. This will upload the wordpress role and all the cookbooks in your chef-repo to your account on the Opscode Chef Platform:</p>
<pre><pre class="brush: plain; title: ; notranslate">
knife role from file roles/wordpress.rb
knife cookbook upload -a
</pre>
<h3>Create the Users databag</h3>
<p>The <em>users</em> <em>cookbook</em> will take info from Opscode Chef Server Data Bag names <em>users</em>. There can be an item for each user that you want to create a login for. The standard Opscode <em>users cookbook </em>expects the users set up in the data bags to be in the group sysadmin and have the ability to sudo and gain root powers.</p>
<p>We&#8217;ll need to create an item for each user you would like to have on your system. I suggest you make at least one for yourself. Here is the data bag I used for my setup. I don&#8217;t show the ssh key. You&#8217;ll have to substitute your own public ssh key for &lt;<em>your public ssh key&gt;</em> that you will use to ssh to the server. Its a requirement that you have an ssh key as described in the next section on the <em>sudo</em> <em>cookbook</em>.</p>
<p>Here is the JSON representation of my user data bag item. Create a directory users in ~/chef-repo/data_bags/users and put the following JSON in the file ~/chef-repo/users/.json (where is the username you want to have on the target system. The id will be the name of the item in the data bag and what will become your username  (in this case <em>rberger_test</em>) You will also need to include the public ssh key you want associated with this user. You will need to have created a ssh keypair (private and public) locally using something like ssh-keygen. You don&#8217;t really need the openid. You should be able to set that to an empty string (&#8220;&#8221;):</p>
<pre><pre class="brush: plain; title: rberger_test.json; notranslate">
{
  &quot;id&quot;: &quot;rberger_test&quot;,
  &quot;comment&quot;: &quot;Robert J. Berger&quot;,
  &quot;uid&quot;: 2001,
  &quot;groups&quot;: &quot;sysadmin&quot;,
  &quot;shell&quot;: &quot;/bin/bash&quot;,
  &quot;openid&quot;: &quot;rberger_test.myopenid.com&quot;,
  &quot;ssh_keys&quot;: &quot;&quot;
}
</pre>
<p>You will need to create the users databag and then upload your version of the user JSON (rberger_test.json in the example) to the Chef server with the following commands:</p>
<pre><pre class="brush: plain; title: ; notranslate">
knife data bag create users
knife data bag from file users data_bags/users/rberger_test.json
</pre>
<p>With Amazon EC2 instances its best to only allow access without passwords using ssh keys. Since the login is protected by ssh keys, and you don&#8217;t have passwords associated with the users, you need to make sure sudo is set up to allow invoking sudo for specific users (sysadmins) without a password. The users cookbook creates such a user based on the users data bag. But the sudo cookbook does not set up sudoers to support not having password. We will modify the sudoers.erb template later. Make sure you don&#8217;t deploy without this modification as the default sudo cookbook will make it impossible to sudo on an EC2 instance after its run.</p>
<h2>Configure AWS</h2>
<p>You can do most of the following by using the a GUI web app such as <a href="https://console.aws.amazon.com/ec2/home" target="_blank" rel="noopener">Amazon&#8217;s AWS console</a>, the Firefox plugin <a href="http://aws.amazon.com/developertools/609?_encoding=UTF8&amp;jiveRedirect=1" target="_blank" rel="noopener">ElasticFox</a> other such GUI  tools or the command line <a href="http://aws.amazon.com/developertools/351?_encoding=UTF8&amp;queryArg=searchQuery&amp;x=0&amp;fromSearch=1&amp;y=0&amp;searchPath=developertools&amp;searchQuery=ec2-api-tools" target="_blank" rel="noopener">ec2-api-tools</a>. For now, we&#8217;ll show how to do this with the Amazon AWS Console.</p>
<h3>Set up Security Group</h3>
<p>Add a WordPress group, that enables  ssh, http and https. You should open at least http and https to all IP addresses (represented by Source IP: 0.0.0.0/0) You can decide to open up ssh to every IP or just to your own development network or host. In this example we&#8217;ll open it up to the world. Note: by default ping (ICMP) is not enabled so you can not ping your instance. You can enable ping by adding a line where it doesn&#8217;t matter what is in Connection Method, Protocol is ICMP, From Port and To Port is set to -1 and Source IP is 0.0.0.0/0.</p>
<p><img decoding="async" loading="lazy" class="alignleft wp-image-686 size-medium" title="AWS Management Console Security Group" src="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/AWS-Management-Console-Security-Group-300x223.jpg?resize=300%2C223" alt="" width="300" height="223" srcset="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/AWS-Management-Console-Security-Group.jpg?resize=300%2C223&amp;ssl=1 300w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/AWS-Management-Console-Security-Group.jpg?resize=150%2C111&amp;ssl=1 150w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/AWS-Management-Console-Security-Group.jpg?resize=400%2C298&amp;ssl=1 400w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/AWS-Management-Console-Security-Group.jpg?w=816&amp;ssl=1 816w" sizes="(max-width: 300px) 100vw, 300px" data-recalc-dims="1" /></p>
<figure id="attachment_687" aria-describedby="caption-attachment-687" style="width: 300px" class="wp-caption aligncenter"><img decoding="async" loading="lazy" class="wp-image-687 size-medium" title="Enter Security Group Name" src="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Enter-Security-Group-Name-300x171.jpg?resize=300%2C171" alt="" width="300" height="171" srcset="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Enter-Security-Group-Name.jpg?resize=300%2C171&amp;ssl=1 300w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Enter-Security-Group-Name.jpg?resize=150%2C85&amp;ssl=1 150w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Enter-Security-Group-Name.jpg?resize=400%2C228&amp;ssl=1 400w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Enter-Security-Group-Name.jpg?w=541&amp;ssl=1 541w" sizes="(max-width: 300px) 100vw, 300px" data-recalc-dims="1" /><figcaption id="caption-attachment-687" class="wp-caption-text">Enter the name and description of the Security Group</figcaption></figure>
<figure id="attachment_688" aria-describedby="caption-attachment-688" style="width: 300px" class="wp-caption alignleft"><img decoding="async" loading="lazy" class="wp-image-688 size-medium" title="Setting ports" src="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Setting-ports-300x184.jpg?resize=300%2C184" alt="" width="300" height="184" srcset="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Setting-ports.jpg?resize=300%2C184&amp;ssl=1 300w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Setting-ports.jpg?resize=150%2C92&amp;ssl=1 150w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Setting-ports.jpg?resize=400%2C245&amp;ssl=1 400w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Setting-ports.jpg?w=986&amp;ssl=1 986w" sizes="(max-width: 300px) 100vw, 300px" data-recalc-dims="1" /><figcaption id="caption-attachment-688" class="wp-caption-text">Set the Ports that are to be enabled (Select the Connection Method, enter the Source IP, and click Save)</figcaption></figure>
<h3>Generate an SSH Key Pair for accessing your instance[s]</h3>
<p>You need to use the Amazon Key Pair generator to generate a key that will be used to make initial ssh connections to your new instances after they are created. You can also do this on the AWS <span style="font-size: 15.6px;">Management Console&#8217;s EC2 Key Pairs page:</span></p>
<figure id="attachment_694" aria-describedby="caption-attachment-694" style="width: 300px" class="wp-caption aligncenter"><img decoding="async" loading="lazy" class="wp-image-694 size-medium" title="AWS Management Console Key Pairs" src="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/AWS-Management-Console-300x175.jpg?resize=300%2C175" alt="" width="300" height="175" srcset="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/AWS-Management-Console.jpg?resize=300%2C175&amp;ssl=1 300w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/AWS-Management-Console.jpg?resize=150%2C87&amp;ssl=1 150w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/AWS-Management-Console.jpg?resize=400%2C234&amp;ssl=1 400w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/AWS-Management-Console.jpg?w=894&amp;ssl=1 894w" sizes="(max-width: 300px) 100vw, 300px" data-recalc-dims="1" /><figcaption id="caption-attachment-694" class="wp-caption-text">Navigate to the Key Pairs page and click on Create Key Pair</figcaption></figure>
<p>You can name the key pair anything, but you may want to use this key pair to access this and future instances, so you might want to name it something general like aws-east. Here we&#8217;re going to name it something more specific: aws-wordpress just for this example.</p>
<figure id="attachment_695" aria-describedby="caption-attachment-695" style="width: 300px" class="wp-caption alignleft"><img decoding="async" loading="lazy" class="wp-image-695 size-medium" title="Create Key Pair naming" src="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Create-Key-Pair-naming-300x183.jpg?resize=300%2C183" alt="" width="300" height="183" srcset="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Create-Key-Pair-naming.jpg?resize=300%2C183&amp;ssl=1 300w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Create-Key-Pair-naming.jpg?resize=150%2C91&amp;ssl=1 150w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Create-Key-Pair-naming.jpg?w=354&amp;ssl=1 354w" sizes="(max-width: 300px) 100vw, 300px" data-recalc-dims="1" /><figcaption id="caption-attachment-695" class="wp-caption-text">Enter the name for the key</figcaption></figure>
<figure id="attachment_697" aria-describedby="caption-attachment-697" style="width: 300px" class="wp-caption alignnone"><img decoding="async" loading="lazy" class="wp-image-697 size-medium" title="keypair created message" src="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/keypair-created-message-300x198.jpg?resize=300%2C198" alt="" width="300" height="198" srcset="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/keypair-created-message.jpg?resize=300%2C198&amp;ssl=1 300w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/keypair-created-message.jpg?resize=150%2C99&amp;ssl=1 150w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/keypair-created-message.jpg?w=353&amp;ssl=1 353w" sizes="(max-width: 300px) 100vw, 300px" data-recalc-dims="1" /><figcaption id="caption-attachment-697" class="wp-caption-text">After the key pair is created, make sure to save the private key that is downloaded automatically</figcaption></figure>
<p>At this point a file named asw-wordpress.pem will have been downloaded by your browser. Make sure not to loose it! Put it into your ~/.ssh directory and chmod it to 0600:</p>
<pre><pre class="brush: plain; title: ; notranslate">
chmod 0600 ~/.ssh/aws-wordpress.pem
</pre>
<p>The final Key Pairs page on the AWS Management Console should look something like:</p>
<figure id="attachment_696" aria-describedby="caption-attachment-696" style="width: 300px" class="wp-caption alignleft"><img decoding="async" loading="lazy" class="wp-image-696 size-medium" title="Final Keypair display" src="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Final-Keypair-display-300x177.jpg?resize=300%2C177" alt="" width="300" height="177" srcset="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Final-Keypair-display.jpg?resize=300%2C177&amp;ssl=1 300w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Final-Keypair-display.jpg?resize=150%2C88&amp;ssl=1 150w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Final-Keypair-display.jpg?resize=400%2C236&amp;ssl=1 400w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Final-Keypair-display.jpg?w=887&amp;ssl=1 887w" sizes="(max-width: 300px) 100vw, 300px" data-recalc-dims="1" /><figcaption id="caption-attachment-696" class="wp-caption-text">Final Key Pair Page</figcaption></figure>
<h2>Create the Instance and Bootstrap Chef on the Instance</h2>
<p>The Chef Knife command has the ability to launch EC2 (and other cloud) instances. This process automatically installs chef and all its dependencies after the instance is created. If all goes well, it then loads and executes your roles and cookbooks on the instance creating your server.</p>
<p>You can see what options are available to this command:</p>
<pre><pre class="brush: plain; title: ; notranslate">
# knife ec2 server create --help
knife ec2 server create (options)
    -Z, --availability-zone ZONE     The Availability Zone
    -A, --aws-access-key-id KEY      Your AWS Access Key ID
    -K SECRET,                       Your AWS API Secret Access Key
        --aws-secret-access-key
        --user-data USER_DATA_FILE   The EC2 User Data file to provision the instance with
        --bootstrap-version VERSION  The version of Chef to install
    -N, --node-name NAME             The Chef node name for your new node
        --server-url URL             Chef Server URL
    -k, --key KEY                    API Client Key
        --color                      Use colored output
    -c, --config CONFIG              The configuration file to use
        --defaults                   Accept default values for all questions
    -d, --distro DISTRO              Bootstrap a distro using a template
        --ebs-no-delete-on-term      Do not delete EBS volumn on instance termination
        --ebs-size SIZE              The size of the EBS volume in GB, for EBS-backed instances
    -e, --editor EDITOR              Set the editor to use for interactive commands
    -E, --environment ENVIRONMENT    Set the Chef environment
    -f, --flavor FLAVOR              The flavor of server (m1.small, m1.medium, etc)
    -F, --format FORMAT              Which format to use for output
    -i IDENTITY_FILE,                The SSH identity file used for authentication
        --identity-file
    -I, --image IMAGE                The AMI for the server
        --no-color                   Don't use colors in the output
    -n, --no-editor                  Do not open EDITOR, just accept the data as is
        --no-host-key-verify         Disable host key verification
    -u, --user USER                  API Client Username
        --prerelease                 Install the pre-release chef gems
        --print-after                Show the data after a destructive operation
        --region REGION              Your AWS region
    -r, --run-list RUN_LIST          Comma separated list of roles/recipes to apply
    -G, --groups X,Y,Z               The security groups for this server
    -S, --ssh-key KEY                The AWS SSH key id
    -P, --ssh-password PASSWORD      The ssh password
    -x, --ssh-user USERNAME          The ssh username
    -s, --subnet SUBNET-ID           create node in this Virtual Private Cloud Subnet ID (implies VPC mode)
        --template-file TEMPLATE     Full path to location of template to use
    -V, --verbose                    More verbose output. Use twice for max verbosity
    -v, --version                    Show chef version
    -y, --yes                        Say yes to all prompts for confirmation
    -h, --help                       Show this message
</pre>
<p>The actual command we&#8217;ll use is:</p>
<pre><pre class="brush: plain; title: ; notranslate">
knife ec2 server create --run-list 'role[wordpress]' --node-name test-wordpress --flavor t1.micro \
--identity-file ~/.ssh/aws-wordpress.pem --image ami-a2f405cb --groups wordpress \
--ssh-key aws-wordpress --ssh-user ubuntu --ebs-no-delete-on-term
</pre>
<h3>Details of knife command to launch instance</h3>
<p><strong>role[wordpress]: </strong>The role[s] given to this instance. More than one can be specified by an orderd space separated list of strings: &#8216;role[role0]&#8217; &#8216;role[role1]&#8217; &#8230;</p>
<p><strong>&#8211;node-name test-wordpress:</strong> The name of the instance. Used by Chef to name the Node and Client</p>
<p><strong>&#8211;flavor t1.micro:</strong> The <a href="http://aws.amazon.com/ec2/instance-types/" target="_blank" rel="noopener">EC2 Instance Type</a>. Here we are using the smallest type. This is the only one that is <a href="http://aws.amazon.com/free/" target="_blank" rel="noopener">&#8220;free&#8221;</a></p>
<p><strong>&#8211;identity-file ~/.ssh/aws-wordpress.pem:</strong> The path to the ssh private key that was downloaded earlier from the AWS Management Console. You could potentially not include this if you added the key to your ssh-agent.</p>
<p><strong>&#8211;image ami-a2f405cb: </strong>The Amazon Machine Image assigned to this instance. It is the image of the root file system for the instance and thus determines what OS and software is booted when the instance is started. In this case it is the Canonical Ubuntu 10.4 32 bit AMI. You can find the latest Ubuntu AMIs for each region at the top of the home page of <a href="http://alestic.com/" target="_blank" rel="noopener">Eric Hammond&#8217;s super helpful site</a>.</p>
<p><strong>&#8211;groups wordpress:</strong> The Security Group[s] to be assigned to this instance. In this case its &#8220;wordpress&#8221; Multiple Groups can be assigned as a comma separated list</p>
<p><strong>&#8211;ssh-key aws-wordpress: </strong>The name of the SSH Key Pair that was downloaded from the AWS Management Console</p>
<p><strong>&#8211;ssh-user ubuntu: </strong>The user name for ssh access. This AMI uses &#8220;ubuntu&#8221;. The AMI&#8217;s usually are configured to allow only a single user to ssh by default. Different AMI&#8217;s use different names such as root or ec2-user.</p>
<p><strong>&#8211;ebs-no-delete-on-term: </strong>By default, the EBS Volume is deleted when the EC2 instance is terminated. By adding this flag it will instead make it so the EBS volume will continue to exist after the EC2 instance has been terminated. You want this for your final deployed site so that if something goes wrong with the EC2 instance you will still have your EBS volume and can use it to create a new EC2 instance without loosing your data. (That is the topic of another tutorial though!)</p>
<h3>Successful launch results</h3>
<p>After you fire off the knife ec2 server create command, you&#8217;ll see something like:</p>
<pre><pre class="brush: plain; title: ; notranslate">
[WARN] Fog::AWS::EC2#new is deprecated, use Fog::AWS::Compute#new instead (/Library/Ruby/Gems/1.8/gems/chef-0.9.12/lib/chef/knife/ec2_server_create.rb:145:in `run')
Instance ID: i-d10ae5bd
Flavor: t1.micro
Image: ami-a2f405cb
Availability Zone: us-east-1b
Security Groups: wordpress
SSH Key: aws-wordpress

Waiting for server..............
Public DNS Name: ec2-184-73-44-17.compute-1.amazonaws.com
Public IP Address: 184.73.44.17
Private DNS Name: domU-12-31-39-10-60-17.compute-1.internal
Private IP Address: 10.198.99.229

Waiting for sshd...done
INFO: Bootstrapping Chef on&amp;amp;nbsp;ec2-184-73-44-17.compute-1.amazonaws.com
</pre>
<p>That will be followed by loads of debugging info as the knife command bootstraps chef and its related packages and gems. This can go on for 10 to 20 minutes. Eventually you&#8217;ll see something along the lines of:</p>
<pre><pre class="brush: plain; title: ; notranslate">
Instance ID: i-d10ae5bd
Flavor: t1.micro
Image: ami-a2f405cb
Availability Zone: us-east-1b
Security Groups: wordpress
SSH Key: aws-wordpress
Public DNS Name: ec2-184-73-44-17.compute-1.amazonaws.com
Public IP Address: 184.73.44.17
Private DNS Name: domU-12-31-39-10-60-17.compute-1.internal
Private IP Address: 10.198.99.229
Run List: role[wordpress]
</pre>
<p>You can look just before this block and see if chef finished the running of the wordpress related cookbooks ok. If within a page above the last block you don&#8217;t see any errors then all is ok. The last few lines should be something like:</p>
<pre><pre class="brush: plain; title: ; notranslate">
[Mon, 03 Jan 2011 07:23:34 +0000] INFO: Chef Run complete in 10.945359 seconds
[Mon, 03 Jan 2011 07:23:34 +0000] INFO: cleaning the checksum cache
[Mon, 03 Jan 2011 07:23:34 +0000] INFO: Running report handlers
[Mon, 03 Jan 2011 07:23:34 +0000] INFO: Report handlers complete
</pre>
<p>If there are errors, you&#8217;ll have to debug your cookbooks which is beyond the scope of this post.</p>
<p>Now you should be able to log into your instance ether as the ubuntu default user or the user you created in the wordpress role and the Users Databag (rberger_test in this example):</p>
<pre><pre class="brush: plain; title: ; notranslate">
# Using the ubuntu user and an explicit ssh key
ssh -i ~/.ssh/aws-wordpress.pem ubuntu@ec2-184-73-44-17.compute-1.amazonaws.com

# Using the user created by the cookbook and a key that is already on you ssh-agent
ssh rberger_test@ec2-184-73-44-17.compute-1.amazonaws.com
</pre>
<h2>Configure DNS to have preferred FQDNs point to your instance</h2>
<p>You can access your site using the Amazon Public DNS name, but that would not be good in general. You probably want to access it via a URL like <em>http://www.myydomain.com</em>. To do this you must configure your DNS to add a CNAME to map your FQDN to the Amazon Public DNS name. How this is done is very specific to your DNS service provider. Bottom line is that you want to do a CNAME not an A record.  (I.E. an alias of your FQDN for the Amazon Public DNS name, not an A record that uses the Amazon IP address). There are some issues of using an A record with Amazon. You probably won&#8217;t see them for a simple situation such as hosting a single instance. But once you have many instances that need to talk to each other, using the CNAME will make life easier.</p>
<h2>Installing your WordPress Blog</h2>
<p>At this point you should be able to access your new instance via http. The initial screen will be the WordPress setup dialog. You should be able to access it via http using the Amazon Public DNS name or any CNAME aliases  you created and also added in the wordpress.rb role file override attribute for (wordpress =&gt;server_aliases. You should see something like:</p>
<figure id="attachment_717" aria-describedby="caption-attachment-717" style="width: 266px" class="wp-caption alignleft"><img decoding="async" loading="lazy" class="wp-image-717 size-medium" title="WordPress › Installation" src="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/WordPress-›-Installation-266x300.jpg?resize=266%2C300" alt="" width="266" height="300" srcset="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/WordPress-›-Installation.jpg?resize=266%2C300&amp;ssl=1 266w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/WordPress-›-Installation.jpg?resize=133%2C150&amp;ssl=1 133w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/WordPress-›-Installation.jpg?resize=400%2C449&amp;ssl=1 400w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/WordPress-›-Installation.jpg?w=775&amp;ssl=1 775w" sizes="(max-width: 266px) 100vw, 266px" data-recalc-dims="1" /><figcaption id="caption-attachment-717" class="wp-caption-text">WordPress startup installation page</figcaption></figure>
<p>It is possible to move an existing WordPress Blog to this new instance but that is beyond the scope of this post.</p>
<h2>Happily Ever After</h2>
<p>By default, the chef client runs every 1/2 hour on the instance. If you change any of the cookbooks and push them up to the Opscode Chef Server, those changes will be propogated to the instance the next time the chef-client runs again on the instance.</p>
<p>This is the way to maintain the server. By updating or adding cookbooks, you define the state of the server and the server will converge to that state when the chef-client runs. The inverse is true. If you change something on the server directly and the service you changed is managed by Chef, your direct changes could be reverted by the chef-client the next time it runs.</p>
<p>You shouldn&#8217;t need to but you can disable the chef-client from running automatically by running the following command while ssh&#8217;d to the instance:</p>
<pre><pre class="brush: plain; title: ; notranslate">
sudo /etc/init.d/chef-client stop
</pre>
<p>That will be reset (ie automatic chef-client runs will be re-enabled) if you reboot. You can permanently disable the automatic running of chef-client by running the following commands while ssh&#8217;d into the instance:</p>
<pre><pre class="brush: plain; title: ; notranslate">
cd /etc/init.d
sudo update-rc.d -f chef-client remove
</pre>
<h3>Using the WordPress Automatic Upgrade Mechanism</h3>
<p>At this point you should be able to use your wordpress blog as normal. You should be able to use the automatic update feature of WordPress to update WordPress itself and the plugins. When you are asked to supply the Connection Information, put in:</p>
<ul>
<li><span style="font-size: 10px;"><strong>Hostname</strong>: The Public FQDN of the host (ether the EC2 Public DNS Name or one of the DNS CNAMEs you set up)</span></li>
<li><span style="font-size: 10px;"><strong>FTP Username</strong>: &#8220;blog&#8221; (or whatever you set node[:wordpress][:blog_updater][:username] in the wordpress.rb role file)</span></li>
<li><span style="font-size: 10px;"><strong>FTP Password</strong>: &#8220;big-secret&#8221; (or whatever you <strong>SHOULD</strong> have set node[:wordpress][:blog_updater][:password] in the wordpress.rb role</span></li>
<li><span style="font-size: 10px;"><strong>Connection Type</strong>: FTPS (SSL)</span></li>
</ul>
<p>For instance for the Plugin Update Page:</p>
<figure id="attachment_746" aria-describedby="caption-attachment-746" style="width: 300px" class="wp-caption alignleft"><img decoding="async" loading="lazy" class="wp-image-746 size-medium" title="Upgrade Plugins ‹ WordPress Test — WordPress" src="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Upgrade-Plugins-‹-Wordpress-Test-—-WordPress-300x198.jpg?resize=300%2C198" alt="" width="300" height="198" srcset="https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Upgrade-Plugins-‹-Wordpress-Test-—-WordPress.jpg?resize=300%2C198&amp;ssl=1 300w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Upgrade-Plugins-‹-Wordpress-Test-—-WordPress.jpg?resize=150%2C99&amp;ssl=1 150w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Upgrade-Plugins-‹-Wordpress-Test-—-WordPress.jpg?resize=400%2C265&amp;ssl=1 400w, https://i0.wp.com/www.ibd.com/wp-content/uploads/2010/10/Upgrade-Plugins-‹-Wordpress-Test-—-WordPress.jpg?w=771&amp;ssl=1 771w" sizes="(max-width: 300px) 100vw, 300px" data-recalc-dims="1" /><figcaption id="caption-attachment-746" class="wp-caption-text">Upgrade Plugins Connection Information</figcaption></figure>
<p>That should work and be secure using the vsftpd server that we installed automatically.</p>
<p>Hopefully all will work well for you. I will try to answer questions but can&#8217;t guarantee quick response here. A great resource is the Opscode Chef IRC channel <a href="irc://irc.freenode.net/chef" target="_blank" rel="noopener">irc.freenode.net #chef</a>. And of course the <a href="http://wiki.opscode.com/" target="_blank" rel="noopener">Opscode Chef Wiki</a> and the <a href="http://help.opscode.com/home" target="_blank" rel="noopener">Opscode Support Site</a>.</p>
<h3>Source Code at Github</h3>
<p>You can get all the source for this at <a href="https://github.com/rberger/ibd-wordpress-repo" target="_blank" rel="noopener">https://github.com/rberger/ibd-wordpress-repo</a></p><p>The post <a href="https://www.ibd.com/howto/deploy-wordpress-to-amazon-ec2-micro-instance-with-opscode-chef/">Deploy WordPress to Amazon EC2 Micro Instance with Opscode Chef</a> first appeared on <a href="https://www.ibd.com">Cognizant Transmutation</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.ibd.com/howto/deploy-wordpress-to-amazon-ec2-micro-instance-with-opscode-chef/feed/</wfw:commentRss>
			<slash:comments>28</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">599</post-id>	</item>
	</channel>
</rss>
