<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:og="http://ogp.me/ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:schema="http://schema.org/" xmlns:sioc="http://rdfs.org/sioc/ns#" xmlns:sioct="http://rdfs.org/sioc/types#" xmlns:skos="http://www.w3.org/2004/02/skos/core#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" version="2.0" xml:base="http://badzilla.co.uk/">
  <channel>
    <title>Fargate</title>
    <link>http://badzilla.co.uk/</link>
    <description/>
    <language>en</language>
    
    <item>
  <title>Programmatically Create AWS ECR Repository and Commit Docker Image to ECR</title>
  <link>http://badzilla.co.uk/programmatically-create-aws-ecr-repository-and-commit-docker-image-ecr</link>
  <description>
&lt;span&gt;Programmatically Create AWS ECR Repository and Commit Docker Image to ECR&lt;/span&gt;

&lt;span&gt;&lt;span lang="" about="http://badzilla.co.uk/user/1" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;nigel&lt;/span&gt;&lt;/span&gt;

&lt;span&gt;Sat, 07/12/2019 - 07:56&lt;/span&gt;

      &lt;div class="field field--name-field-heading-image-text field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;This is a tutorial for using AWS CLI to programmatically create an AWS ECR repository and then commit a Docker image to that repository. This is the first step in a series of tutorials for creating an automated testing framework in AWS Fargate which can be one step of a DevOps pipeline. &lt;/p&gt;

&lt;p&gt;As an example I am going to use the Docker php:7.2-apache image and to make it a little more complex, add a few more PHP extensions using a new Dockerfile so that my new image will be Drupal 8 compliant. &lt;/p&gt;

&lt;p&gt;Let's get started. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Pull Base Image and Define Dockerfile&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The base php:7.2-apache image needs to be pulled from Docker Hub. Issue the following command. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ docker pull php:&lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache
&lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache: Pulling from library&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;php
000eee12ec04: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
8ae4f9fcfeea: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
60f22fbbd07a: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
ccc7a63ad75f: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
a2427b8dd6e7: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
91cac3b30184: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
d6e40015fc10: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
240e21c03bb4: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
504858e1e4aa: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
9a0523b2d73f: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
e3acb84829f4: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
28a372733f87: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
62ee66cdb80a: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
c3f368ddc7aa: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
Digest: sha256:602bef9acc8d54527ae5b7ee0f16e5cdb6ab81364310f5123b93b95e357f608d
Status: Downloaded newer image &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; php:&lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache
docker.io&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;library&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;php:&lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
php                 &lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache          fec8a1aaffb8        &lt;span style="color: #000000;"&gt;31&lt;/span&gt; hours ago        410MB
lambci&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lambda       go1.x               8d962cde7e27        &lt;span style="color: #000000;"&gt;3&lt;/span&gt; months ago        707MB
sls-docker          latest              8d962cde7e27        &lt;span style="color: #000000;"&gt;3&lt;/span&gt; months ago        707MB&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Yes the docker image is there. Now I need to create a directory for the Dockerfile and a sample index.php file which will prove our image is working. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;mkdir&lt;/span&gt; automated &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; automated&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
By default the Docker php image uses /var/www/html as Apache's docroot. However, I'm going to alter this to something more standard for Drupal web apps - a directory called docroot will be created and will contain a simple index.php containing a call to phpinfo();
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;mkdir&lt;/span&gt; docroot &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;?php phpinfo();"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt; docroot&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;index.php&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
The Dockerfile should now be created and populated. There a number of activities that need to be performed on it. 
&lt;ul&gt;
&lt;li&gt;Reference the base image with a FROM instruction&lt;/li&gt;
&lt;li&gt;Install the libraries that support memcached and graphics manipulation&lt;/li&gt;
&lt;li&gt;Enable memcached PHP extension&lt;/li&gt;
&lt;li&gt;Configure the graphics PHP extension&lt;/li&gt;
&lt;li&gt;Install the graphics PHP extension&lt;/li&gt;
&lt;li&gt;Copy the files in the current directory and below into the Docker image at the /var/www/html ensuring the permissions are correct for the apache user and group&lt;/li&gt;
&lt;li&gt;Set the environment variable AH_SITE_ENVIRONMENT to devops - this is an Acquia Cloud environment variable and only of any significance for those using Acquia as their host - or need a setting in my case to denote that devops is not running on Acquia&lt;/li&gt;
&lt;li&gt;Change the default location for the docroot - that means setting an environment variable and using the sed editor to change the configuration in the sites files&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;Dockerfile&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;FROM php:&lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache
RUN &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get update&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get install&lt;/span&gt; &lt;span style="color: #660033;"&gt;-y&lt;/span&gt; libmemcached-dev zlib1g-dev \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libpng-dev \
    libwebp-dev \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; pecl &lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt; memcached \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; docker-php-ext-enable memcached \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; docker-php-ext-configure gd &lt;span style="color: #660033;"&gt;--with-gd&lt;/span&gt; &lt;span style="color: #660033;"&gt;--with-webp-dir&lt;/span&gt; &lt;span style="color: #660033;"&gt;--with-jpeg-dir&lt;/span&gt; \
       &lt;span style="color: #660033;"&gt;--with-png-dir&lt;/span&gt; &lt;span style="color: #660033;"&gt;--with-zlib-dir&lt;/span&gt; &lt;span style="color: #660033;"&gt;--with-freetype-dir&lt;/span&gt; \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; docker-php-ext-install gd
