<?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/"
	>

<channel>
	<title>Xi Group Ltd. Company Blog &#187; Xi Group Ltd. Company Blog &#187; linux</title>
	<atom:link href="http://blog.xi-group.com/tag/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.xi-group.com</link>
	<description>High-quality DevOps Services</description>
	<lastBuildDate>Tue, 09 Jun 2015 11:38:46 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.2.2</generator>
	<item>
		<title>DevOps Shell Script Template</title>
		<link>http://blog.xi-group.com/2014/07/devops-shell-script-template/</link>
		<comments>http://blog.xi-group.com/2014/07/devops-shell-script-template/#comments</comments>
		<pubDate>Thu, 03 Jul 2014 15:49:21 +0000</pubDate>
		<dc:creator><![CDATA[Ivo Vachkov]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Operations]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[heterogenous systems]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[shell script]]></category>
		<category><![CDATA[template]]></category>

		<guid isPermaLink="false">http://blog.xi-group.com/?p=51</guid>
		<description><![CDATA[In everyday life of a DevOps engineer you will have to create multiple pieces of code. Some of those will be run once, others &#8230; well others will live forever. Although it may be compelling to just put all the commands in a text editor, save the result and execute it, one should always consider [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="text-align: justify;">In everyday life of a DevOps engineer you will have to create multiple pieces of code. Some of those will be run once, others &#8230; well others will live forever. Although it may be compelling to just put all the commands in a text editor, save the result and execute it, one should always consider the &#8220;bigger picture&#8221;. What will happen if your script is run on another OS, on another Linux distribution, or even on a different version of the same Linux distribution?! Another point of view is to think what will happen if somehow your neat 10-line-script has to be executed on say 500 servers?! Can you be sure that all the commands will run successfully there? Can you even be sure that all the commands will even be present? Usually &#8230; No!</p>
<p style="text-align: justify;">Faced with similar problems on a daily basis we started devising simple solutions and practices to address them. One of those is the process of standardizing the way different utilities behave, the way they take arguments and report errors. Upon further investigation it became clear that a pattern can be extracted and synthesized in a series of template, one can use in daily work to keep common behavior between different utilities and components.</p>
<p style="text-align: justify;">Here is the basic template used in shell scripts:</p>
<p></p><pre class="crayon-plain-tag">#!/bin/sh
#
# DESCRIPTION: ... Include functional description ...
#
# Requiresments:
#	awk
#	... 
#	uname
#
# Example usag:
#	$ template.sh -h 
#	$ template.sh -p ARG1 -q ARG2
#

RET_CODE_OK=0
RET_CODE_ERROR=1

# Help / Usage function
print_help() {
	echo "$0: Functional description of the utility"
	echo ""
	echo "$0: Usage"
	echo "    [-h] Print help"
	echo "    [-p] (MANDATORY) First argument"
	echo "    [-q] (OPTIONAL) Second argument"
	exit $RET_CODE_ERROR;
}

# Check for supported operating system
p_uname=`whereis uname | cut -d' ' -f2`
if [ ! -x "$p_uname" ]; then
	echo "$0: No UNAME available in the system"
	exit $RET_CODE_ERROR;
fi
OS=`$p_uname`
if [ "$OS" != "Linux" ]; then
	echo "$0: Unsupported OS!";
	exit $RET_CODE_ERROR;
fi

# Check if awk is available in the system
p_awk=`whereis awk | cut -d' ' -f2`
if [ ! -x "$p_awk" ]; then
	echo "$0: No AWK available in the system!";
	exit $RET_CODE_ERROR;
fi

# Check for other used local utilities
#	bc
#	curl
#	grep 
#	etc ...

# Parse command line arguments
while test -n "$1"; do
	case "$1" in
	--help|-h)
		print_help
		exit 0
		;;
	-p)
		P_ARG=$2
		shift
		;;
	-q)
		Q_ARG=$2
		shift
		;;
	*)
		echo "$0: Unknown Argument: $1"
		print_help
		exit $RET_CODE_ERROR;
		;;
	esac
	
	shift
done

