<?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>ECS &#8211; Blog of Kliment Andreev &#8211; A place so I won&#039;t forget things</title>
	<atom:link href="https://blog.andreev.it/tag/ecs/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.andreev.it</link>
	<description></description>
	<lastBuildDate>Mon, 02 Nov 2020 13:39:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<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 fetchpriority="high" 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 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 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>
	</channel>
</rss>