COPY &lt;span style="color: #660033;"&gt;--chown&lt;/span&gt;=www-data:www-data .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;www&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;html&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.
ENV AH_SITE_ENVIRONMENT devops
ENV APACHE_DOCUMENT_ROOT &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;www&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;html&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot
RUN &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ri&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s!/var/www/html!${APACHE_DOCUMENT_ROOT}!g'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;apache2&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;sites-available&lt;span style="color: #000000; font-weight: bold;"&gt;/*&lt;/span&gt;.conf
RUN &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ri&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s!/var/www/!${APACHE_DOCUMENT_ROOT}!g'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;apache2&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;apache2.conf &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;apache2&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;conf-available&lt;span style="color: #000000; font-weight: bold;"&gt;/*&lt;/span&gt;.conf&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Build the Image, Run the Container&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-07%20at%2012.17.34.png?itok=jwU0kVpn 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/Screenshot%202019-12-07%20at%2012.17.34.png?itok=XLFrcLyd 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/Screenshot%202019-12-07%20at%2012.17.34.png?itok=7J5O5LHx 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/Screenshot%202019-12-07%20at%2012.17.34.png?itok=eCD6F2Tg 2310w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-07%20at%2012.17.34.png?itok=jwU0kVpn" alt="phpinfo" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Once the Dockerfile is complete, it is built with
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;docker build &lt;span style="color: #660033;"&gt;-t&lt;/span&gt; d8codebase .&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
and to confirm it's built correctly:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
d8codebase          latest              c2193f9778a6        &lt;span style="color: #000000;"&gt;33&lt;/span&gt; minutes ago      439MB
&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;&lt;/span&gt;none&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;              &lt;span style="color: #000000; font-weight: bold;"&gt;&lt;&lt;/span&gt;none&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;              2a71964685e0        &lt;span style="color: #000000;"&gt;2&lt;/span&gt; hours ago         432MB
php                 &lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache          fec8a1aaffb8        &lt;span style="color: #000000;"&gt;35&lt;/span&gt; hours ago        410MB
lambci&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lambda       go1.x               8d962cde7e27        &lt;span style="color: #000000;"&gt;3&lt;/span&gt; months ago        707MB
sls-docker          latest              8d962cde7e27        &lt;span style="color: #000000;"&gt;3&lt;/span&gt; months ago        707MB&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Great it's there. Now to spin up the container. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;docker run &lt;span style="color: #660033;"&gt;-d&lt;/span&gt; &lt;span style="color: #660033;"&gt;-p&lt;/span&gt; &lt;span style="color: #000000;"&gt;8080&lt;/span&gt;:&lt;span style="color: #000000;"&gt;80&lt;/span&gt; d8codebase&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Note I am mapping port 8080 to the container's port 80 which probably won't be pertinent to you. Long story I will try to make short. I write my blogs on my Macbook on a local network in the 192.168 range assigned by my ISP's hub. But I develop and test all the practical work in my blogs in a VM in the IP 10. range. Routing between 192.168 and 10. is difficult without port forwarding - so I port forward 127.0.0.1 8080 to my VM's 10.0.2.15 8080, so when I run my Docker Apache container I must remember incoming is on port 8080 and map that against the container's port 80. Hope that makes sense!&lt;br /&gt;&lt;br /&gt;Now check it's running:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ docker &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ps&lt;/span&gt;
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
9a6dc2fb88ff        d8codebase          &lt;span style="color: #ff0000;"&gt;"docker-php-entrypoi…"&lt;/span&gt;   &lt;span style="color: #000000;"&gt;44&lt;/span&gt; minutes ago      Up &lt;span style="color: #000000;"&gt;44&lt;/span&gt; minutes       0.0.0.0:&lt;span style="color: #000000;"&gt;8080&lt;/span&gt;-&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;80&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tcp   agitated_feistel&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Yes, and we can see from the screenshot above that it's picking up the memcached and the gd graphics extensions. Success.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Programmatically Create the AWS ECR Repository&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot_2019-12-07_at_13_16_14-edited.png?itok=eiXr6OXC 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/Screenshot_2019-12-07_at_13_16_14-edited.png?itok=6-TIckwl 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/Screenshot_2019-12-07_at_13_16_14-edited.png?itok=inIVYe9n 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/Screenshot_2019-12-07_at_13_16_14-edited.png?itok=cBSia9gB 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot_2019-12-07_at_13_16_14-edited.png?itok=eiXr6OXC" alt="ECR Repository" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;This is quite easy and I've put it into a shell script that requires one parameter - the repo name to be created. The work is done by the aws ecr create-repository call. The rest of the code is simply checking for error conditions. The screenshot above was taken on the AWS console after the shell script below was successfully run with a parameter of d8codebase.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/bin/bash&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;#Programmatically create an ECR repo&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Check whether we have the args&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; $&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"usage: [repo_name]"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Create the repo&lt;/span&gt;
&lt;span style="color: #007800;"&gt;REPO_NAME&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecr create-repository &lt;span style="color: #660033;"&gt;--repository-name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"$1"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .repository.repositoryName -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Check it was created ok. We already get a quality stderr msg from aws cli so just quit on error.&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# Similarly, if already exists it will tell us&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${REPO_NAME}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;!&lt;/span&gt;= &lt;span style="color: #007800;"&gt;$1&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;2&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Successfully created &lt;span style="color: #007800;"&gt;${REPO_NAME}&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Login to Docker and Push Image to ECR&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot_2019-12-08_at_10_20_26-edited.png?itok=sv0QPbaX 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/Screenshot_2019-12-08_at_10_20_26-edited.png?itok=AEUf4O-_ 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/Screenshot_2019-12-08_at_10_20_26-edited.png?itok=z9aPZ3kh 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/Screenshot_2019-12-08_at_10_20_26-edited.png?itok=JirTlXB0 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot_2019-12-08_at_10_20_26-edited.png?itok=sv0QPbaX" alt="Docker Push" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Now the script to automatically login to Docker and push the image to ECR. Note that AWS ECR does require you to use the docker login command, and therefore provides a AWS CLI ECR command get-login which returns a token than can be piped into the docker login command. The token retrieved from ECR has a large payload, and it is top and tailed with other metadata beyond just the password. Therefore that needs to be removed, and if you look closely at the script below, you can see that I pipe the entire returned payload through sed with a regex, and then the result is piped onwards to docker login. Hopefully the rest is quite self explanatory - and you can see the screenshot above that the push has worked and the image can now be included in ECS / Fargate task definitions. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/bin/bash&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;#Programmatically push to an ECR repo&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Check whether we have the args&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; $&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"usage: [repo_name]"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;REPO_NAME&lt;/span&gt;=&lt;span style="color: #007800;"&gt;$1&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ECR_ACCOUNT&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"XXXXXXXXXX.dkr.ecr.eu-west-2.amazonaws.com"&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ECR_REPO&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECR_ACCOUNT}&lt;/span&gt;/$1"&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# AWS Authentication - since we need to use docker push&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# The sed regex will top and tail the additional meta data sent by the aws login request.&lt;/span&gt;
aws ecr get-login &lt;span style="color: #660033;"&gt;--region&lt;/span&gt; eu-west-&lt;span style="color: #000000;"&gt;2&lt;/span&gt;  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s/^.*-p \(.*\)\s\-\e.*$/\1/'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;  docker &lt;span style="color: #c20cb9; font-weight: bold;"&gt;login&lt;/span&gt; &lt;span style="color: #660033;"&gt;--password-stdin&lt;/span&gt; &lt;span style="color: #660033;"&gt;-u&lt;/span&gt; AWS &lt;span style="color: #800000;"&gt;${ECR_ACCOUNT}&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the image id of the Docker build. If there is a "latest" use that else get the first without latest&lt;/span&gt;
&lt;span style="color: #007800;"&gt;TAG&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;docker images &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; &lt;span style="color: #660033;"&gt;-w&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${REPO_NAME}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; latest &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;awk&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'{ print $3; }'&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #800000;"&gt;${TAG}&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
        &lt;span style="color: #007800;"&gt;TAG&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;docker images &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; &lt;span style="color: #660033;"&gt;-w&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${REPO_NAME}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;awk&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'{ print $3; }'&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