# Check if mandatory argument is present?
if [ -z "$P_ARG" ]; then
	echo "$0: Required parameter not specified!"
	print_help
	exit $RET_CODE_ERROR;
fi

# ... 

# Check if optional argument is present and if not, initialize!
if [ -z "$Q_ARG" ]; then
	Q_ARG="0";
fi

# ... 

# DO THE ACTUAL WORK HERE 

exit $RET_CODE_OK;</pre><p></p>
<p style="text-align: justify;">Nothing fancy. Basic framework that does the following:</p>
<ol>
<li><strong>Lines 3 &#8211; 13</strong>: Make sure basic documentation, dependency list and example usage patterns are provided with the script itself;</li>
<li><strong>Lines 15 &#8211; 16</strong>: Define meaningful return codes to allow other utils to identify possible execution problems and react accordingly;</li>
<li><strong>Lines 18 &#8211; 27</strong>: Basic help/usage() function to provide the user with short guidance on how to use the script; </li>
<li><strong>Lines 29 &#8211; 52</strong>: Dependency checks to make sure all utilities the script needs are available and executable in the system;</li>
<li><strong>Lines 54 &#8211; 77</strong>: Argument parsing of everything passed on the command line that supports both short and long argument names;</li>
<li><strong>Lines 79 &#8211; 91</strong>: Validity checks of the argument values that should make sure arguments are passed contextually correct values;</li>
<li><strong>Lines 95 &#8211; N</strong>: Actual programming logic to be implemented &#8230; </li>
</ol>
<p style="text-align: justify;">This template is successfully used in a various scenarios: command line utilities, Nagios plugins, startup/shutdown scripts, UserData scripts, daemons implemented in shell script with the help of <strong>start-stop-daemon</strong>, etc. It is also used to allow deployment on multiple operating systems and distribution versions. Resulting utilities and system components are <strong>more resilient</strong>, include <strong>better documentation and dependency sections</strong>, provide the user with <strong>similar and intuitive way to get help or pass arguments</strong>. Error handling is functional enough to go beyond the simple <strong>OK</strong> / <strong>ERROR</strong> state. And all of those are important feature when components must be run in highly heterogenous environments such as most cloud deployments!</p>
<div class="rpbt_shortcode">
<h3>Related Posts</h3>
<ul>
					
			<li><a href="http://blog.xi-group.com/2015/01/userdata-teplate-for-ubuntu-14-04-ec2-instances-in-aws/">UserData Template for Ubuntu 14.04 EC2 Instances in AWS</a></li>
					
			<li><a href="http://blog.xi-group.com/2014/07/how-to-implement-multi-cloud-deployment-for-scalability-and-reliability/">How to implement multi-cloud deployment for scalability and reliability</a></li>
					
			<li><a href="http://blog.xi-group.com/2014/06/small-tip-how-to-run-non-deamon-ized-processes-in-the-background-with-supervisord/">Small Tip: How to run non-deamon()-ized processes in the background with SupervisorD</a></li>
					
			<li><a href="http://blog.xi-group.com/2015/02/how-to-deploy-single-node-hadoop-setup-in-aws/">How to deploy single-node Hadoop setup in AWS</a></li>
					
			<li><a href="http://blog.xi-group.com/2014/11/small-tip-how-to-use-block-device-mappings-to-manage-instance-volumes-with-aws-cli/">Small Tip: How to use &#8211;block-device-mappings to manage instance volumes with AWS CLI</a></li>
			</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.xi-group.com/2014/07/devops-shell-script-template/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Small Tip: How to run non-deamon()-ized processes in the background with SupervisorD</title>
		<link>http://blog.xi-group.com/2014/06/small-tip-how-to-run-non-deamon-ized-processes-in-the-background-with-supervisord/</link>
		<comments>http://blog.xi-group.com/2014/06/small-tip-how-to-run-non-deamon-ized-processes-in-the-background-with-supervisord/#comments</comments>
		<pubDate>Thu, 26 Jun 2014 11:18:23 +0000</pubDate>
		<dc:creator><![CDATA[Ivo Vachkov]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Operations]]></category>
		<category><![CDATA[Small Tip]]></category>
		<category><![CDATA[background process]]></category>
		<category><![CDATA[daemon]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[long-running]]></category>
		<category><![CDATA[lts]]></category>
		<category><![CDATA[supervisor]]></category>
		<category><![CDATA[supervisord]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://blog.xi-group.com/?p=156</guid>
		<description><![CDATA[The following article will demonstrate how to use Ubuntu 14.04 LTS and SupervisorD to manage the not-so-uncommon case of long running services that expect to be running in active console / terminal. Those are usually quickly / badly written pieces of code that do not use daemon(), or equivalent function, to properly go into background [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="text-align: justify;">The following article will demonstrate how to use Ubuntu 14.04 LTS and <a href="http://supervisord.org">SupervisorD</a> to manage the not-so-uncommon case of long running services that expect to be running in active console / terminal. Those are usually quickly / badly written pieces of code that do not use daemon(), or equivalent function, to properly go into background but instead run forever in the foreground. Over the years multiple solutions emerged, including quite the ugly ones (<strong>nohup &#8230; 2>&#038;1 logfile &#038;</strong>). Luckily, there is a better one, and it&#8217;s called SupervisorD. With Ubuntu 14.04 LTS it even comes as a package and it should be part of your DevOps arsenal of tools!</p>
<p style="text-align: justify;">In a typical Python / Web-scale environment multiple components will be implemented in a de-coupled, micro-services, REST-based architecture. One of the popular frameworks for REST is <a href="http://bottlepy.org">Bottle</a>. And there are multiple approaches to build services with Bottle when full-blown HTTP Server is available (Apache, NginX, etc.) or if performance matters. All of those are valid and somewhat documented. But still, there is the case (and it more common than one would think) when developer will create Bottle server to handle simple task and it will propagate into production, using ugly solution like <strong>Screen/TMUX</strong> or even <strong>nohup</strong>. Here is a way to put this under proper control.</p>
<p>Test Server code: test-server.py</p><pre class="crayon-plain-tag">#!/usr/bin/env python

# Description: Demo Bottle Server to demonstrate use of SupervisorD
#
# How to run:
#       test-server.py -c test-server.conf
#
# Exepects the following configuration file:
#
#       server:
#               bind_ip: 0.0.0.0
#               bind_port: 8080
#
#       configuration_variable: true
#

import argparse
import time
import yaml
import sys

from bottle import route, run, template

# GET: /
@route('/')
def index():
        static_page = """
<html>
<head>
        <title>Test Server</title>
</head>
<body>
        <center><h2>Test Server is working!</h2></center>
</body>
</html>
        """
        return static_page

# Return the server->bind_ip value from the parsed configuration
def get_bind_ip(config):
        if config:
                return config['server']['bind_ip']
        else:
                return None

# Return the server->bind_port value from the parsed configuation
def get_bind_port(config):
        if config:
                return config['server']['bind_port']
        else:
                return None

# Return sample configuration variable
def get_config_data(config):
        if config:
                return config['configuration_variable']
        else:
                return None

# Main entry point for the application
def main():
        """ Main Entry Point for the appliation """

        # Parse command line arguments
        parser = argparse.ArgumentParser(description='Demo Server using Bottle')
        parser.add_argument('-c', '--config', type=str, required=True, dest='config', help='Configuration File Location')

        args = parser.parse_args()
        conf_file = args.config

        # Check config file accessibility
        try:
                conf_fd = open(conf_file, 'r')
        except IOError as e:
                if e.errno == errno.EACCES or e.errno == errno.ENOENT:
                        print("{progname}: Unable to read the configuration file ({config})!".format(progname=sys.argv[0], config=conf_file))
                        sys.exit(1)
        else:
                with conf_fd:
                        config = yaml.load(conf_fd)
                        conf_fd.close()

        # Get configuration data
        bind_ip = get_bind_ip(config)
        bind_port = get_bind_port(config)

        if bind_ip == None or bind_port == None:
                print("{progname}: Required configuration variable is unavailable!".format(progname=sys.argv[0]))
                sys.exit(1)

        config_data = get_config_data(config)

        # Run the web-server
        if config_data == True:
                run(host=bind_ip, port=bind_port)

if __name__ == '__main__':
    main()</pre><p></p>
<p>Test server configuration file: test-server.conf</p><pre class="crayon-plain-tag"># Sample configuration file in YAML format for test-server.py

server:
    bind_ip: 0.0.0.0
    bind_port: 8080

configuration_variable: true</pre><p></p>
<p>Manual execution of the server code will looks like this:</p><pre class="crayon-plain-tag">ubuntu@ip-10-67-161-137:~/test-server$ ./test-server.py -c test-server.conf
Bottle v0.12.0 server starting up (using WSGIRefServer())...
Listening on http://0.0.0.0:8080/
Hit Ctrl-C to quit.

94.155.194.28 - - [23/Jun/2014 12:34:39] "GET / HTTP/1.1" 200 126
^C
ubuntu@ip-10-67-161-137:~/test-server$</pre><p></p>
<p style="text-align: justify;">When the controlling terminal is lost the server will be terminated. Obviously, this is neither acceptable, nor desirable behavior.</p>
<p>With SupervisorD (<strong>sudo aptitude install supervisor</strong>) the service can be properly managed using simple configuration file.</p>
<p>Example SupervisorD configuration file: /etc/supervisor/conf.d/test-server.conf</p><pre class="crayon-plain-tag">[program:test-server]
command=/home/ubuntu/test-server/test-server.py -c /home/ubuntu/test-server/test-server.conf
user=ubuntu
redirect_stderr=true</pre><p></p>
<p>To start the service, execute:</p><pre class="crayon-plain-tag">ubuntu@ip-10-67-161-137:~$ sudo supervisorctl start test-server
test-server: started
ubuntu@ip-10-67-161-137:~$</pre><p></p>
<p>To verify successful service start:</p><pre class="crayon-plain-tag">ubuntu@ip-10-67-161-137:~$ ps ax
. . . 
 4353 ?        Ss     0:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
 4355 ?        S      0:00 python /home/ubuntu/test-server/test-server.py -c /home/ubuntu/test-server/test-server.conf
. . .
ubuntu@ip-10-67-161-137:~$</pre><p></p>
<p>SupervisorD will redirect stdout and stderr to properly named log files:</p><pre class="crayon-plain-tag">ubuntu@ip-10-67-161-137:~$ sudo cat /var/log/supervisor/test-server-stdout---supervisor-ssaGXP.log
Bottle v0.12.0 server starting up (using WSGIRefServer())...
Listening on http://0.0.0.0:8080/
Hit Ctrl-C to quit.

94.155.194.28 - - [23/Jun/2014 13:31:19] "GET / HTTP/1.1" 200 126
ubuntu@ip-10-67-161-137:~$</pre><p>Those log files can be integrated with a centralized logging architecture or processed for error / anomaly detection separately.</p>
<p>SupervisorD also comes with handy, command-line control utility, <strong>supervisorctl</strong>:</p><pre class="crayon-plain-tag">ubuntu@ip-10-67-161-137:~$ sudo supervisorctl status test-server
test-server                      RUNNING    pid 4355, uptime 0:11:40
ubuntu@ip-10-67-161-137:~$</pre><p></p>
<p style="text-align: justify;">With some additional effort SupervisorD can react to various types of events (<a href="http://supervisord.org/events.html">http://supervisord.org/events.html</a>) which bring it one step closer to full process monitoring &#038; notification solution!</p>
<p>References</p>
<ul>
<li>SupervisorD Homepage: <a href="http://supervisord.org">http://supervisord.org</a></li>
<li>Bottle Web Framework: <a href="http://bottlepy.org/docs/dev/index.html">http://bottlepy.org/docs/dev/index.html</a></li>
</ul>
<div class="rpbt_shortcode">
<h3>Related Posts</h3>
<ul>
					
			<li><a href="http://blog.xi-group.com/2014/11/small-tip-how-to-use-block-device-mappings-to-manage-instance-volumes-with-aws-cli/">Small Tip: How to use &#8211;block-device-mappings to manage instance volumes with AWS CLI</a></li>
					
			<li><a href="http://blog.xi-group.com/2014/07/small-tip-aws-announces-t2-instance-types/">Small Tip: AWS announces T2 instance types</a></li>
					
			<li><a href="http://blog.xi-group.com/2014/07/devops-shell-script-template/">DevOps Shell Script Template</a></li>
					
			<li><a href="http://blog.xi-group.com/2015/02/how-to-deploy-single-node-hadoop-setup-in-aws/">How to deploy single-node Hadoop setup in AWS</a></li>
					
			<li><a href="http://blog.xi-group.com/2015/01/userdata-teplate-for-ubuntu-14-04-ec2-instances-in-aws/">UserData Template for Ubuntu 14.04 EC2 Instances in AWS</a></li>
			</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.xi-group.com/2014/06/small-tip-how-to-run-non-deamon-ized-processes-in-the-background-with-supervisord/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Small Tip: Partitioning disk drives from within UserData script</title>
		<link>http://blog.xi-group.com/2014/06/small-tip-partitioning-disk-drives-from-within-userdata-script/</link>
		<comments>http://blog.xi-group.com/2014/06/small-tip-partitioning-disk-drives-from-within-userdata-script/#comments</comments>
		<pubDate>Wed, 11 Jun 2014 08:51:43 +0000</pubDate>
		<dc:creator><![CDATA[Ivo Vachkov]]></dc:creator>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Small Tip]]></category>
		<category><![CDATA[fdisk]]></category>
		<category><![CDATA[instance store]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[partitioning]]></category>

		<guid isPermaLink="false">http://blog.xi-group.com/?p=47</guid>
		<description><![CDATA[In a recent upgrade to the new generation of instances we faced an interesting conundrum. Previous generations came with quite the amount of disk spaces. Usually instance stores are mounted on /mnt. And it is all good and working. The best part, one can leave the default settings for the first instance store and do [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="text-align: justify;">In a recent upgrade to the new generation of instances we faced an interesting conundrum. Previous generations came with quite the amount of disk spaces. Usually instance stores are mounted on /mnt. And it is all good and working. The best part, one can leave the default settings for the first instance store and do anything with the second. And &#8220;anything&#8221; translated to enabling swap on the second instance store. With the new instance types, however the number (and the size) of the instance stores is reduced. It is SSD, but m2.4xlarge comes with 2 x 840 GB, while the equivalent in the last generation, r3.2xlarge, comes with only one 160 GB instance store partition.</p>
<p>Not a problem, just a challenge!</p>
<p style="text-align: justify;">We prefer to use UserData for automatic server setup. After some attempts it became clear that partitioning disks from a shell script is not exactly trivial tasks under Linux in AWS. BSD-based operating systems come with <strong>disklabel</strong> and <strong>fdisk</strong> and those will do the job. Linux comes with <strong>fdisk</strong> by default and that tool is somewhat limited &#8230;</p>
<p style="text-align: justify;">Luckily, <strong>fdisk</strong> reads data from <strong>stdin</strong> so quick-and-dirty solution quickly emerged!</p>
<p style="text-align: justify;">The following UserData is used to modify the instance store of a m3.large instance, creating 8GB swap partition and re-mounting the rest as /mnt:</p>
<p></p><pre class="crayon-plain-tag">#!/bin/bash -ex

# Mark execution start
echo "STARTING" &gt; /root/user_data_run

# Unmount /dev/xvdb if already mounted
umount -f /dev/xvdb

# Partition the disk (8GB for SWAP / Rest for /mnt)
(echo n; echo p; echo 1; echo 2048; echo +8G; echo t; echo 82; echo n; echo p; echo 2; echo; echo; echo w) | fdisk /dev/xvdb

# Make and enable swap
mkswap /dev/xvdb1
swapon /dev/xvdb1

# Make /mnt partition and mount it
mkfs.ext4 /dev/xvdb2
mount /dev/xvdb2 /mnt
sed -i s/xvdb/xvdb2/g /etc/fstab

# Mark execution end
echo "DONE" &gt; /root/user_data_run</pre><p>Execute it with AWS CLI (Using stock Ubuntu 14.04 HVM AMI):</p><pre class="crayon-plain-tag">aws ec2 run-instances --image-id ami-1d8c9574 --count 1 --instance-type m3.large --key-name test-key --security-groups test-sg --user-data file://userdata.sh</pre><p>The result:</p><pre class="crayon-plain-tag">:~&gt; ssh ubuntu@ec2-54-197-66-121.compute-1.amazonaws.com "df -h"
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1      7.8G  765M  6.6G  11% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
udev            3.7G   12K  3.7G   1% /dev
tmpfs           749M  336K  748M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            3.7G     0  3.7G   0% /run/shm
none            100M     0  100M   0% /run/user
/dev/xvdb2       22G   44M   21G   1% /mnt
:~&gt; ssh ubuntu@ec2-54-197-66-121.compute-1.amazonaws.com "free -h"
             total       used       free     shared    buffers     cached
Mem:          7.3G       276M       7.0G       352K       8.6M       177M
-/+ buffers/cache:        90M       7.2G
Swap:         8.0G         0B       8.0G
:~&gt;</pre><p></p>
<p style="text-align: justify;">There it is, 8GB swap partition (/dev/xvdb1) and the rest (/dev/xvdb2) mounted as /mnt. Note that /etc/fstab is also updated to account for the device name change!</p>
<div class="rpbt_shortcode">
<h3>Related Posts</h3>
<ul>
					
			<li><a href="http://blog.xi-group.com/2014/11/small-tip-how-to-use-block-device-mappings-to-manage-instance-volumes-with-aws-cli/">Small Tip: How to use &#8211;block-device-mappings to manage instance volumes with AWS CLI</a></li>
					
			<li><a href="http://blog.xi-group.com/2014/06/small-tip-use-aws-cli-to-create-instances-with-bigger-root-partitions/">Small Tip: Use AWS CLI to create instances with bigger root partitions</a></li>
					
			<li><a href="http://blog.xi-group.com/2015/01/small-tip-how-to-use-aws-cli-filter-parameter/">Small Tip: How to use AWS CLI &#8216;&#8211;filter&#8217; parameter</a></li>
					
			<li><a href="http://blog.xi-group.com/2014/07/small-tip-how-to-use-aws-cli-to-start-spot-instances-with-userdata/">Small Tip: How to use AWS CLI to start Spot instances with UserData</a></li>
					
			<li><a href="http://blog.xi-group.com/2014/07/small-tip-aws-announces-t2-instance-types/">Small Tip: AWS announces T2 instance types</a></li>
			</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.xi-group.com/2014/06/small-tip-partitioning-disk-drives-from-within-userdata-script/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Small Tip: Use AWS CLI to create instances with bigger root partitions</title>
		<link>http://blog.xi-group.com/2014/06/small-tip-use-aws-cli-to-create-instances-with-bigger-root-partitions/</link>
		<comments>http://blog.xi-group.com/2014/06/small-tip-use-aws-cli-to-create-instances-with-bigger-root-partitions/#comments</comments>
		<pubDate>Thu, 05 Jun 2014 13:43:44 +0000</pubDate>
		<dc:creator><![CDATA[Ivo Vachkov]]></dc:creator>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Small Tip]]></category>
		<category><![CDATA[AWS CLI]]></category>
		<category><![CDATA[bigger]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[root partition]]></category>

		<guid isPermaLink="false">http://blog.xi-group.com/?p=42</guid>
		<description><![CDATA[On multiple occasions we had to deal with instances running out of disk space for the root file system. AWS provides you reasonable amount of storage, but most operating systems without additional settings will just use the root partition for everything. Which is usually sub-optimal, since default root partition is 8GB and you may have [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="text-align: justify;">On multiple occasions we had to deal with instances running out of disk space for the root file system. AWS provides you reasonable amount of storage, but most operating systems without additional settings will just use the root partition for everything. Which is usually sub-optimal, since default root partition is 8GB and you may have 160GB SSD just mounted on /mnt and never used. With the AWS Web interface, it is easy. Just create bigger root partitions for the instances. However, the AWS CLI solution is not obvious and somewhat hard to find. If you need to regularly start instances with non-standard root partitions, manual approach is not maintainable.</p>
<p style="text-align: justify;">There is a solution. It lies in the <strong>&#8211;block-device-mappings</strong> parameter that can be passed to <strong>aws ec2 run-instances</strong> command.</p>
<p style="text-align: justify;">According to the documentation this parameter uses JSON-encoded block device mapping to adjust different parameter of the instances that are being started. There is a simple example that shows how to attach additional volume:</p>
<p></p><pre class="crayon-plain-tag">--block-device-mappings "[{\"DeviceName\": \"/dev/sdh\",\"Ebs\":{\"VolumeSize\":100}}]"</pre><p></p>
<p style="text-align: justify;">This will attach additional 100GB EBS volume as /dev/sdb. The key part: <strong>&#8220;Ebs&#8221;: {&#8220;VolumeSize&#8221;: 100}</strong></p>
<p style="text-align: justify;">By specifying your instance&#8217;s root partition you can adjust the root partition size. Following is an example how to create Amazon Linux instance running on t1.micro with 32GB root partition:</p>
<p></p><pre class="crayon-plain-tag">aws ec2 run-instances --image-id ami-fb8e9292 --count 1 --instance-type t1.micro --key-name test-key --security-groups test-sg --block-device-mapping "[ { \"DeviceName\": \"/dev/sda1\", \"Ebs\": { \"VolumeSize\": 32 } } ]"</pre><p>The resulting volume details show the requested size and the fact that this is indeed root partition:<br />
<a href="http://blog.xi-group.com/wp-content/uploads/2014/06/Screen-Shot-2014-06-05-at-4.30.31-PM.png"><img class="alignnone size-full wp-image-53 img-thumbnail img-responsive" src="http://blog.xi-group.com/wp-content/uploads/2014/06/Screen-Shot-2014-06-05-at-4.30.31-PM.png" alt="Screen Shot 2014-06-05 at 4.30.31 PM" width="1474" height="117" /></a></p>
<p>Confirming, that the instance is operating on the proper volume:</p><pre class="crayon-plain-tag">:~&gt; ssh ec2-user@ec2-50-16-57-145.compute-1.amazonaws.com "df -h"
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1       32G  1.1G   31G   4% /
devtmpfs        282M   12K  282M   1% /dev
tmpfs           297M     0  297M   0% /dev/shm
:~&gt;</pre><p></p>
<p style="text-align: justify;">There is enough space in the root partition now. Note: This is EBS volume, additional charges will apply!</p>
<p style="text-align: justify;">References</p>
<ul>
<li>aws ec2 run-instances help</li>
</ul>
<div class="rpbt_shortcode">
<h3>Related Posts</h3>
<ul>
					
			<li><a href="http://blog.xi-group.com/2015/01/small-tip-how-to-use-aws-cli-filter-parameter/">Small Tip: How to use AWS CLI &#8216;&#8211;filter&#8217; parameter</a></li>
					
			<li><a href="http://blog.xi-group.com/2014/11/small-tip-how-to-use-block-device-mappings-to-manage-instance-volumes-with-aws-cli/">Small Tip: How to use &#8211;block-device-mappings to manage instance volumes with AWS CLI</a></li>
					
			<li><a href="http://blog.xi-group.com/2014/07/small-tip-how-to-use-aws-cli-to-start-spot-instances-with-userdata/">Small Tip: How to use AWS CLI to start Spot instances with UserData</a></li>
					
			<li><a href="http://blog.xi-group.com/2014/06/small-tip-ebs-volume-allocation-time-is-linear-to-the-size-and-unrelated-to-the-instance-type/">Small Tip: EBS volume allocation time is linear to the size and unrelated to the instance type</a></li>
					
			<li><a href="http://blog.xi-group.com/2014/06/small-tip-partitioning-disk-drives-from-within-userdata-script/">Small Tip: Partitioning disk drives from within UserData script</a></li>
			</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.xi-group.com/2014/06/small-tip-use-aws-cli-to-create-instances-with-bigger-root-partitions/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
