<?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>Editor&#8217;s Pick &#8211; Blog of Kliment Andreev &#8211; A place so I won&#039;t forget things</title>
	<atom:link href="https://blog.andreev.it/category/editors-pick/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.andreev.it</link>
	<description></description>
	<lastBuildDate>Wed, 12 Jul 2023 13:33:16 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>AWS, CentOS: Create your own radio station and deploy it on Alexa (optional)</title>
		<link>https://blog.andreev.it/2019/10/aws-centos-create-your-own-radio-station-and-deploy-it-on-alexa-optional/</link>
					<comments>https://blog.andreev.it/2019/10/aws-centos-create-your-own-radio-station-and-deploy-it-on-alexa-optional/#comments</comments>
		
		<dc:creator><![CDATA[Kliment Andreev]]></dc:creator>
		<pubDate>Sun, 06 Oct 2019 12:55:24 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Editor's Pick]]></category>
		<category><![CDATA[Alexa]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[icecast]]></category>
		<category><![CDATA[radio station]]></category>
		<guid isPermaLink="false">https://blog.andreev.it/?p=5735</guid>

					<description><![CDATA[In this post I&#8217;ll explain how to run your own Internet radio station. On&#8230;]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>In this post I&#8217;ll explain how to run your own Internet radio station. On top of that, I&#8217;ll show you how to build an Alexa skill to deploy your station in the cloud, so anyone with Alexa can say: &#8220;<strong>Alexa, play</strong> &lt;<strong>whatever_station</strong>&gt;&#8221; and hear your Internet radio station. There are many tutorials that describe this, but most of them require that you pay for some radio station hosting. If that&#8217;s easier for you, then you can skip this tutorial. If you want to have your own radio on the Internet (build from scratch) and deploy it or not on Alexa, than this guide is for you. There are some prerequisites though. You&#8217;ll need a CentOS 7 instance with a public IP and if you decide to publish it on Alexa, then you&#8217;ll need valid SSL certificate.<br />
<strong>IMPORTANT</strong>: If your want your station to be public on Alexa, then you also need license for the music. But no worries, if you just want your music played over Alexa at home (and not public), you can still do it.<br />
Also, the ices2 client can&#8217;t stream MP3 files, so you have to convert them to OGG. If you want to stream MP3s directly, check the earlier version of ices. The configuration file is almost identical. Ogg-Vorbis is perfectly fine and I&#8217;ll show you how to convert your library from MP3 to OGG.<br />
So, there are two parts of this tutorial. Build your own station first and then the optional Alexa part. Let&#8217;s start.</p>
<h1>CentOS 7</h1>
<p>Make sure you have a CentOS 7 instance ready in the cloud with a public IP. NATed instances are OK as long as you can control the ports. In addition, make sure SELinux is disabled. Disabling the OS firewall is optional. I assume that the firewall on the instance is on.</p>
<h2>icecast</h2>
<p><a href="http://icecast.org/" rel="noopener noreferrer" target="_blank">icecast </a>is a streaming <strong>server </strong>similar to shoutcast. It broadcasts a stream that&#8217;s provided by a source. The source can be a microphone, sound card or a file. In order to stream a file, we need a <strong>client </strong>such as ices, LiquidSoap etc. You are not the client, you are the <strong>listener</strong>. Now that we have this straighten up, let&#8217;s install icecast from the source. Just copy and paste everything below. If you get an error, execute line by line and see where it fails. Fix any issues, if any.</p>
<pre class="brush: bash; highlight: [7]; title: ; notranslate">
yum -y groupinstall &quot;Development Tools&quot;
yum install -y wget curl-devel libvorbis-devel libxslt-devel libxslt-devel openssl-devel
cd /tmp
wget http://downloads.xiph.org/releases/icecast/icecast-2.4.4.tar.gz
tar xzvf icecast-2.4.4.tar.gz
cd icecast-2.4.4
./configure --prefix=/opt/icecast --with-curl --with-openssl
make
make install
</pre>
<p>We specified <strong>/opt/icecast</strong> where <strong>icecast </strong>will be installed (line 7). You can change that in the <strong>configure </strong>statement, but you have to adjust everything after. <strong>icecast </strong>creates a sample configuration file named <strong>icecast.xml</strong> under <strong>/opt/icecast/etc</strong>. If you look at the XML file, you&#8217;ll see a bunch of settings and some of them have to be changed.<br />
We&#8217;ll change the following parameters:</p>
<ul>
&lt;<strong>location</strong>&gt; &#8211; Specifies where the radio station is located.<br />
&lt;<strong>admin</strong>&gt; &#8211; An e-mail address of the radio station admin.<br />
&lt;<strong>hostname</strong>&gt; &#8211; A hostname for the radio station. Important only if you are publishing this in YP directory of broadcast streams. Irrelevant for us, but we&#8217;ll change it anyway.<br />
&lt;<strong>source-password</strong>&gt; &#8211; A password so the source client can attach to the icecast server and provide the OGG stream.<br />
&lt;<strong>relay-password</strong>&gt; &#8211; Used only if the icecast is used as a relay.<br />
&lt;<strong>admin-user</strong>&gt; &#8211; Username for the admin web page.<br />
&lt;<strong>admin-password</strong>&gt; &#8211; Password for the admin user.<br />
&lt;<strong>logdir</strong>&gt; &#8211; A directory where the log file is stored.<br />
&lt;<strong>user</strong>&gt; &#8211; A local OS user that will run icecast. Don&#8217;t use root, it won&#8217;t work. You can create a separate user for this. The built-in nobody user is perfectly fine.<br />
&lt;<strong>group</strong>&gt; &#8211; A local OS group that will run icecast. </ul>
<p>So, let&#8217;s change these manually or with this code. Adjust to suit your needs.</p>
<pre class="brush: bash; title: ; notranslate">
cd /opt/icecast/etc
location=&quot;New Jersey&quot;
admin=klimenta@iandreev.com
hostname=radio.iandreev.com
sourcepwd=Sup3rStr0ngP455w0rd
relaypwd=Sup3rStr0ngP455w0rd
admin=myusername
password=Sup3rStr0ngP455w0rd
logdir=/opt/icecast/log
user=nobody
group=nobody
sed -i &quot;s/&lt;location&gt;Earth/&lt;location&gt;$location/&quot; icecast.xml
sed -i &quot;s/&lt;admin&gt;icemaster@localhost/&lt;admin&gt;$admin/&quot; icecast.xml
sed -i &quot;s/&lt;hostname&gt;localhost/&lt;hostname&gt;$hostname/&quot; icecast.xml
sed -i &quot;s/&lt;source-password&gt;hackme/&lt;source-password&gt;$sourcepwd/&quot; icecast.xml
sed -i &quot;s/&lt;relay-password&gt;hackme/&lt;relay-password&gt;$relaypwd/&quot; icecast.xml
sed -i &quot;s/&lt;admin-user&gt;admin/&lt;admin-user&gt;$admin/&quot; icecast.xml
sed -i &quot;s/&lt;admin-password&gt;hackme/&lt;admin-password&gt;$password/&quot; icecast.xml
sed -i &quot;s|&lt;logdir&gt;/opt/icecast/var/log/icecast|&lt;logdir&gt;$logdir|&quot; icecast.xml
sed -i &quot;s/&lt;user&gt;nobody/&lt;user&gt;$user/&quot; icecast.xml
sed -i &quot;s/&lt;group&gt;nogroup/&lt;group&gt;$group/&quot; icecast.xml
</pre>
<p>Let&#8217;s create the log directory and give the icecast daemon permission to write.</p>
<pre class="brush: bash; title: ; notranslate">
cd /opt/icecast
mkdir log
chown -R nobody:nobody log
</pre>
<p>icecast doesn&#8217;t come with a startup systemd script, so we&#8217;ll have to take care of that.</p>
<pre class="brush: bash; title: ; notranslate">
cat &lt;&lt; EOF &gt; /etc/systemd/system/icecast.service
&#x5B;Unit]
Description=Icecast Network Audio Streaming Server
After=network.target

&#x5B;Service]
Type=simple
User=nobody
Group=nobody
ExecStart=/opt/icecast/bin/icecast -c /opt/icecast/etc/icecast.xml
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill $MAINPID

&#x5B;Install]
WantedBy=multi-user.target
EOF
</pre>
<p>Now you can enable icecast on boot and start it.</p>
<pre class="brush: bash; title: ; notranslate">
systemctl enable icecast
systemctl start icecast
</pre>
<p>If you run <strong>systemctl status icecast</strong>, you should see that the daemon is running. Also, if you check the error log (<strong>tail /opt/icecast/log/error.log</strong>), you&#8217;ll see that the daemon is running too. Ignore the SSL warning for now.<br />
<strong>icecast </strong>runs on port <strong>8000</strong>, so if you have a firewall, you&#8217;ll have to poke a hole.</p>
<pre class="brush: bash; title: ; notranslate">
firewall-cmd --add-port=8000/tcp --zone=public --permanent
firewall-cmd --reload
</pre>
<p>From a browser, go to your server&#8217;s IP on port 8000, e.g. <strong>http://201.202.203.24:8000</strong> and you&#8217;ll see something like this.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-01.jpg"><img fetchpriority="high" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-01.jpg" alt="" width="929" height="248" class="aligncenter size-full wp-image-8683" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-01.jpg 929w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-01-300x80.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-01-768x205.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-01-585x156.jpg 585w" sizes="(max-width: 929px) 100vw, 929px" /></a><br />
If you click on <strong>Administration</strong>, you&#8217;ll be prompted to log in. Use the <strong>admin-user</strong> and <strong>admin-password</strong> that you&#8217;ve changed in <strong>icecast.xml</strong>.</p>
<h2>ices</h2>
<p>Now that we have the streaming server ready, let&#8217;s install the source client. The source client will provide the stream to the server. We&#8217;ll use <strong>ices </strong>for this.</p>
<pre class="brush: bash; title: ; notranslate">
cd /tmp
wget http://downloads.us.xiph.org/releases/ices/ices-2.0.2.tar.gz
tar xzvf ices-2.0.2.tar.gz
cd ices-2.0.2
yum -y install libshout-devel
./configure --prefix=/opt/ices
make &amp;&amp; make install
</pre>
<p><strong>ices </strong>creates some configuration files under <strong>/opt/ices/share/ices</strong>. We&#8217;ll use the <strong>ices-playlist.xml</strong> template to generate a radio station for us.</p>
<pre class="brush: bash; title: ; notranslate">
cd /opt/ices/share/ices
cp ices-playlist.xml myradio.xml
</pre>
<p>Now edit <strong>myradio.xml</strong> and change the following with a script or manually. Make sure you adjust for your needs.</p>
<ul>
&lt;<strong>logpath</strong>&gt; &#8211; A directory where the log file is stored.<br />
&lt;<strong>logfile</strong>&gt; &#8211; The name of the log file.<br />
&lt;<strong>name</strong>&gt; &#8211; The name of your radio.<br />
&lt;<strong>genre</strong>&gt; &#8211; Self explanatory.<br />
&lt;<strong>description</strong>&gt; &#8211; Enter a description for your station.<br />
&lt;<strong>password</strong>&gt; &#8211; The password to connect to icecast. It should match the <strong>source-password in icecast.xml</strong><br />
&lt;<strong>mount</strong>&gt; &#8211; The name of the mount. This is like the URL for your station. It has to end with .ogg<br />
&lt;<strong>param name</strong>&gt; &#8211; A file where the playlist for this station will be stored.
</ul>
<pre class="brush: bash; title: ; notranslate">
cd /opt/ices/share/ices
logpath=/opt/ices/log
logfile=myradio.log
name=&quot;Radio MyRadio&quot;
genre=&quot;Some genre&quot;
descr=&quot;Best Radio in the Universe and beyond&quot;
pwd=Sup3rStr0ngP455w0rd
mount=/myradio.ogg
playlist=/opt/ices/playlists/myradio.txt
sed -i &quot;s|&lt;logpath&gt;/var/log/ices|&lt;logpath&gt;$logpath|&quot; myradio.xml
sed -i &quot;s/&lt;logfile&gt;ices.log/&lt;logfile&gt;$logfile/&quot; myradio.xml
sed -i &quot;s/&lt;name&gt;Example stream name/&lt;name&gt;$name/&quot; myradio.xml
sed -i &quot;s/&lt;genre&gt;Example genre/&lt;genre&gt;$genre/&quot; myradio.xml
sed -i &quot;s/&lt;description&gt;A short description of your stream/&lt;description&gt;$descr/&quot; myradio.xml
sed -i &quot;s/&lt;password&gt;hackme/&lt;password&gt;$pwd/&quot; myradio.xml
sed -i &quot;s|&lt;mount&gt;/example1.ogg|&lt;mount&gt;$mount|&quot; myradio.xml
sed -i &quot;s|&lt;param name=\&quot;file\&quot;&gt;playlist.txt|&lt;param name=\&quot;file\&quot;&gt;$playlist|&quot; myradio.xml
</pre>
<p>Let&#8217;s create two directories. One for the logs and the other for the files where we&#8217;ll store playlists. Not the music files  &#8211; the playlists. The playlists tells ices where to look for your music.</p>
<pre class="brush: bash; title: ; notranslate">
cd /opt/ices
mkdir log playlists
chown -R nobody:nobody log
</pre>
<p>Create a startup script for ices as well. Look at line 10, that&#8217;s where my config file for this radio station is. Can you have multiple radio stations? Absolutely, one <strong>icecast </strong>server can handle multiple <strong>ices </strong>clients. Just invoke another <strong>ices </strong>client with a different config file and create a similar startup script with a different URL, e.g &#8230;/myradio.ogg and &#8230;/mystation.ogg. </p>
<pre class="brush: bash; highlight: [10]; title: ; notranslate">
cat &lt;&lt; EOF &gt; /etc/systemd/system/ices-myradio.service
&#x5B;Unit]
Description=Ices Network Audio Streaming Client for MyRadio
After=icecast.service

&#x5B;Service]
Type=simple
User=nobody
Group=nobody
ExecStart=/opt/ices/bin/ices /opt/ices/share/ices/myradio.xml
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill $MAINPID
Restart=always
RestartSec=3

&#x5B;Install]
WantedBy=multi-user.target
EOF
</pre>
<p>At this point you can tell ices where your music is stored. As I mentioned earlier, we&#8217;ll have to use Ogg-Vorbis files (.ogg).<br />
So, create a folder where your music files will be stored. I&#8217;ll use <strong>/music/myradio</strong> and put some public royalty free music there.<br />
Courtesy of <strong>Patrick de Arteaga</strong>. Please give him some credit and visit his <a href="https://patrickdearteaga.com/" rel="noopener noreferrer" target="_blank">site</a>.</p>
<pre class="brush: bash; title: ; notranslate">
mkdir -p /music/myradio
cd /music/myradio
wget -U 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20070802 SeaMonkey/1.1.4' https://patrickdearteaga.com/audio/Battleship.ogg
wget -U 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20070802 SeaMonkey/1.1.4' https://patrickdearteaga.com/audio/Chiptronical.ogg
wget -U 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20070802 SeaMonkey/1.1.4' https://patrickdearteaga.com/audio/Friends.ogg
</pre>
<p>OK, so we have our music there. When the stream ends, it will start from the first song. Now we have to create the playlist and put it under the <strong>/opt/ices/conf</strong> directory.<br />
If you remember we specified <strong><param name></strong> directive in the <strong>myradio.xml</strong> file referencing where the playlist is stored. Let&#8217;s create the file.</p>
<pre class="brush: bash; title: ; notranslate">
ls -d /music/myradio/*.ogg &gt; /opt/ices/playlists/myradio.txt
</pre>
<p>Now that we have everything ready, let&#8217;s enable ices on boot and start it.</p>
<pre class="brush: bash; title: ; notranslate">
systemctl enable ices-myradio
systemctl start ices-myradio
</pre>
<p>Check if everything is OK. </p>
<pre class="brush: bash; title: ; notranslate">
systemctl status ices-myradio
tail /opt/ices/log/myradio.log
</pre>
<p>If everything looks good, you can listen to your stream at <strong>http://whateverIP:8000/myradio.ogg</strong>.<br />
If you are satisfied with this, you can stop reading. You&#8217;ve accomplished enough. If you want to see how to convert MP3 to OGG and how to use a reverse proxy so you can stream over HTTP, then read further.</p>
<h2>MP3 to OGG conversion (sox)</h2>
<p>If you have a bunch of files that you want to convert to OGG, you can use sox. It&#8217;s a very powerful tool for conversion between formats. Let&#8217;s install it first.</p>
<pre class="brush: bash; title: ; notranslate">
yum -y install libmad-devel libid3tag-devel lame lame-devel flac flac-devel
cd /tmp
wget https://sourceforge.net/projects/sox/files/sox/14.4.2/sox-14.4.2.tar.gz
tar xvfz sox-14.4.2.tar.gz
cd sox-14.4.2
./configure
make -s &amp;&amp; make install
</pre>
<p>Now you can convert the files from MP3 to OGG and vice versa. Conversion is very simple. Just specify the source and the destination file, e.g. <strong>sox file1.mp3 file1.ogg</strong> and that&#8217;s it. If you want to see the details of the file such as bit-rate, duration, sample etc, use <strong>soxi</strong>, e.g. <strong>soxi file.ogg</strong>. If you want more details on sox and it&#8217;s usage, please check their <a href="http://sox.sourceforge.net/" rel="noopener noreferrer" target="_blank">website</a>. For <strong>soxi</strong>, check this <a href="http://sox.sourceforge.net/soxi.html" rel="noopener noreferrer" target="_blank">link</a>.<br />
If you want to convert your files in bulk, you can use this command that will search for MP3 files in your current directory and subdirectories and convert them to OGG.</p>
<pre class="brush: bash; title: ; notranslate">
find . -type f -name &quot;*.mp3&quot; -exec sh -c 'sox &quot;$1&quot; &quot;${1%.mp3}.ogg&quot;' _ {} \;
</pre>
<h2>nginx as reverse proxy</h2>
<p>If you recall, we are using <strong>http://somenameorip:8000/myradio.ogg</strong> to access our station. This is fine for regular users from their home, but in any corporate environment, anything than port 80 and 443 are blocked. So, we have to stream our music over port 80. I&#8217;ll show later how to stream over 443 because it&#8217;s a requirement for Alexa. First thing first, let&#8217;s install <strong>nginx</strong>.</p>
<pre class="brush: bash; title: ; notranslate">
yum -y install nginx
systemctl enable nginx
</pre>
<p><strong>nginx </strong>creates a configuration file under <strong>/etc/nginx</strong> called <strong>nginx.conf</strong>. Look for this snippet in the configuration file.</p>
<pre class="brush: plain; title: ; notranslate">
        location / {
        }
</pre>
<p>&#8230;and change it to this.</p>
<pre class="brush: plain; title: ; notranslate">
        location /myradio.ogg {
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_pass http://localhost:8000/myradio.ogg;
        }
</pre>
<p>You can start the reverse proxy now and verify that it&#8217;s working.</p>
<pre class="brush: bash; title: ; notranslate">
systemctl start nginx
systemctl status nginx
</pre>
<p>Because we are proxying over HTTP, we have to open the firewall too and if you want you can close port 8000. It&#8217;s not needed anymore.</p>
<pre class="brush: bash; title: ; notranslate">
firewall-cmd --add-port=80/tcp --zone=public --permanent
firewall-cmd --remove-port=8000/tcp --zone=public --permanent
firewall-cmd --reload
</pre>
<p>Now you can access your station as <strong>http://serveriporname/myradio.ogg</strong>, so there is no need to specify port 8000.</p>
<h2>SSL certificate</h2>
<p>If you decide to publish your station on Alexa, you&#8217;ll need a valid (not self-signed) certificate. You will also need to reconfigure both nginx and icecast to use SSL. You can&#8217;t access your server by IP because you&#8217;ll get an invalid certificate warning, so make sure you have your DNS ready to resolve your IP to a valid domain name. Get the certificates ready. You&#8217;ll need the private key, the certificate, the intermediate certificate and the root CA certificate. When you purchase a certificate all of these will be available for you (except for the private key).<br />
Let&#8217;s create the chain. In my case, I have each certificate in a separate file and I&#8217;ll create one certificate for icecast.</p>
<pre class="brush: bash; title: ; notranslate">
mkdir /opt/icecast/ssl
cat star.iandreev.com.key star.iandreev.com.crt star.iandreev.com.inter star.iandreev.com.CA &gt; /opt/icecast/ssl/icecast.pem
chown -R nobody:nobody /opt/icecast/ssl
</pre>
<p>Then, edit <strong>/opt/icecast/etc/icecast.xml</strong> and find the following snippet.</p>
<pre class="brush: plain; title: ; notranslate">
    &lt;listen-socket&gt;
        &lt;port&gt;8000&lt;/port&gt;
    &lt;/listen-socket&gt;
</pre>
<p>Copy these three lines after, so the config looks like this now. We are telling <strong>icecast </strong>to spawn itself and listen on port 8443 too.</p>
<pre class="brush: bash; title: ; notranslate">
    &lt;listen-socket&gt;
        &lt;port&gt;8000&lt;/port&gt;
    &lt;/listen-socket&gt;
    &lt;listen-socket&gt;
        &lt;port&gt;8443&lt;/port&gt;
        &lt;ssl&gt;1&lt;/ssl&gt;
    &lt;/listen-socket&gt;
</pre>
<p>We also have to specify the certificate chain. Find this line in the config and <strong>uncomment it</strong>. Make sure you uncomment the line, it&#8217;s commented by default.</p>
<pre class="brush: bash; title: ; notranslate">
&lt;ssl-certificate&gt;/opt/icecast/ssl/icecast.pem&lt;/ssl-certificate&gt;
</pre>
<p>Now, you have to restart <strong>icecast</strong> and <strong>ices </strong>too.</p>
<pre class="brush: bash; title: ; notranslate">
systemctl restart icecast
systemctl restart ices-myradio
</pre>
<p>And if you check the error.log (yes, error log), you&#8217;ll see that icecast is using SSL now.</p>
<pre class="brush: bash; highlight: [1]; title: ; notranslate">
tail /opt/icecast/log/error.log
&#x5B;2019-10-03  22:29:23] INFO connection/get_ssl_certificate SSL certificate found at /opt/icecast/ssl/icecast.pem
&#x5B;2019-10-03  22:29:23] INFO connection/get_ssl_certificate SSL using ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES
</pre>
<p>Now the <strong>nginx </strong>part. Edit <strong>/etc/nginx/nginx.conf</strong>.</p>
<ul>
&#8211; uncomment the section for &#8220;a TLS enabled server&#8221;. Remove the # from all the lines below # Settings for a TLS enabled server. Don&#8217;t uncomment this line.<br />
&#8211; Replace location / {} with this snippet. Not the first occurrence for port 80. This is for port 443.</p>
<pre class="brush: plain; title: ; notranslate">
        location /myradio.ogg {
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_pass http://localhost:8000/myradio.ogg;
        }
</pre>
<p>&#8211; Copy your private key to <strong>/etc/pki/nginx/private/server.key</strong> and your public certificate to <strong>/etc/pki/nginx/server.crt</strong>. If the directories do not exists, create them. (<strong>cd /etc/pki &#038;&#038; mkdir -p nginx/private</strong>). Also, make sure that the certificate (<strong>server.crt</strong>) is a chain of certificates, not just a simple server certificate. If you do <strong>curl -iv https://yoursite.com</strong>, the result for the SSL should be clear without any errors or warning. You can reuse the icecast.pem certificate for icecast and copy that file as <strong>server.crt</strong> under <strong>/etc/pki/nginx/</strong>. You can even reference the same file in the same directory, but then you have to change the config files and permissions.<br />
&#8211; Reload nginx (<strong>systemctl reload nginx</strong>)<br />
&#8211; Open the firewall</p>
<pre class="brush: bash; title: ; notranslate">
firewall-cmd --add-port=443/tcp --zone=public --permanent
firewall-cmd --reload
</pre>
</ul>
<p>Now you can access your server with https. If you want to be even more precise, you can redirect the http to https, so you don&#8217;t have to specify the protocol in the browser. Edit <strong>nginx.conf</strong> and add line 5. Reload nginx after (<strong>systemctl reload nginx</strong>).</p>
<pre class="brush: bash; highlight: [5]; title: ; notranslate">
server {
    listen       80 default_server;
    listen       &#x5B;::]:80 default_server;
    server_name  _;
    return 301 https://$host$request_uri;
    root         /usr/share/nginx/html;
</pre>
<p>Here is my <strong>/etc/nginx/nginx.conf</strong> file.</p>
<pre class="brush: bash; collapse: true; light: false; title: ; toolbar: true; notranslate">
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user &#x5B;$time_local] &quot;$request&quot; '
                      '$status $body_bytes_sent &quot;$http_referer&quot; '
                      '&quot;$http_user_agent&quot; &quot;$http_x_forwarded_for&quot;';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       &#x5B;::]:80 default_server;
        server_name  _;
        return 301 https://$host$request_uri;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_pass http://localhost:8000/myradio.ogg;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

# Settings for a TLS enabled server.

    server {
        listen       443 ssl http2 default_server;
        listen       &#x5B;::]:443 ssl http2 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        ssl_certificate &quot;/etc/pki/nginx/server.crt&quot;;
        ssl_certificate_key &quot;/etc/pki/nginx/private/server.key&quot;;
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location /myradio.ogg {
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_pass http://localhost:8000/myradio.ogg;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

}
</pre>
<h1>Alexa</h1>
<p>Now comes the fun part. It&#8217;s much easier than you think thanks to <a href="https://andymoore.info/" rel="noopener noreferrer" target="_blank">Andy Moore</a>. He has a great step-by-step <a href="https://andymoore.info/stream-your-radio-station-on-alexa-for-free" rel="noopener noreferrer" target="_blank">tutorial </a>for this. I&#8217;ll quickly go over what&#8217;s needed.<br />
You&#8217;ll need your:</p>
<ul>
&#8211; Radio station name<br />
&#8211; Name of your website<br />
&#8211; URL of your stream (it has to be https)</ul>
<p>Fun fact. I named my station Radio Andreev and whatever I said, Alexa couldn&#8217;t understand. It was looking for Radio Andrea all the time. So, do yourself a favor and name your station something that Alexa can understand. I named my station Radio Tincup, my website is https://radio.iandreev.com and the stream is at https://radio.iandreev.com/myradio.ogg. Generate the JSON from the site above or get this code and change your values. Click the (+) sign to expand. </p>
<pre class="brush: xml; collapse: true; highlight: [4,27,28,29,30]; light: false; title: ; toolbar: true; notranslate">
{
  &quot;interactionModel&quot;: {
    &quot;languageModel&quot;: {
      &quot;invocationName&quot;: &quot;radio tincup&quot;,
      &quot;intents&quot;: &#x5B;
        {
          &quot;name&quot;: &quot;AMAZON.CancelIntent&quot;,
          &quot;samples&quot;: &#x5B;
            &quot;Cancel&quot;
          ]
        },
        {
          &quot;name&quot;: &quot;AMAZON.HelpIntent&quot;,
          &quot;samples&quot;: &#x5B;
            &quot;Help&quot;
          ]
        },
        {
          &quot;name&quot;: &quot;AMAZON.StopIntent&quot;,
          &quot;samples&quot;: &#x5B;
            &quot;Stop&quot;
          ]
        },
        {
          &quot;name&quot;: &quot;Play&quot;,
          &quot;samples&quot;: &#x5B;
            &quot;Ask radio tincup to play radio tincup&quot;,
            &quot;Start radio tincup&quot;,
            &quot;Ask radio tincup to play&quot;,
            &quot;Play radio tincup&quot;
          ]
        },
        {
          &quot;name&quot;: &quot;AMAZON.NavigateHomeIntent&quot;,
          &quot;samples&quot;: &#x5B;]
        },
        {
          &quot;name&quot;: &quot;AMAZON.PauseIntent&quot;,
          &quot;samples&quot;: &#x5B;]
        },
        {
          &quot;name&quot;: &quot;AMAZON.ResumeIntent&quot;,
          &quot;samples&quot;: &#x5B;]
        }
      ],
      &quot;types&quot;: &#x5B;]
    }
  }
}
</pre>
<p>And this is your JavaScript. </p>
<pre class="brush: jscript; collapse: true; highlight: [28,71]; light: false; title: ; toolbar: true; notranslate">
const Alexa = require('ask-sdk-core');
var https = require('https');

const PlayHandler = {
	canHandle(handlerInput)
	{
		return (
			handlerInput.requestEnvelope.request.type === 'LaunchRequest' ||
			(
				handlerInput.requestEnvelope.request.type === 'IntentRequest' &amp;&amp;
				handlerInput.requestEnvelope.request.intent.name === 'Play'
			) ||
			(
				handlerInput.requestEnvelope.request.type === 'IntentRequest' &amp;&amp;
				handlerInput.requestEnvelope.request.intent.name === 'AMAZON.ResumeIntent'
			)
		);
	},
	handle(handlerInput)
	{
		return handlerInput.responseBuilder
			.addDirective({
				type: 'AudioPlayer.Play',
				playBehavior: 'REPLACE_ALL',
				audioItem:{
					stream:{
						token: '0',
						url: 'https://radio.iandreev.com/myradio.ogg',
						offsetInMilliseconds: 0
					}
				}
			})
			.getResponse();
	}
};

const PauseStopHandler = {
	canHandle(handlerInput)
	{
		return (
				handlerInput.requestEnvelope.request.type === 'IntentRequest' &amp;&amp;
				(
					handlerInput.requestEnvelope.request.intent.name === 'AMAZON.CancelIntent' ||
					handlerInput.requestEnvelope.request.intent.name === 'AMAZON.StopIntent'
				)
			) ||
			(
				handlerInput.requestEnvelope.request.type === 'IntentRequest' &amp;&amp;
				handlerInput.requestEnvelope.request.intent.name === 'AMAZON.PauseIntent'
			);
	},
	handle(handlerInput)
	{
		return handlerInput.responseBuilder
			.addDirective({
				type: 'AudioPlayer.ClearQueue',
				clearBehavior: 'CLEAR_ALL'
			})
			.getResponse();
	}
};

const HelpIntentHandler = {
	canHandle(handlerInput)
	{
		return handlerInput.requestEnvelope.request.type === 'IntentRequest' &amp;&amp;
			handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent';
	},
	handle(handlerInput)
	{
		const speechText = 'You can say Play, Stop or Resume. For more information please visit radio dot iandreev dot com';
		return handlerInput.responseBuilder
			.speak(speechText)
			.getResponse();
	}
};

const SessionEndedRequestHandler = {
	canHandle(handlerInput)
	{
		return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
	},
	handle(handlerInput)
	{
		return handlerInput.responseBuilder.getResponse();
	}
};

const IntentReflectorHandler = {
	canHandle(handlerInput)
	{
		return handlerInput.requestEnvelope.request.type === 'IntentRequest';
	},
	handle(handlerInput)
	{
		const intentName = handlerInput.requestEnvelope.request.intent.name;
		const speechText = 'NO INTENT HELP TEXT';
		return handlerInput.responseBuilder
			.speak(speechText)
			.getResponse();
	}
};

const ErrorHandler = {
	canHandle()
	{
		return true;
	},
	handle(handlerInput, error)
	{
		const speechText = `Sorry, I could not understand what you said. Please try again.`;
		return handlerInput.responseBuilder
			.speak(speechText)
			.reprompt(speechText)
			.getResponse();
	}
};

exports.handler = Alexa.SkillBuilders.custom()
	.addRequestHandlers(
		PlayHandler,
		PauseStopHandler,
		HelpIntentHandler,
		SessionEndedRequestHandler,
		IntentReflectorHandler)
	.addErrorHandlers(
		ErrorHandler)
	.lambda();
</pre>
<p>Go to <a href="https://developer.amazon.com" rel="noopener noreferrer" target="_blank">https://developer.amazon.com</a> and log in (or register). Make sure you use the same account in the developer console with the same account that you have your Alexa configured. Once logged in, click on <strong>Alexa </strong>from the menu and then <strong>Alexa Skills Kit</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-02.png"><img decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-02.png" alt="" width="503" height="180" class="aligncenter size-full wp-image-8684" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-02.png 503w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-02-300x107.png 300w" sizes="(max-width: 503px) 100vw, 503px" /></a><br />
Click <strong>Create Skill</strong>. Enter the name of your station and the language.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-03.png"><img decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-03.png" alt="" width="496" height="299" class="aligncenter size-full wp-image-8685" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-03.png 496w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-03-300x181.png 300w" sizes="(max-width: 496px) 100vw, 496px" /></a><br />
Choose a <strong>Custom </strong>model.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-04.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-04.png" alt="" width="416" height="341" class="aligncenter size-full wp-image-8686" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-04.png 416w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-04-300x246.png 300w" sizes="(max-width: 416px) 100vw, 416px" /></a><br />
Choose <strong>Alexa-Hosted</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-05.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-05.png" alt="" width="317" height="275" class="aligncenter size-full wp-image-8687" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-05.png 317w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-05-300x260.png 300w" sizes="(max-width: 317px) 100vw, 317px" /></a><br />
Scroll up and in the top right corner click <strong>Create skill</strong>. After 30-40 seconds, you&#8217;ll be presented with a different screen. On the left side find the <strong>Interfaces </strong>menu, then click on it. Then enable the <strong>Audio Player</strong> on the right.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-06.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-06.png" alt="" width="1061" height="442" class="aligncenter size-full wp-image-8688" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-06.png 1061w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-06-300x125.png 300w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-06-1024x427.png 1024w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-06-768x320.png 768w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-06-585x244.png 585w" sizes="(max-width: 1061px) 100vw, 1061px" /></a><br />
Scroll up and click on <strong>Save Interfaces</strong> first, then <strong>Build Model</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-07.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-07.png" alt="" width="634" height="182" class="aligncenter size-full wp-image-8689" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-07.png 634w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-07-300x86.png 300w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-07-585x168.png 585w" sizes="(max-width: 634px) 100vw, 634px" /></a><br />
Click on the <strong>JSON Editor</strong> on the left, right above <strong>Interfaces</strong>. Once the editor shows up, delete everything there and paste the JSON file.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-08.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-08.png" alt="" width="771" height="204" class="aligncenter size-full wp-image-8690" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-08.png 771w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-08-300x79.png 300w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-08-768x203.png 768w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-08-585x155.png 585w" sizes="(max-width: 771px) 100vw, 771px" /></a><br />
Click <strong>Save Model</strong> then <strong>Build Model</strong> from the top.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-09.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-09.png" alt="" width="597" height="156" class="aligncenter size-full wp-image-8691" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-09.png 597w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-09-300x78.png 300w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-09-585x153.png 585w" sizes="(max-width: 597px) 100vw, 597px" /></a><br />
Click on <strong>Code </strong>from the top and paste the <strong>JavaScript</strong> in the editor.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-10.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-10.png" alt="" width="345" height="285" class="aligncenter size-full wp-image-8692" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-10.png 345w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-10-300x248.png 300w" sizes="(max-width: 345px) 100vw, 345px" /></a><br />
Click <strong>Save </strong>then <strong>Deploy </strong>from the upper right.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-11.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-11.png" alt="" width="404" height="103" class="aligncenter size-full wp-image-8693" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-11.png 404w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-11-300x76.png 300w" sizes="(max-width: 404px) 100vw, 404px" /></a><br />
Click on <strong>Test</strong>, allow access to the microphone and change <strong>Skill testing</strong> from <strong>Off </strong>to <strong>Development</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-12.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-12.png" alt="" width="527" height="220" class="aligncenter size-full wp-image-8694" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-12.png 527w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-12-300x125.png 300w" sizes="(max-width: 527px) 100vw, 527px" /></a><br />
Now, with the mouse hit the microphone icon, hold it there, say <strong>Alexa Play Radio Tincup</strong> and release the button.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-13.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-13.png" alt="" width="503" height="273" class="aligncenter size-full wp-image-8695" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-13.png 503w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-13-300x163.png 300w" sizes="(max-width: 503px) 100vw, 503px" /></a><br />
Here is what I was talking to. Alexa can&#8217;t understand me&#8230;or maybe my mic is bad. If Alexa doesn&#8217;t understand, just type &#8220;<strong>Alexa play Radio Tincup</strong>&#8221; in the text field.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-14.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-14.png" alt="" width="414" height="778" class="aligncenter size-full wp-image-8696" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-14.png 414w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-14-160x300.png 160w" sizes="(max-width: 414px) 100vw, 414px" /></a><br />
You won&#8217;t hear Alexa playing and you won&#8217;t hear any music from the computer, but you&#8217;ll see a JSON response with the valid URL of your OGG stream.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-15.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-15.png" alt="" width="667" height="385" class="aligncenter size-full wp-image-8697" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-15.png 667w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-15-300x173.png 300w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-15-585x338.png 585w" sizes="(max-width: 667px) 100vw, 667px" /></a><br />
At this point you are all set. You can play your music using Alexa. For most people this would be the end. But if you really like to publish your station to be public, then proceed. In the console, click on <strong>Distribution</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/10/P137-16.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/10/P137-16.jpg" alt="" width="508" height="102" class="aligncenter size-full wp-image-8698" srcset="https://blog.andreev.it/wp-content/uploads/2019/10/P137-16.jpg 508w, https://blog.andreev.it/wp-content/uploads/2019/10/P137-16-300x60.jpg 300w" sizes="(max-width: 508px) 100vw, 508px" /></a><br />
You&#8217;ll see a bunch of questions regarding the nature of your station, are you collecting customer information, are you advertising and so on. Just follow the process and hopefully, you&#8217;ll get your station published.</p>
<h1>Cleanup</h1>
<p>You might want to delete the tarballs for the icecast, ices and sox that you&#8217;ve downloaded.</p>
<pre class="brush: bash; title: ; notranslate">
rm -rf /tmp/ice*
rm -rf /tmp/sox*
</pre>
<p>You&#8217;ll also want to make sure that the firewall allows only port 80 and 443. Ports 8000 and 8443 can be, but they don&#8217;t have to be exposed to the Internet.</p>
<pre class="brush: bash; title: ; notranslate">
firewall-cmd --remove-port=8000/tcp --zone=public --permanent
firewall-cmd --remove-port=8443/tcp --zone=public --permanent
firewall-cmd --reload
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.andreev.it/2019/10/aws-centos-create-your-own-radio-station-and-deploy-it-on-alexa-optional/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		<enclosure url="https://patrickdearteaga.com/audio/Battleship.ogg" length="1320786" type="audio/ogg" />
<enclosure url="https://patrickdearteaga.com/audio/Chiptronical.ogg" length="4175911" type="audio/ogg" />
<enclosure url="https://patrickdearteaga.com/audio/Friends.ogg" length="1721081" type="audio/ogg" />
<enclosure url="https://radio.iandreev.com/myradio.ogg" length="0" type="audio/ogg" />

			</item>
		<item>
		<title>Azure: Migrate VMware VMs and physical servers using Azure Migrate: Server Assessment and Server Migration</title>
		<link>https://blog.andreev.it/2019/09/azure-migrate-vmware-vms-and-physical-servers-using-azure-migrate-server-assessment-and-server-migration/</link>
					<comments>https://blog.andreev.it/2019/09/azure-migrate-vmware-vms-and-physical-servers-using-azure-migrate-server-assessment-and-server-migration/#comments</comments>
		
		<dc:creator><![CDATA[Kliment Andreev]]></dc:creator>
		<pubDate>Tue, 24 Sep 2019 18:38:45 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Editor's Pick]]></category>
		<category><![CDATA[ESX/ESXi]]></category>
		<category><![CDATA[ASR]]></category>
		<category><![CDATA[Migrate]]></category>
		<category><![CDATA[VMware]]></category>
		<guid isPermaLink="false">https://blog.andreev.it/?p=5617</guid>

					<description><![CDATA[If you have some on-prem workloads (either virtual or physical servers) and you want&#8230;]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>If you have some on-prem workloads (either virtual or physical servers) and you want to migrate them to Azure, this post might be for you. I&#8217;ll describe how to migrate these servers in Azure using Azure Migrate and Azure Site Recovery. These tools (actual VMs) will have to be installed in your on-prem environment and they&#8217;ll do the heavy lifting for you. Before I begin, there are some pre-requisites. You&#8217;ll need a valid Azure subscription, supported VMware vCenter (v5.5 and above) and resources to install two VMs. On my ESXi host, using thin provisioned storage, I needed 8 CPUs, 32GB RAM and 20GB-80GB thin provisioned storage for <strong>Azure Migrate: Server Assessment</strong> and 8CPUs, 32GB RAM and 40GB disk for <strong>Azure Migrate: Server Migration</strong> tool. It will take much more space if you have a lots of VMs. I have about 15. You&#8217;ll also need a VNET(s) and subnet(s) where you&#8217;ll migrate the VMs.<br />
I&#8217;ll configure that first. I&#8217;ll give you an example of how to migrate a two-tier Windows application (web server + MS SQL server) and a WordPress server running on two CentOS 7 servers.</p>
<h1>Azure VNET/subnet</h1>
<p>Log to your Azure subscription and create a resource group for the migration. I&#8217;ll name mine <strong>rgMigration</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-01.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-01.jpg" alt="" width="732" height="374" class="aligncenter size-full wp-image-8700" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-01.jpg 732w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-01-300x153.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-01-585x299.jpg 585w" sizes="(max-width: 732px) 100vw, 732px" /></a><br />
Then create a new VNET and a subnet where you&#8217;ll migrate your VMs. You can use the same subnets as on-prem but only if you don&#8217;t have a ExpressRoute or VPN between on-prem and Azure. In my case, I have a <a href="https://blog.andreev.it/?p=3250" rel="noopener noreferrer" target="_blank">VPN between my home-lab and Azure</a>, so I have to choose a different subnet. I named my VNET <strong>vnetMigration</strong> and the subnet <strong>subServers</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-02.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-02.jpg" alt="" width="298" height="535" class="aligncenter size-full wp-image-8701" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-02.jpg 298w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-02-167x300.jpg 167w" sizes="(max-width: 298px) 100vw, 298px" /></a></p>
<h1>Azure Migrate</h1>
<p>Once completed, in the Azure portal in the middle upper search field, start typing <strong>migrate </strong>and select <strong>Azure Migrate</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-03.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-03.jpg" alt="" width="590" height="110" class="aligncenter size-full wp-image-8702" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-03.jpg 590w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-03-300x56.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-03-585x110.jpg 585w" sizes="(max-width: 590px) 100vw, 590px" /></a><br />
You&#8217;ll be presented with different options to migrate data, SQL, servers etc. Choose this one that says <strong>migrate servers</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-04.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-04.jpg" alt="" width="347" height="341" class="aligncenter size-full wp-image-8703" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-04.jpg 347w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-04-300x295.jpg 300w" sizes="(max-width: 347px) 100vw, 347px" /></a><br />
Click on <strong>Add tool(s)</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-05.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-05.jpg" alt="" width="335" height="326" class="aligncenter size-full wp-image-8704" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-05.jpg 335w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-05-300x292.jpg 300w" sizes="(max-width: 335px) 100vw, 335px" /></a><br />
You&#8217;ll be prompted to choose the subscription, the resource group, name the project and choose the region. Use whatever suits your needs and click <strong>Next</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-06.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-06.jpg" alt="" width="818" height="530" class="aligncenter size-full wp-image-8705" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-06.jpg 818w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-06-300x194.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-06-768x498.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-06-585x379.jpg 585w" sizes="(max-width: 818px) 100vw, 818px" /></a><br />
There are several tools there, we&#8217;ll use the <strong>Microsoft Migrate: Server Assessment</strong>. Click on it to highlight and click <strong>Next</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-07.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-07.jpg" alt="" width="1025" height="120" class="aligncenter size-full wp-image-8706" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-07.jpg 1025w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-07-300x35.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-07-768x90.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-07-585x68.jpg 585w" sizes="(max-width: 1025px) 100vw, 1025px" /></a><br />
For the migration tool, we&#8217;ll choose Azure Migrate: Server Migration. Select, click <strong>Next </strong>and finally click <strong>Add tool(s)</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-08.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-08.jpg" alt="" width="996" height="119" class="aligncenter size-full wp-image-8707" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-08.jpg 996w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-08-300x36.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-08-768x92.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-08-585x70.jpg 585w" sizes="(max-width: 996px) 100vw, 996px" /></a><br />
It takes about a minute to provision the tools. You&#8217;ll see two tiles on your screen, one for the Assessment tool and the other for the migration.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-09.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-09.jpg" alt="" width="511" height="549" class="aligncenter size-full wp-image-8708" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-09.jpg 511w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-09-279x300.jpg 279w" sizes="(max-width: 511px) 100vw, 511px" /></a><br />
We&#8217;ll use the first tool to assess the on-prem servers. This tool will tell us if we have servers that can be actually moved to Azure cloud and it will recommend the size of those servers. </p>
<h2>Server Assessment</h2>
<p>Click on <strong>Discover </strong>first. You&#8217;ll see another screen where you can download an OVA file for your vCenter. Download the file and deploy the OVA file (v2.19.07.30). I won&#8217;t go into details how to do this, it&#8217;s super easy. Once you have your VM from the OVA file up and running, open the console for that VM, accept the EULA, change the admin password and log in as Administrator with the password that you just specified. You might also want to change the IP from DHCP to static before proceeding. In addition, disable the <strong>IE Enhanced Security Configuration</strong> from the <strong>Server Manager</strong> or you&#8217;ll get bombarded with annoying popups from IE.<br />
On the desktop, there should be two files, one text file with the appliance version and a shortcut to <strong>Microsoft Azure Appliance Configuration Manager</strong>. Accept the license terms for the appliance.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-10.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-10.jpg" alt="" width="558" height="243" class="aligncenter size-full wp-image-8709" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-10.jpg 558w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-10-300x131.jpg 300w" sizes="(max-width: 558px) 100vw, 558px" /></a><br />
Wait for the appliance to do the pre-flight checks and then install <strong>VMware vSphere Virtual Disk Development Kit</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-11.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-11.jpg" alt="" width="522" height="468" class="aligncenter size-full wp-image-8710" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-11.jpg 522w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-11-300x269.jpg 300w" sizes="(max-width: 522px) 100vw, 522px" /></a><br />
Pretty much, you&#8217;ll have to download a ZIP file from VMware site, extract the ZIP and put it under C:\Program Files\VMWare\VMWare Virtual Disk Development Kit.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-12.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-12.jpg" alt="" width="408" height="221" class="aligncenter size-full wp-image-8711" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-12.jpg 408w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-12-300x163.jpg 300w" sizes="(max-width: 408px) 100vw, 408px" /></a><br />
Click <strong>Verify and Install</strong> and <strong>Continue</strong>. Then, login to Azure portal from the appliance to register it.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-13.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-13.jpg" alt="" width="537" height="288" class="aligncenter size-full wp-image-8712" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-13.jpg 537w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-13-300x161.jpg 300w" sizes="(max-width: 537px) 100vw, 537px" /></a><br />
Fill out the subscription, specify the migration project and enter a name for this appliance. Click <strong>Register</strong> and once successfully registered click <strong>Continue</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-14.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-14.jpg" alt="" width="571" height="539" class="aligncenter size-full wp-image-8713" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-14.jpg 571w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-14-300x283.jpg 300w" sizes="(max-width: 571px) 100vw, 571px" /></a><br />
Specify the vCenter where your VMs reside, enter the username and password and click to <strong>Validate Connection</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-15.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-15.jpg" alt="" width="568" height="481" class="aligncenter size-full wp-image-8714" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-15.jpg 568w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-15-300x254.jpg 300w" sizes="(max-width: 568px) 100vw, 568px" /></a><br />
Finally if everything is OK, click on <strong>Save and start discovery</strong>.<br />
<em>NOTE from the appliance: You will be able to review the discovered machines on the Azure portal and create as-on-premises assessments within 15 minutes. Collection of performance data will be initiated and it is recommended that you create performance-based assessments after 24-hours.</em><br />
It&#8217;s important to leave the appliance running for some time so it can properly determine the usage and size the destination VM for you. If you already know what size your VM will be in Azure, you don&#8217;t have to worry about this.<br />
Now, go back to Azure portal and find the <strong>Azure Migrate</strong> service. Click on <strong>Servers </strong>and then on <strong>Discovered servers</strong> under <strong>Assessment tools</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-16.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-16.jpg" alt="" width="673" height="358" class="aligncenter size-full wp-image-8715" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-16.jpg 673w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-16-300x160.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-16-585x311.jpg 585w" sizes="(max-width: 673px) 100vw, 673px" /></a><br />
You&#8217;ll see a list of all servers in your vCenter and their specs. We&#8217;ll create a new assessment group for two Linux servers that I have (apache and mysql) and that are part of my local WordPress installation.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-17.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-17.jpg" alt="" width="998" height="535" class="aligncenter size-full wp-image-8716" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-17.jpg 998w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-17-300x161.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-17-768x412.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-17-585x314.jpg 585w" sizes="(max-width: 998px) 100vw, 998px" /></a><br />
Then, create an assessment for that same group from the top menu.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-18.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-18.jpg" alt="" width="495" height="162" class="aligncenter size-full wp-image-8717" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-18.jpg 495w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-18-300x98.jpg 300w" sizes="(max-width: 495px) 100vw, 495px" /></a><br />
Make sure you change the assessment properties. That&#8217;s where you specify the region. Just click on <strong>View all</strong> and change the settings there.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-19.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-19.jpg" alt="" width="890" height="533" class="aligncenter size-full wp-image-8718" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-19.jpg 890w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-19-300x180.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-19-768x460.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-19-585x350.jpg 585w" sizes="(max-width: 890px) 100vw, 890px" /></a><br />
Now if you go back to the Azure Migrate, you&#8217;ll see that you have one group and one assessment.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-20.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-20.jpg" alt="" width="437" height="392" class="aligncenter size-full wp-image-8719" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-20.jpg 437w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-20-300x269.jpg 300w" sizes="(max-width: 437px) 100vw, 437px" /></a><br />
Click on the Groups and then on the actual group. You&#8217;ll see something like this.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-21.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-21.jpg" alt="" width="462" height="205" class="aligncenter size-full wp-image-8720" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-21.jpg 462w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-21-300x133.jpg 300w" sizes="(max-width: 462px) 100vw, 462px" /></a><br />
If you want to see what your server is doing in terms of connections to others servers over TCP/UDP, you have to install the agent. It&#8217;s not necessary, but you&#8217;ll see the dependencies. It&#8217;s useful when you migrate some servers as a group and then you realize that you need to migrate another server because there is a dependency.</p>
<h3>Dependencies agent</h3>
<p>Click on the link <strong>Requires agent installation</strong> and you&#8217;ll see this page. Pretty much you have to install two agents on each server and configure them. But, first you have to configure the <strong>OMS Workspace</strong> that gathers metadata from the VMs.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-22.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-22.jpg" alt="" width="1095" height="527" class="aligncenter size-full wp-image-8721" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-22.jpg 1095w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-22-300x144.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-22-1024x493.jpg 1024w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-22-768x370.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-22-585x282.jpg 585w" sizes="(max-width: 1095px) 100vw, 1095px" /></a><br />
Click on <strong>Configure OMS workspace</strong> first. Type a name a region and click <strong>Configure </strong>at the bottom.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-23.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-23.jpg" alt="" width="300" height="243" class="aligncenter size-full wp-image-8722" /></a></p>
<h4>Linux</h4>
<p>Download both files. You&#8217;ll get redirected to github for the first agent. Download <strong>omsagent-1.11.0-9.universal.x64.sh</strong> for a 64-bit Linux OS or whatever is the latest version. This is a bash script file with an embedded tar binary file. Transfer it to the Linux box, make sure it&#8217;s executable and run the script. Check this <a href="https://docs.microsoft.com/en-us/system-center/scom/manage-install-crossplat-agent-cmdline?view=sc-om-1807" rel="noopener noreferrer" target="_blank">link </a>for your version of Linux/Unix. Make sure you specify the Workspace ID and the Workspace Key, which you can get at the bottom of the page from the <strong>Dependencies </strong>screenshot (see the previous screenshot above).</p>
<pre class="brush: bash; title: ; notranslate">
wget https://github.com/microsoft/OMS-Agent-for-Linux/releases/download/OMSAgent_v1.11.0-9/omsagent-1.11.0-9.universal.x64.sh
chmod +x omsagent-1.11.0-9.universal.x64.sh
./omsagent-1.11.0-9.universal.x64.sh --install --enable-opsmgr -w &lt;workspaceID&gt; -s &lt;workspaceKey&gt;
</pre>
<p>You should see a message saying <strong>Shell bundle exiting with code 0</strong>.<br />
For the second agent, download it from the Microsoft site, change the permission to execute and run.</p>
<pre class="brush: bash; title: ; notranslate">
wget http://aka.ms/dependencyagentlinux -O InstallDependencyAgent-Linux64.bin
chmod +x InstallDependencyAgent-Linux64.bin
./InstallDependencyAgent-Linux64.bin
</pre>
<p>Type <strong>YES </strong>when prompted and you should be good.</p>
<h4>Windows</h4>
<p>Download both files (<strong>MMASetup-AMD64.exe</strong> and <strong>InstallDependencyAgent-Windows.exe</strong>). Install on each server. For the MMA agent, check to connect the agent to <strong>Azure Log Analytics (OMS)</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-24.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-24.jpg" alt="" width="510" height="392" class="aligncenter size-full wp-image-8723" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-24.jpg 510w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-24-300x231.jpg 300w" sizes="(max-width: 510px) 100vw, 510px" /></a><br />
Enter the Workspace ID and the key and choose Azure Commericial.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-25.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-25.jpg" alt="" width="511" height="395" class="aligncenter size-full wp-image-8724" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-25.jpg 511w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-25-300x232.jpg 300w" sizes="(max-width: 511px) 100vw, 511px" /></a><br />
Installing the dependency agent is even easier, just double-click the EXE and accept the agreement. From the <strong>Discovered servers</strong> list, click on the server where it says <strong>View dependencies</strong> and you&#8217;ll something like this.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-26.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-26.png" alt="" width="661" height="469" class="aligncenter size-full wp-image-8725" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-26.png 661w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-26-300x213.png 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-26-585x415.png 585w" sizes="(max-width: 661px) 100vw, 661px" /></a><br />
Click on each block to see more details.</p>
<h2>Server Migration</h2>
<p>Once we have all the pre-requisites in place and we are all confident in the assessment based on the confidence rating, we can proceed with the migration.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-27.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-27.jpg" alt="" width="847" height="223" class="aligncenter size-full wp-image-8726" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-27.jpg 847w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-27-300x79.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-27-768x202.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-27-585x154.jpg 585w" sizes="(max-width: 847px) 100vw, 847px" /></a><br />
Now, you can do the migration within <strong>Azure Migrate: Server Assessment</strong> tool. Just click on <strong>Discovered Servers</strong> under the tool and click <strong>Replicate </strong>from the menu.<br />
Specify the type of the hypervisor and the on-prem appliance.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-28.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-28.jpg" alt="" width="444" height="290" class="aligncenter size-full wp-image-8727" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-28.jpg 444w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-28-300x196.jpg 300w" sizes="(max-width: 444px) 100vw, 444px" /></a><br />
As you can see from the appliance suffix, the migration option of the assessment tool is in preview. You can proceed further. In the screenshot below, I&#8217;ll be migrating my Linux servers.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-29.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-29.png" alt="" width="819" height="587" class="aligncenter size-full wp-image-8728" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-29.png 819w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-29-300x215.png 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-29-768x550.png 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-29-585x419.png 585w" sizes="(max-width: 819px) 100vw, 819px" /></a><br />
You just have to specify where you want your servers migrated.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-30.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-30.jpg" alt="" width="831" height="468" class="aligncenter size-full wp-image-8729" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-30.jpg 831w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-30-300x169.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-30-768x433.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-30-585x329.jpg 585w" sizes="(max-width: 831px) 100vw, 831px" /></a><br />
Choose the size of the servers, the disk size and you can proceed.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-31.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-31.jpg" alt="" width="684" height="108" class="aligncenter size-full wp-image-8730" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-31.jpg 684w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-31-300x47.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-31-585x92.jpg 585w" sizes="(max-width: 684px) 100vw, 684px" /></a><br />
This is probably the way to go, but because it&#8217;s in preview, I&#8217;ll explain the old way too.<br />
Under the migration tool, click <strong>Discover</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-32.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-32.jpg" alt="" width="435" height="385" class="aligncenter size-full wp-image-8731" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-32.jpg 435w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-32-300x266.jpg 300w" sizes="(max-width: 435px) 100vw, 435px" /></a><br />
Specify where do you want your VMs migrated. This is an important step. Click on <strong>Create resources</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-33.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-33.jpg" alt="" width="502" height="400" class="aligncenter size-full wp-image-8732" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-33.jpg 502w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-33-300x239.jpg 300w" sizes="(max-width: 502px) 100vw, 502px" /></a><br />
Finish step 1. Download the OVA and install it in your vCenter. Same as with the previous OVA, log to the console, and change the IP to static. First, you&#8217;ll be prompted to name the appliance.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-34.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-34.jpg" alt="" width="635" height="179" class="aligncenter size-full wp-image-8733" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-34.jpg 635w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-34-300x85.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-34-585x165.jpg 585w" sizes="(max-width: 635px) 100vw, 635px" /></a><br />
Then log in to Azure portal.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-35.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-35.jpg" alt="" width="443" height="318" class="aligncenter size-full wp-image-8734" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-35.jpg 443w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-35-300x215.jpg 300w" sizes="(max-width: 443px) 100vw, 443px" /></a><br />
Configure the appliance using the Site Recovery icon on the desktop. It&#8217;s gonna ask you to log (again) to Azure and provide the subscription, resource group and the vault. Make sure you choose the vault that&#8217;s provided in the same dialog box where you downloaded the OVA. If you fail to provide the proper vault, you&#8217;ll have to deal with deleting hidden resources etc&#8230;<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-36.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-36.jpg" alt="" width="473" height="463" class="aligncenter size-full wp-image-8735" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-36.jpg 473w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-36-300x294.jpg 300w" sizes="(max-width: 473px) 100vw, 473px" /></a><br />
Next step is to agree to install MySQL server on the appliance and specify the vCenter.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-37.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-37.jpg" alt="" width="735" height="502" class="aligncenter size-full wp-image-8736" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-37.jpg 735w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-37-300x205.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-37-585x400.jpg 585w" sizes="(max-width: 735px) 100vw, 735px" /></a><br />
You should also add the credentials for Windows and Linux servers. For example, my username has full access to all Windows VMs and root has access to all Linux servers.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-38.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-38.jpg" alt="" width="788" height="428" class="aligncenter size-full wp-image-8737" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-38.jpg 788w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-38-300x163.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-38-768x417.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-38-585x318.jpg 585w" sizes="(max-width: 788px) 100vw, 788px" /></a><br />
Once completed, you can go to the Azure Portal and if you click on <strong>Replicate</strong>, you&#8217;ll see that our new appliance showed up.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-39.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-39.jpg" alt="" width="434" height="354" class="aligncenter size-full wp-image-8738" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-39.jpg 434w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-39-300x245.jpg 300w" sizes="(max-width: 434px) 100vw, 434px" /></a><br />
If you are having problems finding out where to register the new appliance, go to the <strong>Replicate </strong>menu. Fill out the pre-requisites and you&#8217;ll get a warning that your appliance is not registered. Click <strong>Finalize registration</strong> from here.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-40.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-40.jpg" alt="" width="912" height="569" class="aligncenter size-full wp-image-8739" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-40.jpg 912w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-40-300x187.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-40-768x479.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-40-585x365.jpg 585w" sizes="(max-width: 912px) 100vw, 912px" /></a><br />
As you can see, with this tool, migrate is grayed. First, we&#8217;ll have to replicate the servers.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-41.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-41.png" alt="" width="429" height="379" class="aligncenter size-full wp-image-8740" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-41.png 429w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-41-300x265.png 300w" sizes="(max-width: 429px) 100vw, 429px" /></a><br />
Fill out the settings and proceed. Make sure you choose the right credentials. I&#8217;ll be replicating Linux instances, so I chose Linux-CREDS. These were defined when we configured the appliance.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-42.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-42.png" alt="" width="806" height="494" class="aligncenter size-full wp-image-8741" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-42.png 806w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-42-300x184.png 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-42-768x471.png 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-42-585x359.png 585w" sizes="(max-width: 806px) 100vw, 806px" /></a><br />
Choose the VMs.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-43.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-43.png" alt="" width="821" height="643" class="aligncenter size-full wp-image-8742" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-43.png 821w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-43-300x235.png 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-43-768x601.png 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-43-585x458.png 585w" sizes="(max-width: 821px) 100vw, 821px" /></a><br />
Choose the VNET, subnet etc&#8230;<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-44.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-44.png" alt="" width="809" height="508" class="aligncenter size-full wp-image-8743" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-44.png 809w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-44-300x188.png 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-44-768x482.png 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-44-585x367.png 585w" sizes="(max-width: 809px) 100vw, 809px" /></a><br />
Choose the rest of the requirements (disk etc&#8230;) and click on <strong>Replicate</strong>.<br />
You can check the status from the tool. Click on <strong>Overview</strong>, then <strong>Replicating machines</strong>, then click the <strong>Other</strong> tab.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-45.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-45.png" alt="" width="1540" height="421" class="aligncenter size-full wp-image-8744" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-45.png 1540w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-45-300x82.png 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-45-1024x280.png 1024w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-45-768x210.png 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-45-1536x420.png 1536w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-45-1170x320.png 1170w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-45-585x160.png 585w" sizes="(max-width: 1540px) 100vw, 1540px" /></a><br />
Once the replication is completed, you can do a <strong>Test migration</strong> or <strong>full migration</strong>. Click on the menu (three dots) on the right of each VM and do a Test migration first. If you a confident, you can do full migration as well.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-46.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-46.jpg" alt="" width="298" height="292" class="aligncenter size-full wp-image-8745" /></a><br />
For a test migration, you have to specify a VNET. When you do a test migration, the original VM stays up and the new VM in Azure has a <strong>-test</strong> suffix. Here I have my apache server test-migrated in Azure.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-47.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-47.jpg" alt="" width="697" height="394" class="aligncenter size-full wp-image-8746" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-47.jpg 697w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-47-300x170.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-47-585x331.jpg 585w" sizes="(max-width: 697px) 100vw, 697px" /></a><br />
And I can access it over my VPN.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-48.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-48.jpg" alt="" width="377" height="195" class="aligncenter size-full wp-image-8747" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-48.jpg 377w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-48-300x155.jpg 300w" sizes="(max-width: 377px) 100vw, 377px" /></a><br />
When you a done, you can <strong>clean up the test migration</strong> from the same menu above and you&#8217;ll get an option to delete the test VM. Finally, once everything is OK, you can do a full migration. Click <strong>Migrate </strong>and you&#8217;ll be all set.<br />
NOTE: If you can&#8217;t RDP to your VM in Azure, it&#8217;s because RDP port was disabled. You can re-enable it from the console. Go to the VM menu and all the way down, click on <strong>Reset password</strong>. Do <strong>Reset configuration only</strong> and after a minute or so, you&#8217;ll be able to RDP.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-49.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-49.jpg" alt="" width="260" height="183" class="aligncenter size-full wp-image-8748" /></a><br />
And if you get this error, The remote computer requires Network Level Authentication&#8230;blah, blah, domain controller.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-50.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-50.jpg" alt="" width="554" height="163" class="aligncenter size-full wp-image-8749" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-50.jpg 554w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-50-300x88.jpg 300w" sizes="(max-width: 554px) 100vw, 554px" /></a><br />
&#8230;then log as local administrator and check the DNS settings. Most likely the DNS settings were messed up when migrating. Here is an example of what I got from my VM in Azure.</p>
<pre class="brush: bash; title: ; notranslate">
  Default Gateway . . . . . . . . . : 192.168.10.1
  DHCP Server . . . . . . . . . . . : 168.63.129.16
  DHCPv6 IAID . . . . . . . . . . . : 352324922
  DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-25-0F-72-AF-00-50-56-B9-F7-0F
  DNS Servers . . . . . . . . . . . : 168.63.129.16
</pre>
<p>Azure assigned a DNS in Azure. Change it to your DNS and you should be OK.</p>
<h3>Migrating a physical server</h3>
<p>In order to migrate a physical server, you&#8217;ll have to follow <a href="https://docs.microsoft.com/en-us/azure/migrate/tutorial-migrate-physical-virtual-machines" rel="noopener noreferrer" target="_blank">these </a>steps. In essence, you&#8217;ll have to log to the Azure Site recovery VM and go to this folder (<strong>C:\ProgramData\ASR\home\svsystems\pushinstallsvc\repository</strong>). Transfer the ASR file to each physical instance. While logged in the appliance, get your key.</p>
<pre class="brush: powershell; title: ; notranslate">
C:\ProgramData\ASR\home\svsystems\bin\genpassphrase.exe -v
</pre>
<p>Don&#8217;t run the EXE on the VM yet. You&#8217;ll have to do it from a command prompt. Open up a command prompt (with admin rights) and execute these lines.</p>
<pre class="brush: powershell; title: ; notranslate">
mkdir c:\temp
cd c:\&lt;path_to_EXE&gt;
ren Mi&lt;hit_TAB_for_autocompletion&gt; MobilityServiceInstaller.exe 
move MobilityServiceInstaller.exe c:\temp
cd c:\temp
MobilityServiceInstaller.exe /q /x:C:\Temp\
UnifiedAgent.exe /Role &quot;MS&quot; /Silent
</pre>
<p>The last command will open a new terminal window and install the agent. Wait to finish and you can exit. Then in the GUI go to <strong>c:\program files (x86)\Microsoft Azure Site Recovery\agent</strong> folder. Double-click the <strong>UnifiedAgentConfigurator.exe</strong> file and enter the IP of your <strong>Site Recovery</strong> appliance and the passphrase that you got from the command above.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-51.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-51.png" alt="" width="910" height="571" class="aligncenter size-full wp-image-8750" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-51.png 910w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-51-300x188.png 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-51-768x482.png 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-51-585x367.png 585w" sizes="(max-width: 910px) 100vw, 910px" /></a><br />
After 10 seconds you should have everything ready.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-52.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-52.png" alt="" width="511" height="190" class="aligncenter size-full wp-image-8751" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-52.png 511w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-52-300x112.png 300w" sizes="(max-width: 511px) 100vw, 511px" /></a><br />
Go back to the portal and in the <strong>Azure Migrate: Server Migration</strong> tool, click on <strong>Replicate</strong>. Under the <strong>Source settings</strong> tab, select that your machines are <strong>NOT</strong> virtualized. Choose the Site Recovery appliance and specify the credentials that will be used to access the physical server.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-53.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-53.png" alt="" width="779" height="431" class="aligncenter size-full wp-image-8752" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-53.png 779w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-53-300x166.png 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-53-768x425.png 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-53-585x324.png 585w" sizes="(max-width: 779px) 100vw, 779px" /></a><br />
You don&#8217;t have an assessment for the physical server, so choose to specify the migrations settings manually. My physical server is called W2012R2.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-54.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-54.png" alt="" width="654" height="456" class="aligncenter size-full wp-image-8753" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-54.png 654w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-54-300x209.png 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-54-585x408.png 585w" sizes="(max-width: 654px) 100vw, 654px" /></a><br />
Choose the subscription, VNET, subnet under <strong>Target settings</strong>. Choose automatic or specify the compute type of your instance under <strong>Compute </strong>tab and do the same for the disks under the next tab.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-55.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-55.png" alt="" width="810" height="184" class="aligncenter size-full wp-image-8754" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-55.png 810w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-55-300x68.png 300w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-55-768x174.png 768w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-55-585x133.png 585w" sizes="(max-width: 810px) 100vw, 810px" /></a><br />
Click <strong>Replicate </strong>when ready. After a minute or so, you can check the status  under <strong>Replicating servers</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/09/P136-56.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/09/P136-56.png" alt="" width="392" height="315" class="aligncenter size-full wp-image-8755" srcset="https://blog.andreev.it/wp-content/uploads/2019/09/P136-56.png 392w, https://blog.andreev.it/wp-content/uploads/2019/09/P136-56-300x241.png 300w" sizes="(max-width: 392px) 100vw, 392px" /></a><br />
&#8230;and same with the other VMs that were replicated, you can do a test migration and full migration. Once you power up the replicated server, make sure you uninstall any HW related software for the arrays, WMI management etc&#8230; And pretty much that&#8217;s it!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.andreev.it/2019/09/azure-migrate-vmware-vms-and-physical-servers-using-azure-migrate-server-assessment-and-server-migration/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>AWS: WordPress using various AWS services and ECS containers</title>
		<link>https://blog.andreev.it/2019/02/147-aws-ecs-wordpress-using-various-aws-services/</link>
					<comments>https://blog.andreev.it/2019/02/147-aws-ecs-wordpress-using-various-aws-services/#respond</comments>
		
		<dc:creator><![CDATA[Kliment Andreev]]></dc:creator>
		<pubDate>Thu, 07 Feb 2019 20:36:58 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Containers]]></category>
		<category><![CDATA[Editor's Pick]]></category>
		<category><![CDATA[containers]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[ECS]]></category>
		<guid isPermaLink="false">https://blog.andreev.it/?p=4417</guid>

					<description><![CDATA[My plan was to see if I can move my blog to use containers&#8230;]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>My plan was to see if I can move my blog to use containers instead of a server, so I decided to try and see if WordPress would work on <a href="https://aws.amazon.com/ecs/" rel="noopener noreferrer" target="_blank">AWS ECS</a>. The result is mixed. While I was able to run WordPress without any issues, the performance wasn&#8217;t that good and I had problems figuring out when to scale in and out. I wouldn&#8217;t say that WordPress architecture is not meant to be containerized, but there were some challenges along the way. So, use this post more as a guide for ECS and how to containerize an application, not as a guide on making WordPress work as a container.</p>
<h1>Pre-requisites</h1>
<p>In order to make a Docker image and upload it to the AWS Docker Registry (ECR), we&#8217;ll need a Linux machine (I am using CentOS), Docker, AWS CLI and AWS ECS CLI installed. You can see how to install Docker in my other <a href="https://blog.andreev.it/?p=4208" rel="noopener noreferrer" target="_blank">post</a>. Same for AWS CLI, you can use one of my earlier <a href="https://blog.andreev.it/?p=1905" rel="noopener noreferrer" target="_blank">guides</a>. And for installing AWS ECS CLI, you can visit the official AWS <a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_CLI_installation.html" rel="noopener noreferrer" target="_blank">page</a>.<br />
Make sure you get some output for all three commands.</p>
<pre class="brush: bash; highlight: [1,3,5]; title: ; notranslate">
docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
aws --version
aws-cli/1.16.96 Python/2.7.5 Linux/3.10.0-957.5.1.el7.x86_64 botocore/1.12.86
ecs-cli --version
ecs-cli version 1.12.1 (e70f1b1)
</pre>
<h1>EFS file system</h1>
<p>We&#8217;ll use AWS EFS as a shared file system for all containers. The containers will have Apache + PHP7 on the OS partition and the WordPress will be on a NFS file share. That way all containers will write to a same WordPress instance. But before we create that, let&#8217;s create a security group that will allow access to our NFS share.<br />
In my case, the security group looks like this.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-01.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-01.png" alt="" width="1093" height="193" class="aligncenter size-full wp-image-8423" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-01.png 1093w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-01-300x53.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-01-1024x181.png 1024w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-01-768x136.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-01-585x103.png 585w" sizes="(max-width: 1093px) 100vw, 1093px" /></a><br />
The port 2049 is the NFS port. The source subnet 172.17.0.0/16  is the subnet for the containers. When you launch a container, its IP will be in this subnet. The second subnet 172.31.0.0/16 is the subnet of the VPC where the containers reside. Why do we need this subnet? Well, we&#8217;ll have to download the WordPress ZIP file and extract it on the NFS filesystem. Because we can&#8217;t browse the file system from the console, we&#8217;ll have to use a temp instance to transfer the files. Make sure the instance and the EFS file system are in the same AZ. So, create the security group and the EFS filesystem and make sure you assign the security group to the EFS. Mine looks like this.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-02.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-02.jpg" alt="" width="1349" height="795" class="aligncenter size-full wp-image-8424" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-02.jpg 1349w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-02-300x177.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-02-1024x603.jpg 1024w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-02-768x453.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-02-1170x690.jpg 1170w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-02-585x345.jpg 585w" sizes="(max-width: 1349px) 100vw, 1349px" /></a><br />
Once you have the EFS ready, get its DNS name.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-03.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-03.png" alt="" width="810" height="658" class="aligncenter size-full wp-image-8425" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-03.png 810w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-03-300x244.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-03-768x624.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-03-585x475.png 585w" sizes="(max-width: 810px) 100vw, 810px" /></a><br />
Spin up an instance in the same VPC where you created the EFS file system. Download the latest WordPress archive and open it.</p>
<pre class="brush: bash; title: ; notranslate">
cd /tmp
wget https://www.wordpress.org/latest.zip
unzip latest.zip
</pre>
<p>Mount the NFS and unzip the files there. Make sure you put your DNS name here.</p>
<pre class="brush: bash; title: ; notranslate">
mkdir /mnt/nfs
mount -t nfs fs-3b6XXXXX.efs.us-east-1.amazonaws.com:/ /mnt/nfs
cd /tmp
cp -R wordpress/* /mnt/nfs
</pre>
<p>The idea is to get the WordPress extracted in the root of the NFS, so it looks like this.</p>
<pre class="brush: bash; title: ; notranslate">
&#x5B;root@guac nfs]# ls -l /mnt/nfs
total 204
-rw-r--r--.  1 nfsnobody nfsnobody     0 Feb  7 19:13 health.txt
-rw-r--r--.  1 nfsnobody nfsnobody   418 Feb  5 16:14 index.php
-rw-r--r--.  1 nfsnobody nfsnobody 19935 Feb  5 16:14 license.txt
-rw-r--r--.  1 nfsnobody nfsnobody  7415 Feb  5 16:14 readme.html
-rw-r--r--.  1 nfsnobody nfsnobody  6878 Feb  5 16:14 wp-activate.php
drwxr-xr-x.  9 nfsnobody nfsnobody  6144 Feb  5 16:14 wp-admin
-rw-r--r--.  1 nfsnobody nfsnobody   364 Feb  5 16:14 wp-blog-header.php
-rw-r--r--.  1 nfsnobody nfsnobody  1889 Feb  5 16:14 wp-comments-post.php
</pre>
<p>Now, we are ready to create the image.</p>
<h1>Dockerfile</h1>
<p>Here is my Dockerfile that I used to build the image. Make sure you put your EFS DNS in line 17.</p>
<pre class="brush: bash; title: ; notranslate">
FROM alpine:3.8

LABEL maintainer &quot;kliment@andreev.it&quot;

RUN apk update &amp;&amp; apk upgrade &amp;&amp; apk add apache2 &amp;&amp; \
    apk add php7-fpm apache2-proxy bash php7-mysqli &amp;&amp; \
    apk add php7-gd php7-curl nfs-utils &amp;&amp; \
sed -i '/mod_mpm_prefork/s/^/#/' /etc/apache2/httpd.conf &amp;&amp; \
sed -i '/^#.*mod_mpm_event/s/^#//' /etc/apache2/httpd.conf &amp;&amp; \
sed -i '/^#.*slotmem_shm/s/^#//' /etc/apache2/httpd.conf &amp;&amp; \
sed -i '/ServerName www/s/^#//g' /etc/apache2/httpd.conf &amp;&amp; \
sed -i $'/&lt;IfModule dir_module&gt;/a \    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/localhost/htdocs' /etc/apache2/httpd.conf &amp;&amp; \
sed -i 's/DirectoryIndex index.html/DirectoryIndex index.php index.html/' /etc/apache2/httpd.conf &amp;&amp; \
sed -i 's|ErrorLog logs/error.log|ErrorLog /dev/stdout|' /etc/apache2/httpd.conf &amp;&amp; \
sed -i 's|CustomLog logs/access.log combined|CustomLog /dev/stdout combined|' /etc/apache2/httpd.conf &amp;&amp; \
echo 'PidFile /var/run/httpd.pid' &gt;&gt; /etc/apache2/httpd.conf &amp;&amp; \
echo 'fs-3b6XXXXX.efs.us-east-1.amazonaws.com:/       /var/www/localhost/htdocs    nfs     defaults 0 0' &gt;&gt; /etc/fstab

COPY script.sh /usr/sbin/script.sh

EXPOSE 80

CMD &#x5B;&quot;/bin/bash&quot;, &quot;/usr/sbin/script.sh&quot;]
</pre>
<p>I won&#8217;t go into details, the script is self explanatory. First we download the necessary packages, make some changes in httpd.conf and mount the NFS on boot. Each container will expose port 80 and it will run a script on each startup.<br />
Here is the script. It should be in the same directory as the Dockerfile. Change the DNS EFS in line 10.</p>
<pre class="brush: bash; title: ; notranslate">
# Start the PHP-FPM process
/usr/sbin/php-fpm7 -D
status=$?
if &#x5B; $status -ne 0 ]; then
  echo &quot;Failed to start php-fpm7: $status&quot; &gt;&gt; /var/log/script.log
  exit $status
fi

# Mount the NFS share
/bin/mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport fs-3bXXXXX.efs.us-east-1.amazonaws.com:/ /var/www/localhost/htdocs
status=$?
if &#x5B; $status -ne 0 ]; then
  echo &quot;Failed to mount NFS share: $status&quot; &gt;&gt; /var/log/script.log
  exit $status
fi

# Add health check file
/bin/touch /var/www/localhost/htdocs/health.txt

# Change ownership of www root
/bin/chown -R nobody:nobody /var/www/localhost/htdocs

# Start the Apache process
/usr/sbin/httpd -D FOREGROUND
status=$?
if &#x5B; $status -ne 0 ]; then
  echo &quot;Failed to start httpd: $status&quot; &gt;&gt; /var/log/script.log
  exit $status
fi
</pre>
<p>Now, you can build the image.</p>
<pre class="brush: bash; title: ; notranslate">
docker build --rm -t wordpress:1.0 .
</pre>
<h1>ECR</h1>
<p>Once we have the image ready, we can upload it to the ECR (the container registry). Replace XYZ with your AWS account number in lines 3 and 4.</p>
<pre class="brush: bash; title: ; notranslate">
$(aws ecr get-login --no-include-email)
aws ecr create-repository --repository-name wordpress
docker tag wordpress:1.0 XYZ.dkr.ecr.us-east-1.amazonaws.com/wordpress:1.0
docker push XYZ.dkr.ecr.us-east-1.amazonaws.com/wordpress:1.0
</pre>
<p>If you go to ECR, you&#8217;ll see the image there.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-04.jpg"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-04.jpg" alt="" width="1316" height="221" class="aligncenter size-full wp-image-8426" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-04.jpg 1316w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-04-300x50.jpg 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-04-1024x172.jpg 1024w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-04-768x129.jpg 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-04-1170x196.jpg 1170w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-04-585x98.jpg 585w" sizes="(max-width: 1316px) 100vw, 1316px" /></a></p>
<h1>RDS</h1>
<p>We&#8217;ll need a MySQL database for WordPress. But before we create the database, create a security group and allow the following subnets and ports. We&#8217;ll assign this group to the RDS database.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-05.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-05.png" alt="" width="1078" height="205" class="aligncenter size-full wp-image-8427" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-05.png 1078w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-05-300x57.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-05-1024x195.png 1024w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-05-768x146.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-05-585x111.png 585w" sizes="(max-width: 1078px) 100vw, 1078px" /></a><br />
You can create the database now. I&#8217;ll create a MariaDB RDS. Nothing specific here, just make sure it&#8217;s not publicly accessible. I&#8217;ve created the database using CLI. In my case, I use <strong>20GB</strong> storage, <strong>t2.small</strong> instance, the name of the instance is <strong>dbwordpress</strong>, a <strong>MariaDB SQL</strong> instance. The admin username is <strong>dbmaster </strong>with <strong>dbpassword </strong>as password. I&#8217;ve attached the security group <strong>sg-ID</strong> that I just created previously. The DB will in a single AZ and without public access. Finally, I&#8217;ll create a database called <strong>wordpress</strong>.</p>
<pre class="brush: bash; title: ; notranslate">
aws rds create-db-instance --allocated-storage 20 --db-instance-class db.t2.small --db-instance-identifier dbwordpress --engine mariadb --master-username dbmaster --master-user-password dbpassword --vpc-security-group-ids sg-ID --no-multi-az --no-publicly-accessible --db-name wordpress
</pre>
<h1>CloudWatch</h1>
<p>In my Dockerfile, I&#8217;ve changed the httpd.conf file, so all the logs are going to the console. This is the original config.</p>
<pre class="brush: bash; title: ; notranslate">
ErrorLog logs/error.log
CustomLog logs/access.log combined
</pre>
<p>And this is the modified httpd.conf config.</p>
<pre class="brush: bash; title: ; notranslate">
ErrorLog /dev/stdout
CustomLog /dev/stdout combined
</pre>
<p>In CloudWatch go to <strong>Logs </strong>and create a new <strong>Log Group</strong> called <strong>/ecs/WordPress</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-06.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-06.png" alt="" width="536" height="153" class="aligncenter size-full wp-image-8428" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-06.png 536w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-06-300x86.png 300w" sizes="(max-width: 536px) 100vw, 536px" /></a></p>
<h1>ECS</h1>
<p>Go to ECS and create a new cluster. It has to be <strong>EC2 Linux + Networking</strong>. Name the cluster and choose On-Demand Instances.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-07.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-07.png" alt="" width="1226" height="775" class="aligncenter size-full wp-image-8429" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-07.png 1226w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-07-300x190.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-07-1024x647.png 1024w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-07-768x485.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-07-1170x740.png 1170w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-07-585x370.png 585w" sizes="(max-width: 1226px) 100vw, 1226px" /></a><br />
Choose the instance type, 2 instances and the key to log to the instances if needed.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-08.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-08.png" alt="" width="1003" height="772" class="aligncenter size-full wp-image-8430" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-08.png 1003w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-08-300x231.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-08-768x591.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-08-585x450.png 585w" sizes="(max-width: 1003px) 100vw, 1003px" /></a><br />
Select your VPC and for a security group choose or create one that has port 80 allowed from everywhere (0.0.0.0/0). Let&#8217;s call this security group sgECS. You can also create your ECS cluster with CLI.</p>
<pre class="brush: bash; title: ; notranslate">
ecs-cli up --keypair MyKeyPair --instance-type t3.medium  --size 2 --cluster clusterWordPress --capability-iam --security-group sg-ID1 --vpc vpc-ID --subnets subnet-XY1,subnet-XY2 --verbose
</pre>
<p>Where <strong>sg-ID1</strong> is a security group that allows port 80 from 0.0.0.0/0, <strong>vpc-ID</strong> is the ID of your VPC where the RDS and EFS are and choose two subnets from that VPC where the instances will be created. It&#8217;s recommended that the subnets you choose are the same where the RDS and the EFS are located.<br />
Now, we have to create a task that will include the Docker image that we created. We can&#8217;t do that in the console because the NFS mount parameter requires an argument that can&#8217;t be specified there. So, we have to create a JSON file and create the task from CLI. If we would&#8217;ve run the image from a command line, we would have to specify the sys_admin parameter. This parameter can&#8217;t be specified in the task screen, but can be specified in JSON.</p>
<pre class="brush: bash; title: ; notranslate">
docker run --name wordpress --cap-add sys_admin -d wordpress:1.0
</pre>
<p>So, create the following JSON file and save it as <strong>task-wordpress.json</strong>.</p>
<pre class="brush: xml; title: ; notranslate">
{
  &quot;containerDefinitions&quot;: &#x5B;
    {
      &quot;portMappings&quot;: &#x5B;
        {
          &quot;hostPort&quot;: 0,
          &quot;protocol&quot;: &quot;tcp&quot;,
          &quot;containerPort&quot;: 80
        }
      ],
      &quot;linuxParameters&quot;: {
         &quot;capabilities&quot;: {
             &quot;add&quot;: &#x5B;&quot;SYS_ADMIN&quot;]
          }
      },
      &quot;logConfiguration&quot;: {
          &quot;logDriver&quot;: &quot;awslogs&quot;,
          &quot;options&quot;: {
              &quot;awslogs-group&quot;: &quot;/ecs/WordPress&quot;,
              &quot;awslogs-region&quot;: &quot;us-east-1&quot;,
              &quot;awslogs-stream-prefix&quot;: &quot;ecs&quot;
          }
      },
      &quot;memoryReservation&quot;: 1024,
      &quot;volumesFrom&quot;: &#x5B;],
      &quot;image&quot;: &quot;XYZ.dkr.ecr.us-east-1.amazonaws.com/wordpress:1.0&quot;,
      &quot;essential&quot;: true,
      &quot;name&quot;: &quot;cWordPress&quot;
    }
  ],
  &quot;placementConstraints&quot;: &#x5B;],
  &quot;family&quot;: &quot;taskWordPress&quot;,
  &quot;requiresCompatibilities&quot;: &#x5B;
    &quot;EC2&quot;
  ],
  &quot;networkMode&quot;: &quot;bridge&quot;,
  &quot;volumes&quot;: &#x5B;]
}
</pre>
<p>Create the task from CLI.</p>
<pre class="brush: bash; title: ; notranslate">
aws ecs register-task-definition --cli-input-json file://task-wordpress.json
</pre>
<p>Line 6 maps port 0 to port 80 on each container, which means a random port on the host. We can&#8217;t have multiple containers listen on port 80.<br />
Line 13 allows <strong>mount </strong> command to be run from the container, otherwise it will fail. We specify the CloudWatch log group in line 19. Line 24 allows 1GB soft-limit for each container. Replace XYZ in line 26 with you account number. That&#8217;s the Docker image. And we&#8217;ll use a bridge mode.<br />
Once you complete this, you&#8217;ll have your task under <strong>Task Definitions</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-09.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-09.png" alt="" width="610" height="395" class="aligncenter size-full wp-image-8431" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-09.png 610w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-09-300x194.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-09-585x379.png 585w" sizes="(max-width: 610px) 100vw, 610px" /></a></p>
<h1>ELB</h1>
<p>Before we proceed with the ECS, we&#8217;ll have to create a load balancer. But before we create a load balancer, let&#8217;s create a new security group. Let&#8217;s call this security group sgELB. This security group should allow port 80 from everywhere. In addition, because we won&#8217;t be exposing the ECS clusters to the internet and the containers will run Apache on a random port, we have to modify the group for the ECS cluster. So, find the group (sgECS) that you specified when you created the ECS cluster (ecs-cli up command) and modify it so it looks like this. The All Traffic source is the ID of sgELB.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-10.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-10.png" alt="" width="1235" height="214" class="aligncenter size-full wp-image-8432" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-10.png 1235w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-10-300x52.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-10-1024x177.png 1024w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-10-768x133.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-10-1170x203.png 1170w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-10-585x101.png 585w" sizes="(max-width: 1235px) 100vw, 1235px" /></a><br />
You can remove port 22 if you want, but the the traffic from the ELB security group has to be allowed all the traffic. The reason being that the containers can map port 80 to any random port on the host. Technically, you can change the rule from <strong>All Traffic</strong> to <strong>TCP range 1024-65535</strong>.<br />
Now, we can create a new application load balancer. Nothing special here. Choose an Internet facing load balancer, create a listener on port 80, choose two subnets, the same where the ECS EC2 instance were created and choose the security group that allows port 80 (sgELB). For the target group an the health checks, do something like this. Make sure <strong>health.txt</strong> is configured.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-11.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-11.png" alt="" width="859" height="626" class="aligncenter size-full wp-image-8433" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-11.png 859w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-11-300x219.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-11-768x560.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-11-585x426.png 585w" sizes="(max-width: 859px) 100vw, 859px" /></a><br />
Don&#8217;t choose ANYTHING for targets, just click <strong>Review </strong>and <strong>Create</strong>.</p>
<h1>ECS Service</h1>
<p>Almost there&#8230; Go back to ECS and select the task and choose <strong>Create Service</strong> from <strong>Actions</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-12.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-12.png" alt="" width="900" height="396" class="aligncenter size-full wp-image-8434" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-12.png 900w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-12-300x132.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-12-768x338.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-12-585x257.png 585w" sizes="(max-width: 900px) 100vw, 900px" /></a><br />
Fill out the following values.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-13.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-13.png" alt="" width="1142" height="896" class="aligncenter size-full wp-image-8435" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-13.png 1142w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-13-300x235.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-13-1024x803.png 1024w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-13-768x603.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-13-585x459.png 585w" sizes="(max-width: 1142px) 100vw, 1142px" /></a><br />
Fargate won&#8217;t work because SYS_ADMIN flag is not supported. For the <strong>Deployments </strong>and <strong>Task Placement</strong> use the defaults and click <strong>Next Step</strong>.<br />
Choose Application Load Balancer and if you don&#8217;t have the role created (<strong>AWSServiceRoleForECS</strong>), let AWS create one for you. For the Container to load balance, you should see our container there. Just click <strong>Add to load balancer</strong>.<br />
Choose the port and the target group that you created when creating the load balancer.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-14.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-14.png" alt="" width="1250" height="735" class="aligncenter size-full wp-image-8436" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-14.png 1250w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-14-300x176.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-14-1024x602.png 1024w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-14-768x452.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-14-1170x688.png 1170w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-14-585x344.png 585w" sizes="(max-width: 1250px) 100vw, 1250px" /></a><br />
You can leave the rest as defaults and click <strong>Next Step</strong>. Allow auto-scaling by clicking on the second option (<strong>Configure Service Auto Scaling to adjust your service’s desired count</strong>). And then configure the auto-scaling policy. It&#8217;s up to you how you&#8217;ll configure it.<br />
This is how mine looks like.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-15.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-15.png" alt="" width="1198" height="428" class="aligncenter size-full wp-image-8437" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-15.png 1198w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-15-300x107.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-15-1024x366.png 1024w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-15-768x274.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-15-1170x418.png 1170w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-15-585x209.png 585w" sizes="(max-width: 1198px) 100vw, 1198px" /></a><br />
I shouldn&#8217;t be scaling based on CPU, 30% CPU is very low value. Maybe scaling based on Network Bytes In/Out is better. I didn&#8217;t have time to play with this, so this is how my scaling policy looks like.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-16.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-16.png" alt="" width="1302" height="1029" class="aligncenter size-full wp-image-8438" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-16.png 1302w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-16-300x237.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-16-1024x809.png 1024w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-16-768x607.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-16-1170x925.png 1170w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-16-585x462.png 585w" sizes="(max-width: 1302px) 100vw, 1302px" /></a><br />
You can ommit the Scale in policy for the test. Click <strong>Next Step</strong> and click <strong>Create Service</strong>. If it fails because of a namespace error, just go back twice and then forward to create the service.<br />
Once that&#8217;s done, click on the <strong>Clusters</strong>, click the cluster name and then on the <strong>Services </strong>tab. Your service should have a status of <strong>Active</strong>. If you click on <strong>Tasks</strong>, you should see 4 tasks running. Finally, get the DNS name for the load balancer and go to that URL in a browser.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-17.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-17.png" alt="" width="809" height="365" class="aligncenter size-full wp-image-8439" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-17.png 809w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-17-300x135.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-17-768x347.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-17-585x264.png 585w" sizes="(max-width: 809px) 100vw, 809px" /></a><br />
You should see the known WordPress initial page. When asked to configure the database, enter the values that you use when creating the RDS (dbmaster, dbpassword, wordpress and the hostname which can be found as an endpoint in the RDS console).<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-18.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-18.png" alt="" width="827" height="434" class="aligncenter size-full wp-image-8440" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-18.png 827w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-18-300x157.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-18-768x403.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-18-585x307.png 585w" sizes="(max-width: 827px) 100vw, 827px" /></a><br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-19.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-19.png" alt="" width="784" height="561" class="aligncenter size-full wp-image-8441" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-19.png 784w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-19-300x215.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-19-768x550.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-19-585x419.png 585w" sizes="(max-width: 784px) 100vw, 784px" /></a><br />
You should be all set now with a fully functional WordPress site. You can check the ClouwWatch for the Apache logs.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2019/02/P124-20.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2019/02/P124-20.png" alt="" width="1065" height="168" class="aligncenter size-full wp-image-8442" srcset="https://blog.andreev.it/wp-content/uploads/2019/02/P124-20.png 1065w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-20-300x47.png 300w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-20-1024x162.png 1024w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-20-768x121.png 768w, https://blog.andreev.it/wp-content/uploads/2019/02/P124-20-585x92.png 585w" sizes="(max-width: 1065px) 100vw, 1065px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.andreev.it/2019/02/147-aws-ecs-wordpress-using-various-aws-services/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>General: Transfer a domain from 1and1.com to godaddy.com</title>
		<link>https://blog.andreev.it/2013/12/transfer-a-domain-from-1and1-com-to-godaddy-com/</link>
					<comments>https://blog.andreev.it/2013/12/transfer-a-domain-from-1and1-com-to-godaddy-com/#respond</comments>
		
		<dc:creator><![CDATA[Kliment Andreev]]></dc:creator>
		<pubDate>Mon, 16 Dec 2013 16:54:44 +0000</pubDate>
				<category><![CDATA[Editor's Pick]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[1 & 1]]></category>
		<category><![CDATA[domain transfer]]></category>
		<category><![CDATA[GoDaddy]]></category>
		<guid isPermaLink="false">http://blog.iandreev.com/?p=981</guid>

					<description><![CDATA[In this post I&#8217;ll describe the current procedure of migrating a domain that&#8217;s registered&#8230;]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>In this post I&#8217;ll describe the current procedure of migrating a domain that&#8217;s registered and hosted at <a href="http://www.1and1.com" target="_blank" rel="noopener noreferrer">1and1.com</a> to <a href="http://www.godaddy.com" target="_blank" rel="noopener noreferrer">godaddy.com</a>. The reason for my migration is simple. I just want to move all my registered domains to godaddy.com and consolidate them. In addition, since I purchased some <a href="http://en.wikipedia.org/wiki/Virtual_private_server" target="_blank" rel="noopener noreferrer">VPS</a>, I&#8217;ve decided to migrate my stuff to a full-blown server instead of renting web hosting from 1and1.com</p>
<p>First log to your 1and1.com domain panel and click <strong>Manage domains</strong>.</p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-01.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-01.png" alt="" width="918" height="267" class="aligncenter size-full wp-image-6801" /></a></p>
<p>Select the domain that you want to transfer (in my case iandreev.com), click <strong>Transfers</strong> and choose <strong>Lock/Unlock</strong> option.</p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-02.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-02.png" alt="" width="763" height="223" class="aligncenter size-full wp-image-6802" /></a></p>
<p>Select <strong>Unlock</strong>.</p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-03.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-03.png" alt="" width="688" height="297" class="aligncenter size-full wp-image-6803" /></a></p>
<p>ICANN regulations prohibit transferring domain names (except .au) that were registered or previously transferred in the last 60 days, so if you already transferred your domain in the past two months, you won&#8217;t be able to do so.</p>
<p>Back in the domain panel, select the domain again and click <strong>Info</strong>.</p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-04.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-04.png" alt="" width="917" height="240" class="aligncenter size-full wp-image-6855" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-04.png 917w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-04-300x79.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-04-768x201.png 768w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-04-585x153.png 585w" sizes="(max-width: 917px) 100vw, 917px" /></a></p>
<p>You should see something similar to this. The most important thing here is the last line <strong>&#8220;Auth code.com&#8221;</strong> and its value.</p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-05.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-05.png" alt="" width="475" height="292" class="aligncenter size-full wp-image-6837" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-05.png 475w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-05-300x184.png 300w" sizes="(max-width: 475px) 100vw, 475px" /></a></p>
<p>Log to your account at go daddy.com and go to this link.</p>
<p><a href="http://www.godaddy.com/domains/domain-transfer.aspx">http://www.godaddy.com/domains/domain-transfer.aspx</a></p>
<p>When you see this page:<br />
<a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-06.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-06.png" alt="" width="701" height="294" class="aligncenter size-full wp-image-6838" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-06.png 701w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-06-300x126.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-06-585x245.png 585w" sizes="(max-width: 701px) 100vw, 701px" /></a></p>
<p>Type the domain name that you want to transfer and click <strong>Go</strong>. At the top, you&#8217;ll see the domain name, just verify it and click <strong>Proceed to Checkout</strong>.</p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-07.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-07.png" alt="" width="734" height="347" class="aligncenter size-full wp-image-6839" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-07.png 734w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-07-300x142.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-07-585x277.png 585w" sizes="(max-width: 734px) 100vw, 734px" /></a></p>
<p>You&#8217;ll get some offers but they are not worth it, so just skip this step and click <strong>Continue</strong>.</p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-08.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-08.png" alt="" width="720" height="533" class="aligncenter size-full wp-image-6840" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-08.png 720w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-08-300x222.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-08-585x433.png 585w" sizes="(max-width: 720px) 100vw, 720px" /></a></p>
<p>Review the current order and pay the transfer fees.</p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-09.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-09.png" alt="" width="1067" height="584" class="aligncenter size-full wp-image-6841" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-09.png 1067w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-09-300x164.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-09-1024x560.png 1024w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-09-768x420.png 768w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-09-585x320.png 585w" sizes="(max-width: 1067px) 100vw, 1067px" /></a></p>
<p>Once your payment is approved, usually instantly click on <strong>Domain Name</strong> image.</p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-10.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-10.png" alt="" width="995" height="522" class="aligncenter size-full wp-image-6842" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-10.png 995w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-10-300x157.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-10-768x403.png 768w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-10-585x307.png 585w" sizes="(max-width: 995px) 100vw, 995px" /></a></p>
<p>Within a minute or two, you’ll receive this e-mail, so make sure you have access to the mailbox that was used when your domain was registered.</p>
<pre class="brush: plain; title: ; notranslate">
Kliment Andreev, approve your transfer request.

====================================================================
DOMAIN NAME TRANSFER - Initial Authorization for Registrar Transfer
====================================================================

Re: Transfer of IANDREEV.COM

Dear Kliment Andreev,

GoDaddy received a request on December 09, 2013 for us to become the new registrar of record.

You received this message because you're listed as the Registered Name Holder or Administrative contact for this domain name. If you're not the Account Holder, or you're transferring the domain to a new owner, please forward this email to the appropriate Account Holder to complete the transfer process.

///////////////////////////////////////////////////////////
IMPORTANT: If the steps below are not completed, the domain name(s) listed above will NOT be transferred to us.
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When authorizing this transfer, you'll be prompted to provide the following Transfer IDs:

Transaction ID: 159067416
Security Code: OYVB28941

To proceed with the transfer, follow the instructions here:
http://support.godaddy.com/help/article/1592?prog_id=GoDaddy&isc=gdbbx2&ci=83387
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

NOTE: After a domain transfer is complete, you cannot transfer it to another registrar for 60 days, apart from transferring back to the original registrar in cases where both registrars so agree or where a decision in the dispute resolution process so directs.

If you DO NOT WANT the transfer to proceed, do not respond to this message.

If you have any questions about this process, contact us by email at support@godaddy.com, or by phone at (480) 505-8877.

Regards,
GoDaddy

Search for a new domain:
http://www.godaddy.com/domains/search.aspx?prog_id=GoDaddy&isc=gdbbx2&ci=83389

Go to My Account:
https://mya.godaddy.com/myrenewals/myrenewals.aspx?shopperid=2529155&prog_id=GoDaddy&myatabs=false&isc=gdbbx2&ci=83385

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright (C) 1999-2013 GoDaddy.com, LLC. All rights reserved.


</pre>
<p>Next, click on <strong>Domains</strong>, then <strong>Transfers</strong> tab and click the green <strong>Launch</strong> image.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-11.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-11.png" alt="" width="980" height="251" class="aligncenter size-full wp-image-6843" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-11.png 980w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-11-300x77.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-11-768x197.png 768w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-11-585x150.png 585w" sizes="(max-width: 980px) 100vw, 980px" /></a></p>
<p>Click on <strong>Authorization code needed</strong>. </p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-12.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-12.png" alt="" width="921" height="180" class="aligncenter size-full wp-image-6844" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-12.png 921w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-12-300x59.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-12-768x150.png 768w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-12-585x114.png 585w" sizes="(max-width: 921px) 100vw, 921px" /></a></p>
<p>Then click <strong>Add now</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-13.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-13.png" alt="" width="662" height="411" class="aligncenter size-full wp-image-6845" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-13.png 662w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-13-300x186.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-13-585x363.png 585w" sizes="(max-width: 662px) 100vw, 662px" /></a></p>
<p>Enter the <strong>Transaction ID</strong> and <strong>Security Code</strong> from the e-mail that you just received.</p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-14.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-14.png" alt="" width="599" height="327" class="aligncenter size-full wp-image-6846" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-14.png 599w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-14-300x164.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-14-585x319.png 585w" sizes="(max-width: 599px) 100vw, 599px" /></a><br />
Click <strong>Next</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-15.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-15.png" alt="" width="654" height="342" class="aligncenter size-full wp-image-6847" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-15.png 654w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-15-300x157.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-15-585x306.png 585w" sizes="(max-width: 654px) 100vw, 654px" /></a></p>
<p>When prompted for the <strong>Authorization Code</strong>, enter the code from 1and1.com (Info button).</p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-16.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-16.png" alt="" width="665" height="423" class="aligncenter size-full wp-image-6848" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-16.png 665w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-16-300x191.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-16-585x372.png 585w" sizes="(max-width: 665px) 100vw, 665px" /></a></p>
<p>You’ll see a short notice that the domain transfer is in process, but you’ll end up with a prompt to enter the <strong>Authorization Code</strong> again. </p>
<p>Just hit F5 and you’ll see this.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-17.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-17.png" alt="" width="846" height="165" class="aligncenter size-full wp-image-6849" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-17.png 846w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-17-300x59.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-17-768x150.png 768w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-17-585x114.png 585w" sizes="(max-width: 846px) 100vw, 846px" /></a></p>
<p>After 2 hours I received an email from 1and1.com.</p>
<pre class="brush: plain; title: ; notranslate">
Dear Mr. Andreev,

Thank you for your transfer request for your domain iandreev.com
on 2013-12-10 04:01:39.We are happy to provide you with more
detailed information.

The current transfer status of your domain is: off.

Do you want to revoke the transfer of your domain? Simply change the
status to &quot;Lock&quot; in your 1&amp;amp;1 Control Panel. To do so, go to:

https://www.1and1.com/login

If you still want your domain to be transferred, please make sure the
status of your domain is set to &quot;Unlock&quot;. The transfer of your domain
will then be completed automatically on 2013-12-15 04:01:39.

If your domain is locked, the transfer will be automatically canceled on
2013-12-14 04:01:39.

IMPORTANT: Please note that upon the domain transfer your domain as
well as all associated rights will be transferred to the new registrant -
thus to the new owner of the domain. This means that your domain, together
will all subdomains and e-mail accounts using this domain name, will be
removed from your contract.

Therefore, please make sure that you only agree to this domain transfer
if you have initiated it yourself or if you have already agreed on all
details with the new registrant.

Please find below a step-by-step instruction on how to lock or unlock
your domain for the transfer:

1. Log in to your 1&amp;amp;1 Control Panel with your customer data at
https://www.1and1.com/login.

2. Select the package containing the respective domain. Click on &quot;Domains&quot;
under &quot;Domains &amp;amp; Web Space&quot;. You can lock or unlock your domain by selecting
the domain from the list and then clicking on &quot;Transfers&quot;/&quot;Lock/Unlock&quot;.

If you cannot log in to your 1&amp;amp;1 Control Panel, please contact our
1&amp;amp;1 Customer Support via the following e-mail address:

support@1and1.com.

Please note our Terms and Conditions at https://www.1and1.com/Gtc. Please
refer to our FAQ section at http://faq.1and1.com/domains/domain_xfers/xfer_of_reg/index.html
for further information.

Yours sincerely,

1&amp;1 Internet Inc.


</pre>
<p>The only important part in this e-mail is this “<em>The transfer of your domain will then be completed automatically on 2013-12-15 04:01:39”</em>. If everything goes well, after a week you’ll receive an email from godaddy.com that looks like this.</p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-18.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-18.png" alt="" width="663" height="532" class="aligncenter size-full wp-image-6850" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-18.png 663w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-18-300x241.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-18-585x469.png 585w" sizes="(max-width: 663px) 100vw, 663px" /></a><br />
Click on <strong>Go to My Account</strong> and once you log in, click on <strong>Domains</strong>. Select the domain that you just transferred, click on the <strong>Nameservers</strong> icon and then click on <strong>Set Nameservers</strong>.  </p>
<p><a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-19.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-19.png" alt="" width="1018" height="471" class="aligncenter size-full wp-image-6851" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-19.png 1018w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-19-300x139.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-19-768x355.png 768w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-19-585x271.png 585w" sizes="(max-width: 1018px) 100vw, 1018px" /></a></p>
<p>Click on <strong>Standard</strong> to change the DNS servers to GoDaddy’s DNS servers.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2013/12/P034-20.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2013/12/P034-20.png" alt="" width="634" height="450" class="aligncenter size-full wp-image-6852" srcset="https://blog.andreev.it/wp-content/uploads/2013/12/P034-20.png 634w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-20-300x213.png 300w, https://blog.andreev.it/wp-content/uploads/2013/12/P034-20-585x415.png 585w" sizes="(max-width: 634px) 100vw, 634px" /></a></p>
<p>Mind that when you are changing the DNS, all the sub domains that you had with 1 and 1 will be gone. You’ll have to recreate them under Go Daddy’s panel, so make sure that you have a migration plan for all of your sub domains and the data associated.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.andreev.it/2013/12/transfer-a-domain-from-1and1-com-to-godaddy-com/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>General: Tips &#038; Tricks and one-liners (Part I)</title>
		<link>https://blog.andreev.it/2011/12/prevent-root-login-in-ssh/</link>
					<comments>https://blog.andreev.it/2011/12/prevent-root-login-in-ssh/#respond</comments>
		
		<dc:creator><![CDATA[Kliment Andreev]]></dc:creator>
		<pubDate>Sat, 03 Dec 2011 21:26:30 +0000</pubDate>
				<category><![CDATA[Editor's Pick]]></category>
		<category><![CDATA[General]]></category>
		<guid isPermaLink="false">http://blog.iandreev.com/?p=134</guid>

					<description><![CDATA[Part II, Part III, Part IV. MySQL Backup/Restore BACKUP mysqldump -u &#60;username&#62; -p &#60;password&#62;&#8230;]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p><a href="https://blog.andreev.it/?p=203" rel="noopener noreferrer" target="_blank">Part II</a>, <a href="https://blog.andreev.it/?p=5117" rel="noopener noreferrer" target="_blank">Part III</a>, <a href="https://blog.andreev.it/?p=9343" rel="noopener noreferrer" target="_blank">Part IV.</p>
<h1>MySQL Backup/Restore</h1>
<p><strong>BACKUP</strong></p>
<pre class="brush: sql; title: ; notranslate">
mysqldump -u &lt;username&gt;  -p &lt;password&gt; databasename &gt; /somewhere/dbname.sql
</pre>
<p>Do not leave space between -p and the password.</p>
<p><strong>RESTORE</strong></p>
<pre class="brush: sql; title: ; notranslate">
mysql -u &lt;username&gt;  -p   &lt;password&gt; databasename &lt;  /somewhere/dbname.sql
</pre>
<p><strong>CREATE USER/DATABASE and GRANT RIGHTS</strong></p>
<pre class="brush: sql; title: ; notranslate">
mysql -u adminusername -p
CREATE USER &#039;custom&#039;@&#039;localhost&#039; IDENTIFIED BY &#039;obscure&#039;;
CREATE DATABASE databasename;
GRANT ALL PRIVILEGES ON databasename.* TO &quot;custom&quot;@&quot;localhost&quot; IDENTIFIED BY &quot;obscure&quot;;
FLUSH PRIVILEGES;
</pre>
<h1>FreeBSD update OS and ports</h1>
<p>To update the OS (not upgrade):</p>
<pre class="brush: plain; title: ; notranslate">
freebsd-update fetch
freebsd-update install
</pre>
<p>To update the ports tree:</p>
<pre class="brush: plain; title: ; notranslate">
portsnap fetch
portsnap update
</pre>
<p>Update the actual ports:</p>
<pre class="brush: plain; title: ; notranslate">
portmaster -a
</pre>
<h1>tail under Windows</h1>
<pre class="brush: powershell; title: ; notranslate">
Get-Content -Path &quot;&lt;drive&gt;:\Folder\FileName.extension&quot; -Wait
</pre>
<h1>tcpdump to monitor HTTP traffic</h1>
<p>1. To monitor HTTP traffic including request and response headers and message body:</p>
<pre class="brush: bash; title: ; notranslate">
tcpdump -A -s 0 &#039;tcp port 80 and (((ip&#x5B;2:2] - ((ip&#x5B;0]&amp;amp;0xf)&lt;&lt;2)) - ((tcp&#x5B;12]&amp;amp;0xf0)&gt;&gt;2)) != 0)&#039;
</pre>
<p>2. To monitor HTTP traffic including request and response headers and message body from a particular source:</p>
<pre class="brush: bash; title: ; notranslate">
tcpdump -A -s 0 &#039;src example.com and tcp port 80 and (((ip&#x5B;2:2] - ((ip&#x5B;0]&amp;amp;0xf)&lt;&lt;2)) - ((tcp&#x5B;12]&amp;amp;0xf0)&gt;&gt;2)) != 0)&#039;
</pre>
<p>3. To monitor HTTP traffic including request and response headers and message body from local host to local host:</p>
<pre class="brush: bash; title: ; notranslate">
tcpdump -A -s 0 &#039;tcp port 80 and (((ip&#x5B;2:2] - ((ip&#x5B;0]&amp;amp;0xf)&lt;&lt;2)) - ((tcp&#x5B;12]&amp;amp;0xf0)&gt;&gt;2)) != 0)&#039; -i lo
</pre>
<p>4. To only include HTTP requests, modify “tcp port 80” to “tcp dst port 80” in above commands</p>
<h1>Get the OU for a user or a computer in PowerShell.</h1>
<pre class="brush: powershell; title: ; notranslate">
$comp=Get-ADComputer -identity &lt;computer_name&gt; -properties CanonicalName
</pre>
<pre class="brush: powershell; title: ; notranslate">
$user=Get-ADUser -identity &lt;user_name&gt; -properties CanonicalName
</pre>
<h1>Send e-mail using Python and AWS SES</h1>
<p>Create an index.html file in the same directory where this script will reside called index.html. That will be the body of your e-mail.<br />
In my case index.html looks like this.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;h1&gt;Hello!&lt;/h1&gt;
</pre>
<p>You can comment line #24 below if you don&#8217;t want to see the debug output. I suggest you leave it as is.</p>
<pre class="brush: python; title: ; notranslate">
import smtplib

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

fromaddr = &quot;no-reply@somedomain.com&quot;
toaddr = &quot;kliment.andreev@whatever.com&quot;
EMAIL_HOST = &#039;email-smtp.us-east-1.amazonaws.com&#039;
EMAIL_HOST_USER = &#039;AKIAJUEQQ7DIHJUCKAVA&#039;
EMAIL_HOST_PASSWORD = &#039;AlRPmyef-qAkajSzCtn43YY447rFlJ8GXCBMWyaNide&#039;
EMAIL_PORT = 587

msg = MIMEMultipart(&#039;alternative&#039;)
msg&#x5B;&#039;Subject&#039;] = &quot;AWS TEST&quot;
msg&#x5B;&#039;From&#039;] = fromaddr
msg&#x5B;&#039;To&#039;] = toaddr

html = open(&#039;index.html&#039;).read()

mime_text = MIMEText(html, &#039;html&#039;)
msg.attach(mime_text)

s = smtplib.SMTP(EMAIL_HOST, EMAIL_PORT)
s.set_debuglevel(10)
s.starttls()
s.login(EMAIL_HOST_USER, EMAIL_HOST_PASSWORD)
s.sendmail(fromaddr, toaddr, msg.as_string())
s.quit()
</pre>
<p>If you want to send to multiple recipients, replace the lines #7 and #27 to look like this.</p>
<pre class="brush: python; title: ; notranslate">
toaddr = &quot;kliment.andreev@domain1.com,klimenta@domain2.com,kandreev@domain3.com&quot;
s.sendmail(fromaddr, msg&#x5B;&#039;To&#039;].split(&#039;,&#039;), msg.as_string())
</pre>
<h1>Display remote SSL certificate</h1>
<pre class="brush: bash; title: ; notranslate">
echo | openssl s_client -showcerts -servername blog.andreev.it -connect blog.andreev.it:443 2&gt;/dev/null | openssl x509 -inform pem -noout -text
</pre>
<h1>Windows DNS server &#8211; clear cache</h1>
<p>From an elevated cmd prompt</p>
<pre class="brush: bash; title: ; notranslate">
dnscmd /clearcache
</pre>
<h1>List public IP addresses associated with an instance in AWS</h1>
<pre class="brush: bash; title: ; notranslate">
aws ec2 describe-instances --query &quot;Reservations&#x5B;*].Instances&#x5B;*].PublicIpAddress&quot; --output=text
</pre>
<h1>RHEL\CentOS 7: Limit SSH to specific IPs</h1>
<p>I have a CentOS VM that&#8217;s running behind a pfSense firewall and a NAT rule that forwards all SSH traffic to this VM. So, pretty much my VM is exposed to the public. I saw a lot of scripts trying to penetrate so what I did is, I used the <strong>firewalld </strong>service to restrict SSH to specific IPs. Make sure that you have <strong>firewalld </strong>enabled and running.</p>
<pre class="brush: bash; title: ; notranslate">
systemctl status firewalld
</pre>
<p>Now, add the trusted IPs or ranges. In my case my home network range and a single public IP.</p>
<pre class="brush: bash; title: ; notranslate">
firewall-cmd --zone=&quot;trusted&quot; –-add-source=192.168.1.0/24
firewall-cmd --zone=&quot;trusted&quot; –-add-source=11.12.99.88
</pre>
<p>Add the SSH service to the trusted zone.</p>
<pre class="brush: bash; title: ; notranslate">
firewall-cmd --zone=&quot;trusted&quot; –add-service=ssh
</pre>
<p>Check if everything is OK</p>
<pre class="brush: bash; title: ; notranslate">
firewall-cmd --zone=&quot;trusted&quot; –list-all
</pre>
<pre class="brush: bash; title: ; notranslate">
firewall-cmd –-zone=public –remove-service=ssh
</pre>
<p>Try to access your server from some other IP and you&#8217;ll see you are blocked. In order for these changes to be permanent, you&#8217;ll have to execute all these commands again with the <strong>&#8211;permanent</strong> option.</p>
<pre class="brush: bash; title: ; notranslate">
firewall-cmd --zone=&quot;trusted&quot; –-add-source=192.168.1.0/24 --permanent
firewall-cmd --zone=&quot;trusted&quot; –-add-source=11.12.99.88 --permanent
firewall-cmd --zone=&quot;trusted&quot; –add-service=ssh --permanent
firewall-cmd –-zone=public –remove-service=ssh --permanent
</pre>
<p>Now, the changes will stay across reboots. You can use the same scenario for other services as well.</p>
<h1>Download Oracle JRE from command prompt</h1>
<p>Go to the <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" rel="noopener noreferrer" target="_blank">download </a>page and find the archive that you want to download. Click to accept the agreement and then get the URL of the archive.</p>
<pre class="brush: bash; title: ; notranslate">
wget --header &quot;Cookie: oraclelicense=accept-securebackup-cookie&quot; &lt;URL&gt;
</pre>
<h1>Convert MP3 files to Ogg-Vorbis using sox in all subfolders</h1>
<pre class="brush: bash; title: ; notranslate">
find . -name &#039;*.mp3&#039; -exec bash -c &#039; sox -V3 &quot;$1&quot; &quot;${1%.mp3}.ogg&quot;&#039; -- {} \;
</pre>
<p>Delete all mp3 files after.</p>
<pre class="brush: bash; title: ; notranslate">
find . -name &quot;*.mp3&quot; -exec rm {} \;
</pre>
<h1>Extract a tar archive (tarball) without the head/container directory (folder)</h1>
<p>You have a tarball aaa.tar.gz with the following structure.<br />
<aaa><br />
&#8212;-file1.txt<br />
&#8212;-file2.txt<br />
You want to extract the files to a directory without the top aaa folder.</p>
<pre class="brush: bash; title: ; notranslate">
tar xzvf aaa.tar.gz --strip 1 -C destination_folder
</pre>
<p></aaa></p>
<h1>Samba 4.x, list Windows share, mount Windows share</h1>
<pre class="brush: plain; title: ; notranslate">
sudo mount.cifs -v -o username=my_username,domain=netbios_domain_name,vers=2.1 //host.domain.local/share /mnt
</pre>
<p>If you are unable to write to the mounted folder, specify the user as -o&#8230;vers=2.1,uid=4801105,gid=4800513 which is a user that has rights to that share.</p>
<pre class="brush: plain; title: ; notranslate">
smbclient //host.domain.local/share -U my_username@domain.local -m SMB3 -W netbios_domain_name
</pre>
<h1>Speed up video files x30</h1>
<pre class="brush: bash; title: ; notranslate">
ffmpeg -i input.mov -vf &quot;setpts=(PTS-STARTPTS)/30&quot; -crf 18 output.mov
</pre>
<h1>Replace pattern in file names</h1>
<p>E.g. You want to remove [BBB] from these files 123[BBB]aaa.txt and asd[BBB]123.txt.</p>
<pre class="brush: powershell; title: ; notranslate">
Get-ChildItem *.txt | ForEach { Move-Item -LiteralPath $_.Name $_.Name.Replace(&quot;&#x5B;BBB]&quot;, &quot;&quot;) }
</pre>
<h1>PowerShell &#8211; create TCP listener</h1>
<pre class="brush: powershell; title: ; notranslate">
$Listener = &#x5B;System.Net.Sockets.TcpListener]9999;
$Listener.Start();
# Test the port with telnet
# once completed execute below
$Listener.Stop();
</pre>
<h1>Get the model name of the computer from BIOS</h1>
<pre class="brush: bash; title: ; notranslate">
wmic csproduct get name
</pre>
<h1>uptime in Windows</h1>
<p>Download the zipped EXE <a href="https://blog.andreev.it/wp-content/uploads/2011/12/uptime.zip" rel="noopener noreferrer" target="_blank">here</a>. MD5: e37822139136b6296bc58617fceb010d. Source in C.</p>
<pre class="brush: cpp; title: ; notranslate">
// uptime - shows the uptime on a Windows system
// K.Andreev - 20180803 - BSD Simplified License

#include &quot;stdafx.h&quot;
#include &lt;Windows.h&gt;

int main()
{
DWORD dMilliseconds = GetTickCount();
DWORD dDays = dMilliseconds / 86400000;
DWORD dHours = dMilliseconds / 3600000 - dDays * 24;
DWORD dMinutes = dMilliseconds / 60000 - dHours * 60 - dDays * 1440;
DWORD dTemp = dDays * 86400 - dHours * 3600 - dMinutes * 60;
DWORD dSeconds = dMilliseconds / 1000 - dDays * 86400 - dHours * 3600 - dMinutes * 60;

if (dDays != 0) {
printf(&quot;up %d days, %d hours, %d minutes, %d seconds&quot;, dDays, dHours, dMinutes, dSeconds);
return 0;
}
if (dHours != 0) {
printf(&quot;up %d hours, %d minutes, %d seconds&quot;, dHours, dMinutes, dSeconds);
return 0;
}
if (dMinutes != 0) {
printf(&quot;up %d minutes, %d seconds&quot;, dMinutes, dSeconds);
return 0;
}
printf(&quot;up %d seconds&quot;, dSeconds);

return 0;
}
</pre>
<h1>Replace CRLF in a file, DOS 2 UNIX text format</h1>
<pre class="brush: bash; title: ; notranslate">
sed -i &#039;s/\r//g&#039; /tmp/script.sh
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.andreev.it/2011/12/prevent-root-login-in-ssh/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