docker tag &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$TAG&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECR_REPO}&lt;/span&gt;"&lt;/span&gt;
docker push &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECR_REPO}&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
      &lt;div class="field field--name-field-blog-youtube field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-text-youtube paragraph--view-mode--default"&gt;
          
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
  &lt;div class="field field--name-field-blog-terms field--type-entity-reference field--label-inline"&gt;
    &lt;div class="field--label"&gt;blog terms&lt;/div&gt;
          &lt;span class="field__items"&gt;
              &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/aws" hreflang="en"&gt;AWS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/awscli" hreflang="en"&gt;AWS CLI&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/docker" hreflang="en"&gt;Docker&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/devops" hreflang="en"&gt;devops&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/fargate" hreflang="en"&gt;Fargate&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/ecs" hreflang="en"&gt;ECS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/development" hreflang="en"&gt;Development&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/bash" hreflang="en"&gt;bash&lt;/a&gt;&lt;/span&gt;
              &lt;/span&gt;
      &lt;/div&gt;
</description>
  <pubDate>Sat, 07 Dec 2019 07:56:15 +0000</pubDate>
    <dc:creator>nigel</dc:creator>
    <guid isPermaLink="false">172 at http://badzilla.co.uk</guid>
    </item>
<item>
  <title>Create Arbitrary Subdomains for AWS Fargate Tasks using AWS CLI</title>
  <link>http://badzilla.co.uk/create-arbitrary-subdomains-aws-fargate-tasks-using-aws-cli</link>
  <description>
&lt;span&gt;Create Arbitrary Subdomains for AWS Fargate Tasks using AWS CLI&lt;/span&gt;

&lt;span&gt;&lt;span lang="" about="http://badzilla.co.uk/user/1" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;nigel&lt;/span&gt;&lt;/span&gt;

&lt;span&gt;Fri, 01/11/2019 - 15:03&lt;/span&gt;

      &lt;div class="field field--name-field-heading-image-text field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot_2019-11-03_at_11_24_32-edited1.png?itok=t3-00HWu 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-11/Screenshot_2019-11-03_at_11_24_32-edited1.png?itok=dcZAK-DY 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-11/Screenshot_2019-11-03_at_11_24_32-edited1.png?itok=aY5EToiP 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-11/Screenshot_2019-11-03_at_11_24_32-edited1.png?itok=MUHYEW-M 1695w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot_2019-11-03_at_11_24_32-edited1.png?itok=t3-00HWu" alt="Success" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;AWS Fargate is a relatively new product offering the capability of running Docker bundles as an ECS compute service on EC2 without the necessity for the user to have to orchestrate the underlying EC2 infrastructure. It is perfect for DevOps, and was the technology I chose as DevOps Architect at my current client. The client wanted standard CI/CD capabilities such as spinning up containerised copies of their website environment per feature branch to perform static analysis, automated testing, and also significantly, a persisting playground that QA or development personnel could use for manual testing and troubleshooting a feature (or hotfix) branch they are currently working on.&lt;/p&gt;

&lt;p&gt;This is similar to the offering of both Platform.sh and Amazee Labs hosting solutions - developers can spin up their feature branches. Alas my client is locked into another host yet needed on-the-fly feature branch Docker bundles.&lt;/p&gt;

&lt;p&gt;AWS Fargate tasks can achieve this, but out of the box it isn't possible to create public domain registration via ECS Service Discovery. The Fargate task is issued a bare IPv4 address which will obviously work but our requirement is to have a subdomain created per branch that would be of the format {hotfix|feature}--{jira ticket}-{suitable branch name}.{top level domain}.  So an example would be:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;feature--doi-746-my-whizzy-new-feature.clientdomain.dev&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So whilst we can't create a subdomain like that natively, we can do it by retrieving the IP address from the ECS Fargate task, then add that IP to a public Route 53 Hosted Zone. Furthermore, since the Fargate task is run via a Jenkins pipeline job that uses shell scripts populated with AWS CLI, the good news is we can indeed complete the registration of subdomain also using the AWS CLI *and* have the DNS propagate within 60 seconds! Amazing! Let's dive into how we achieve this. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Requirements + Assumptions&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The solution will be built using the standard httpd Apache2 server sample Fargate task described on the AWS blog &lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_AWSCLI_Fargate.html"&gt;Tutorial: Creating a Cluster with a Fargate Task Using the AWS CLI&lt;/a&gt;. I added the task definition into the console, although it is also possible create a shell script and use AWS CLI. I have used the default cluster for brevity's sake, and the AWS account default VPC. I have also transferred a spare domain I had, &lt;em&gt;saasidate.com&lt;/em&gt;, into Route 53 before I started the blog. This will be my tld and all the subdomains will be added off it. It's important that the ownership of the domain is transferred into Route 53 since otherwise subdomains will have authority issues if the parent domain is still registered to other domain providers such as GoDaddy or 123-Reg. &lt;/p&gt;
&lt;p&gt;The solution I am putting together will use AWS CLI which by default returns JSON structured data. It is absolutely essential to use the Linux command line utility &lt;strong&gt;jq&lt;/strong&gt; for parsing the JSON. Documentation on jq is readily available on the net. &lt;/p&gt;
&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Steps&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The solution will need the following steps:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;Get the user's default VPC (or create a custom VPC if preferred. We'll need this at a few points in the code. &lt;/li&gt;
	&lt;li&gt;Get a subnet from the VPC. Three subnets are created for use with the default VPC. I pick the first which is arbitrary.&lt;/li&gt;
	&lt;li&gt;Get a security group. A new security group is created per task when using the console but that is unnecessary for the shell scripts we will be building. So in our script, check whether our 'standard' security group has been created. If so use it, if not then create a security group with an ingress port of 80 and a CIDR of 0.0.0.0/0 which allows access worldwide on TCP port 80.&lt;/li&gt;
	&lt;li&gt;Run the Fargate task and loop / sleep until the task has a status of RUNNING. &lt;/li&gt;
	&lt;li&gt;Get the network interface id of the task and interrogate it for the IP address. &lt;/li&gt;
	&lt;li&gt;Get the hosted zone for the parent domain.&lt;/li&gt;
	&lt;li&gt;Add a record set containing the feature branch subdomain to the parent domain's hosted zone.&lt;/li&gt;
	&lt;li&gt;Create a new hosted zone using the feature branch. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ok - let's crack on and put this into AWS CLI shell scripts. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Get the VPC&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;I'm using the default VPC so I can filter the list I get back from AWS using the IsDefault attribute. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #007800;"&gt;VPC&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-vpcs &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;'.Vpcs[] | select(.IsDefault == true) | .VpcId'&lt;/span&gt; -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Note the use of the jq select statement. This is a familiar construct and will be used throughout this blog. Also note the -r flag - this removes the double quotes from the response.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Get the First Subnet in the Default VPC&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Here I am using jq again but piping the results through head to get the first subnet. There wasn't an obvious jq query to do this natively within jq. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# Get the first subnet of the VPC&lt;/span&gt;
&lt;span style="color: #007800;"&gt;SUBNET&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-subnets &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #660033;"&gt;--arg&lt;/span&gt; VPC &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$VPC&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'.Subnets[] | select(.VpcId == $VPC) | .SubnetId'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;head&lt;/span&gt; &lt;span style="color: #660033;"&gt;-n&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Get the Security Group&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Here I check whether we already have a dedicated security group which gives us worldwide access to port 80. I search first for a unique security group description and if it doesn't exist, then create it.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# Check if our security group for port 80 webserver already exists. Search for our funky unique description&lt;/span&gt;
&lt;span style="color: #007800;"&gt;SECURITY&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-security-groups &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;' .SecurityGroups[] | select (.Description == "Ingress Port 80 Anywhere") | .GroupId'&lt;/span&gt; -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Let's inspect what we got back.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-security-groups failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# If we didn't get a security group then create&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$SECURITY&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #007800;"&gt;SECURITY&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 create-security-group \
		&lt;span style="color: #660033;"&gt;--description&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Ingress Port 80 Anywhere"&lt;/span&gt; \
		&lt;span style="color: #660033;"&gt;--group-name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Fargate Webserver Port 80"&lt;/span&gt; \
		&lt;span style="color: #660033;"&gt;--vpc-id&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$VPC&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .GroupId &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
 
	aws ec2 authorize-security-group-ingress \
		&lt;span style="color: #660033;"&gt;--group-id&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$SECURITY&lt;/span&gt;"&lt;/span&gt; \
		&lt;span style="color: #660033;"&gt;--ip-permissions&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"FromPort=80,ToPort=80,IpProtocol=TCP,IpRanges=[{CidrIp=0.0.0.0/0}]"&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Run the Fargate Task&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Next I run the Fargate task. This is the sample Fargate task covered in the AWS documentation and uses the httpd docker image. When I created it in the console I called it "first-run-task-definition" - for the life of me I can't remember why I chose such a crazy name! Note I am piping the result through jq as per normal and then onwards through sed to get the task id without all the arn information that precedes it. The sed command looks for the final forward slash in the task arn and crops anything before it. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# Run the task and parse the task ARN for polling later to determine its status&lt;/span&gt;
&lt;span style="color: #007800;"&gt;TASK&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs run-task \
	&lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--task-definition&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"first-run-task-definition"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--network-configuration&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"awsvpcConfiguration={subnets=[&lt;span style="color: #007800;"&gt;${SUBNET}&lt;/span&gt;],securityGroups=[&lt;span style="color: #007800;"&gt;${SECURITY}&lt;/span&gt;],assignPublicIp=ENABLED}"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--launch-type&lt;/span&gt; FARGATE  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .tasks&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;.taskArn &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"s/.*\///"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Let's inspect what we got back. There should be a task identifier.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"task-run failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$TASK&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"task-run could not create task"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Loop and Wait for Fargate Task to get to RUNNING Status&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Next I have to wait for the task to acquire RUNNING status, However I can't wait for ever, and thus I have wrapped a shell script rule into a timeout mechanism. I have allowed for 5 minutes for the task to get to RUNNING status and that should be more than enough.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# Loop around until we see a RUNNING status or timeout after 10 x 30 second sleeps&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; i &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;3&lt;/span&gt; &lt;span style="color: #000000;"&gt;4&lt;/span&gt; &lt;span style="color: #000000;"&gt;5&lt;/span&gt; &lt;span style="color: #000000;"&gt;6&lt;/span&gt; &lt;span style="color: #000000;"&gt;7&lt;/span&gt; &lt;span style="color: #000000;"&gt;8&lt;/span&gt; &lt;span style="color: #000000;"&gt;9&lt;/span&gt; &lt;span style="color: #000000;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;11&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;do&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$i&lt;/span&gt; &lt;span style="color: #660033;"&gt;-eq&lt;/span&gt; &lt;span style="color: #000000;"&gt;11&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Timed out before could establish task is running"&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
	&lt;span style="color: #007800;"&gt;STATUS&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs describe-tasks &lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--tasks&lt;/span&gt; &lt;span style="color: #007800;"&gt;$TASK&lt;/span&gt;  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .tasks&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;.lastStatus -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
	&lt;span style="color: #666666; font-style: italic;"&gt;# Did it exit unexpectedly?&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-tasks failed with code $?"&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
	&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$STATUS&lt;/span&gt;"&lt;/span&gt; = &lt;span style="color: #ff0000;"&gt;"RUNNING"&lt;/span&gt;  &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;break&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
	&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sleep&lt;/span&gt; &lt;span style="color: #000000;"&gt;30&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Obtain the Network Interface Id&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The ENI is available in the Fargate task's description so I needed to parse this on my quest to get the public IP. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# Get the network Interface id&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ENI&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs describe-tasks &lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--tasks&lt;/span&gt; &lt;span style="color: #007800;"&gt;$TASK&lt;/span&gt;  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;'.tasks[0].attachments[0].details[] | select(.name == "networkInterfaceId") | .value'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Let's inspect what we got back. There should be a network interface id.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-tasks failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$ENI&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-tasks could not establish eni"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Get the Public IP Address&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;With the ENI it is possible to parse the the descriptions of all the network interfaces for the public IP address. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #007800;"&gt;PUBLIC_IP&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-network-interfaces &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #660033;"&gt;--arg&lt;/span&gt; ENI &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$ENI&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'.NetworkInterfaces[] | select(.NetworkInterfaceId == $ENI) | .PrivateIpAddresses[0].Association.PublicIp'&lt;/span&gt; -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Did we get an IP address?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-network-interfaces failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$PUBLIC_IP&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-network-interfaces could not retrieve public IP address"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Get the Parent Domain's Hosted Zone Id&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The shell script needs to know about the parent domain and the subdomain name (which in my case is a feature branch name) - so those need to be retrieved from runtime arguments. This will go at the top of the shell script.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #007800;"&gt;$1&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;||&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #007800;"&gt;$2&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"usage: parent_domain_name feature_branch_name"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;BRANCH&lt;/span&gt;=&lt;span style="color: #007800;"&gt;$2&lt;/span&gt;.&lt;span style="color: #007800;"&gt;$1&lt;/span&gt;
&lt;span style="color: #007800;"&gt;PARENT&lt;/span&gt;=&lt;span style="color: #007800;"&gt;$1&lt;/span&gt;.&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Then continuing at the end of the codebase, the following gets the parent domain
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #007800;"&gt;PARENT_ZONE&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws route53 list-hosted-zones-by-name &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #660033;"&gt;--arg&lt;/span&gt; PARENT &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$PARENT&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'.HostedZones[] | select(.Name == $PARENT) | .Id'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"s/.*\///"&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Add the Feature Branch Name and Public IP Address to the Parent Hosted Zone&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Now I created a new record set for the parent domain's hosted zone. This uses the AWS CLI command change-resource-record-sets which allows for insert, upsert and delete. I needed a DNS A record adding. The easiest way of providing the runtime parameters is via a JSON structure and that is created in shell script heredoc format to simplify shell script escaping. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #007800;"&gt;BATCH&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOT
{
  "Comment":"CREATE/DELETE/UPSERT a record",
  "Changes":[{
    "Action": "UPSERT",
    		  "ResourceRecordSet": {
    		  	"Name": "${BRANCH}",
    		  	"Type": "A",
    		  	"TTL": 300,
    		  	"ResourceRecords": [{ "Value": "${PUBLIC_IP}"}]
    		  }
  }]
}
EOT&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Use the hosted zone of the tld&lt;/span&gt;
aws route53 change-resource-record-sets \
	&lt;span style="color: #660033;"&gt;--hosted-zone-id&lt;/span&gt; &lt;span style="color: #007800;"&gt;$PARENT_ZONE&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--change-batch&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$BATCH&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Create the Feature Branch Hosted Zone&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The final AWS CLI call is to use create-hosted-zone, and here I needed to provide the feature branch name and an arbitrary unique caller reference for which I used a timestamp. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #007800;"&gt;timestamp&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;date&lt;/span&gt; +&lt;span style="color: #000000; font-weight: bold;"&gt;%&lt;/span&gt;s&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Now create a new hosted zone of the feature branch&lt;/span&gt;
aws route53 create-hosted-zone \
	&lt;span style="color: #660033;"&gt;--name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$BRANCH&lt;/span&gt;"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--caller-reference&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$timestamp&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;The Complete Script&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The complete script is listed below. Note that for brevity and easy reading I have cut a few coding standards. There is repetition in the error condition checking. This should be rewritten with calls to shell script functions in a separate file. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/bin/bash&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Script to assign a public IP address issued by a Fargate task to a subdomain&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #007800;"&gt;$1&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;||&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #007800;"&gt;$2&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"usage: parent_domain_name feature_branch_name"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;BRANCH&lt;/span&gt;=&lt;span style="color: #007800;"&gt;$2&lt;/span&gt;.&lt;span style="color: #007800;"&gt;$1&lt;/span&gt;
&lt;span style="color: #007800;"&gt;PARENT&lt;/span&gt;=&lt;span style="color: #007800;"&gt;$1&lt;/span&gt;.
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the default VPC.&lt;/span&gt;
&lt;span style="color: #007800;"&gt;VPC&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-vpcs &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;'.Vpcs[] | select(.IsDefault == true) | .VpcId'&lt;/span&gt; -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the first subnet of the VPC&lt;/span&gt;
&lt;span style="color: #007800;"&gt;SUBNET&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-subnets &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #660033;"&gt;--arg&lt;/span&gt; VPC &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$VPC&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'.Subnets[] | select(.VpcId == $VPC) | .SubnetId'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;head&lt;/span&gt; &lt;span style="color: #660033;"&gt;-n&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Check if our security group for port 80 webserver already exists. Search for our funky unique description&lt;/span&gt;
&lt;span style="color: #007800;"&gt;SECURITY&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-security-groups &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;' .SecurityGroups[] | select (.Description == "Ingress Port 80 Anywhere") | .GroupId'&lt;/span&gt; -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Let's inspect what we got back.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-security-groups failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# If we didn't get a security group then create&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$SECURITY&lt;/span&gt;"&lt;/span&gt; = &lt;span style="color: #ff0000;"&gt;""&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #007800;"&gt;SECURITY&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 create-security-group \
		&lt;span style="color: #660033;"&gt;--description&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Ingress Port 80 Anywhere"&lt;/span&gt; \
		&lt;span style="color: #660033;"&gt;--group-name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Fargate Webserver Port 80"&lt;/span&gt; \
		&lt;span style="color: #660033;"&gt;--vpc-id&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$VPC&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .GroupId &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
 
	aws ec2 authorize-security-group-ingress \
		&lt;span style="color: #660033;"&gt;--group-id&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$SECURITY&lt;/span&gt;"&lt;/span&gt; \
		&lt;span style="color: #660033;"&gt;--ip-permissions&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"FromPort=80,ToPort=80,IpProtocol=TCP,IpRanges=[{CidrIp=0.0.0.0/0}]"&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Run the task and parse the task ARN for polling later to determine its status&lt;/span&gt;
&lt;span style="color: #007800;"&gt;TASK&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs run-task \
	&lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--task-definition&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"first-run-task-definition"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--network-configuration&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"awsvpcConfiguration={subnets=[&lt;span style="color: #007800;"&gt;${SUBNET}&lt;/span&gt;],securityGroups=[&lt;span style="color: #007800;"&gt;${SECURITY}&lt;/span&gt;],assignPublicIp=ENABLED}"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--launch-type&lt;/span&gt; FARGATE  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .tasks&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;.taskArn &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"s/.*\///"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Let's inspect what we got back. There should be a task identifier.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"task-run failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$TASK&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"task-run could not create task"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Loop around until we see a RUNNING status or timeout after 10 x 30 second sleeps&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; i &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;3&lt;/span&gt; &lt;span style="color: #000000;"&gt;4&lt;/span&gt; &lt;span style="color: #000000;"&gt;5&lt;/span&gt; &lt;span style="color: #000000;"&gt;6&lt;/span&gt; &lt;span style="color: #000000;"&gt;7&lt;/span&gt; &lt;span style="color: #000000;"&gt;8&lt;/span&gt; &lt;span style="color: #000000;"&gt;9&lt;/span&gt; &lt;span style="color: #000000;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;11&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;do&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$i&lt;/span&gt; &lt;span style="color: #660033;"&gt;-eq&lt;/span&gt; &lt;span style="color: #000000;"&gt;11&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Timed out before could establish task is running"&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
	&lt;span style="color: #007800;"&gt;STATUS&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs describe-tasks &lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--tasks&lt;/span&gt; &lt;span style="color: #007800;"&gt;$TASK&lt;/span&gt;  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .tasks&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;.lastStatus -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
	&lt;span style="color: #666666; font-style: italic;"&gt;# Did it exit unexpectedly?&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-tasks failed with code $?"&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
	&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$STATUS&lt;/span&gt;"&lt;/span&gt; = &lt;span style="color: #ff0000;"&gt;"RUNNING"&lt;/span&gt;  &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;break&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
	&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sleep&lt;/span&gt; &lt;span style="color: #000000;"&gt;30&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the network Interface id&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ENI&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs describe-tasks &lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--tasks&lt;/span&gt; &lt;span style="color: #007800;"&gt;$TASK&lt;/span&gt;  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;'.tasks[0].attachments[0].details[] | select(.name == "networkInterfaceId") | .value'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Let's inspect what we got back. There should be a network interface id.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-tasks failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$ENI&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-tasks could not establish eni"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the Public IP Address&lt;/span&gt;
&lt;span style="color: #007800;"&gt;PUBLIC_IP&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-network-interfaces &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #660033;"&gt;--arg&lt;/span&gt; ENI &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$ENI&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'.NetworkInterfaces[] | select(.NetworkInterfaceId == $ENI) | .PrivateIpAddresses[0].Association.PublicIp'&lt;/span&gt; -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Did we get an IP address?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-network-interfaces failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$PUBLIC_IP&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-network-interfaces could not retrieve public IP address"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;BATCH&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOT
{
  "Comment":"CREATE/DELETE/UPSERT a record",
  "Changes":[{
    "Action": "UPSERT",
    		  "ResourceRecordSet": {
    		  	"Name": "${BRANCH}",
    		  	"Type": "A",
    		  	"TTL": 300,
    		  	"ResourceRecords": [{ "Value": "${PUBLIC_IP}"}]
    		  }
  }]
}
EOT&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;PARENT_ZONE&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws route53 list-hosted-zones-by-name &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #660033;"&gt;--arg&lt;/span&gt; PARENT &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$PARENT&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'.HostedZones[] | select(.Name == $PARENT) | .Id'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"s/.*\///"&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
aws route53 change-resource-record-sets \
	&lt;span style="color: #660033;"&gt;--hosted-zone-id&lt;/span&gt; &lt;span style="color: #007800;"&gt;$PARENT_ZONE&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--change-batch&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$BATCH&lt;/span&gt;"&lt;/span&gt;
 
 
&lt;span style="color: #007800;"&gt;timestamp&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;date&lt;/span&gt; +&lt;span style="color: #000000; font-weight: bold;"&gt;%&lt;/span&gt;s&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Now create a new hosted zone of the feature branch&lt;/span&gt;
aws route53 create-hosted-zone \
	&lt;span style="color: #660033;"&gt;--name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$BRANCH&lt;/span&gt;"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--caller-reference&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$timestamp&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Invoking the Script&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot_2019-11-03_at_11_25_07-edited1.png?itok=6zDl28OV 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-11/Screenshot_2019-11-03_at_11_25_07-edited1.png?itok=PtA97zAh 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-11/Screenshot_2019-11-03_at_11_25_07-edited1.png?itok=onEwER9j 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-11/Screenshot_2019-11-03_at_11_25_07-edited1.png?itok=3pXhsRib 1362w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot_2019-11-03_at_11_25_07-edited1.png?itok=6zDl28OV" alt="Full Domain Name" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The script requires two parameters as previous discussed. Here's my example for the blog:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;.&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;feature-branch.sh saasidate.com feature--doi-&lt;span style="color: #000000;"&gt;746&lt;/span&gt;-my-whizzy-new-feature&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Currently the output of the script is the response from the AWS CLI route53 create-hosted-zone call, and here you can detect the full domain name.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Checking the Outcome&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot%202019-11-03%20at%2011.58.11.png?itok=J7vAfmhk 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-11/Screenshot%202019-11-03%20at%2011.58.11.png?itok=UyDrsDoT 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-11/Screenshot%202019-11-03%20at%2011.58.11.png?itok=vqKiRvSi 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-11/Screenshot%202019-11-03%20at%2011.58.11.png?itok=YUAatBcF 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot%202019-11-03%20at%2011.58.11.png?itok=J7vAfmhk" alt="Tasks Running" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot%202019-11-03%20at%2012.00.56.png?itok=d-SSfTq- 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-11/Screenshot%202019-11-03%20at%2012.00.56.png?itok=N4C40cpp 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-11/Screenshot%202019-11-03%20at%2012.00.56.png?itok=oHvt2vUZ 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-11/Screenshot%202019-11-03%20at%2012.00.56.png?itok=wa9icCup 2254w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot%202019-11-03%20at%2012.00.56.png?itok=d-SSfTq-" alt="Route 53" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;Obviously the first check is to copy and paste the url of the feature branch into a browser and see if it loads. An example of this is the blog heading image at the top of the page. &lt;/p&gt;

&lt;p&gt;Also the AWS console is the place to check everything is as required. Navigate to ECS -&gt; default -&gt; Tasks and you should see a screenshot similar to the first one immediately above. This is the task we invoked from inside our shell script. Now navigate to Route 53 -&gt; Hosted Zones -&gt; {domain name} and you can see the feature branch and its IP address.&lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Steps left to do&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;New hosted zones will normally propagate in 60 seconds in Route 53 - but it would be good if the script above polls Route 53 every 10 seconds or so and reports back the subdomain url and the IP address once the propagation has completed. This should be surfaced on the command line as a minimum, but perhaps a notification on Slack would be even better. Both options are trivial. &lt;/p&gt;

&lt;p&gt;Whilst the idea is that the Fargate tasks should persist, they shouldn't be around forever. Therefore there needs to be clear up activities to remove the feature subdomain from the parent domain's hosted zone, and the subdomain hosted zone. Also there obviously needs a step to stop the Fargate task. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Caveats&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;There are caveats to this solution - but for my use case, it's one of those rare occurrences in life that the caveats don't apply to me. &lt;/p&gt;

&lt;p&gt;Firstly, this solution will only work with a Fargate &lt;strong&gt;task&lt;/strong&gt; and not an ECS &lt;strong&gt;service&lt;/strong&gt; running a Fargate task. Tasks should be run as services for production environments since services give you great things like replication, and health percentages against number of running tasks. There is therefore no scaling, no load balancing, no DDOS protection in what I'm offering here.&lt;/p&gt;

&lt;p&gt;Fargate tasks run in isolation are perfect for spun up short living environments such as playgrounds for devs and QAs to run manual tests against or troubleshoot development issues - which is exactly my use case. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
      &lt;div class="field field--name-field-blog-youtube field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-text-youtube paragraph--view-mode--default"&gt;
          
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-text-youtube paragraph--view-mode--default"&gt;
          
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
  &lt;div class="field field--name-field-blog-terms field--type-entity-reference field--label-inline"&gt;
    &lt;div class="field--label"&gt;blog terms&lt;/div&gt;
          &lt;span class="field__items"&gt;
              &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/aws" hreflang="en"&gt;AWS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/awscli" hreflang="en"&gt;AWS CLI&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/docker" hreflang="en"&gt;Docker&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/devops" hreflang="en"&gt;devops&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/fargate" hreflang="en"&gt;Fargate&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/ecs" hreflang="en"&gt;ECS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/development" hreflang="en"&gt;Development&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/Route53" hreflang="en"&gt;Route 53&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/bash" hreflang="en"&gt;bash&lt;/a&gt;&lt;/span&gt;
              &lt;/span&gt;
      &lt;/div&gt;
</description>
  <pubDate>Fri, 01 Nov 2019 15:03:02 +0000</pubDate>
    <dc:creator>nigel</dc:creator>
    <guid isPermaLink="false">171 at http://badzilla.co.uk</guid>
    </item>

  </channel>
</rss>
