{"id":18941,"date":"2017-10-12T12:15:54","date_gmt":"2017-10-12T09:15:54","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=18941"},"modified":"2017-10-12T11:10:05","modified_gmt":"2017-10-12T08:10:05","slug":"shared-resources-terraformed-docker-environment-aws","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/","title":{"rendered":"Shared Resources for Your Terraformed Docker Environment on AWS"},"content":{"rendered":"<p>In <a href=\"https:\/\/www.webcodegeeks.com\/devops\/terraforming-docker-environment-aws\/\">Part 1 of this series<\/a>, we laid the groundwork for Terraforming infrastructure on Amazon. Today we\u2019ll define our actual infrastructure consisting of networks, servers, etc. Have fun!<\/p>\n<h2>Shared Resources Declaration<\/h2>\n<p>Since our service depends on underlying resources like the VPC and EC2 instances, we\u2019ll create the shared environment first. Make sure you\u2019re in the <code>my-terraform-environment\/shared\/<\/code> folder before proceeding.<\/p>\n<p>We\u2019ll start with core ECS-related resources. We need to look up the most recent ECS optimized AMI, create the ECS cluster, and create the necessary IAM Roles for services and instances to use to support ECS.<\/p>\n<pre class=\"brush:php\">\/\/ shared\/main.tf\r\n\/*\r\n * Determine most recent ECS optimized AMI\r\n *\/\r\ndata \"aws_ami\" \"ecs_ami\" {\r\n most_recent = true\r\n owners      = [\"amazon\"]\r\n\r\n filter {\r\n   name   = \"name\"\r\n   values = [\"amzn-ami-*-amazon-ecs-optimized\"]\r\n }\r\n}\r\n\r\n\/*\r\n * Create ECS cluster\r\n *\/\r\nresource \"aws_ecs_cluster\" \"ecs_cluster\" {\r\n name = \"ecs-cluster\"\r\n}\r\n\r\n\/*\r\n * Create ECS IAM Instance Role and Policy\r\n * Use random id in naming of roles to prevent collisions\r\n * should other ECS clusters be created in same AWS account\r\n * using this same code. \r\n *\/\r\nresource \"random_id\" \"code\" {\r\n byte_length = 4\r\n}\r\n\r\nresource \"aws_iam_role\" \"ecsInstanceRole\" {\r\n name               = \"ecsInstanceRole-${random_id.code.hex}\"\r\n assume_role_policy = &lt;&lt;EOF\r\n{\r\n \"Version\": \"2008-10-17\",\r\n \"Statement\": [\r\n   {\r\n     \"Sid\": \"\",\r\n     \"Effect\": \"Allow\",\r\n     \"Principal\": {\r\n       \"Service\": \"ec2.amazonaws.com\"\r\n     },\r\n     \"Action\": \"sts:AssumeRole\"\r\n   }\r\n ]\r\n}\r\nEOF\r\n\r\n}\r\n\r\nresource \"aws_iam_role_policy\" \"ecsInstanceRolePolicy\" {\r\n name   = \"ecsInstanceRolePolicy-${random_id.code.hex}\"\r\n role   = \"${aws_iam_role.ecsInstanceRole.id}\"\r\n policy = &lt;&lt;EOF\r\n{\r\n \"Version\": \"2012-10-17\",\r\n \"Statement\": [\r\n   {\r\n     \"Effect\": \"Allow\",\r\n     \"Action\": [\r\n       \"ecs:CreateCluster\",\r\n       \"ecs:DeregisterContainerInstance\",\r\n       \"ecs:DiscoverPollEndpoint\",\r\n       \"ecs:Poll\",\r\n       \"ecs:RegisterContainerInstance\",\r\n       \"ecs:StartTelemetrySession\",\r\n       \"ecs:Submit*\",\r\n       \"ecr:GetAuthorizationToken\",\r\n       \"ecr:BatchCheckLayerAvailability\",\r\n       \"ecr:GetDownloadUrlForLayer\",\r\n       \"ecr:BatchGetImage\",\r\n       \"logs:CreateLogStream\",\r\n       \"logs:PutLogEvents\"\r\n     ],\r\n     \"Resource\": \"*\"\r\n   }\r\n ]\r\n}\r\nEOF\r\n\r\n}\r\n\r\n\/*\r\n * Create ECS IAM Service Role and Policy\r\n *\/\r\nresource \"aws_iam_role\" \"ecsServiceRole\" {\r\n name               = \"ecsServiceRole-${random_id.code.hex}\"\r\n assume_role_policy = &lt;&lt;EOF\r\n{\r\n \"Version\": \"2008-10-17\",\r\n \"Statement\": [\r\n   {\r\n     \"Sid\": \"\",\r\n     \"Effect\": \"Allow\",\r\n     \"Principal\": {\r\n       \"Service\": \"ecs.amazonaws.com\"\r\n     },\r\n     \"Action\": \"sts:AssumeRole\"\r\n   }\r\n ]\r\n}\r\nEOF\r\n\r\n}\r\n\r\nresource \"aws_iam_role_policy\" \"ecsServiceRolePolicy\" {\r\n name   = \"ecsServiceRolePolicy-${random_id.code.hex}\"\r\n role   = \"${aws_iam_role.ecsServiceRole.id}\"\r\n policy = &lt;&lt;EOF\r\n{\r\n \"Version\": \"2012-10-17\",\r\n \"Statement\": [\r\n   {\r\n     \"Effect\": \"Allow\",\r\n     \"Action\": [\r\n       \"ec2:AuthorizeSecurityGroupIngress\",\r\n       \"ec2:Describe*\",\r\n       \"elasticloadbalancing:DeregisterInstancesFromLoadBalancer\",\r\n       \"elasticloadbalancing:DeregisterTargets\",\r\n       \"elasticloadbalancing:Describe*\",\r\n       \"elasticloadbalancing:RegisterInstancesWithLoadBalancer\",\r\n       \"elasticloadbalancing:RegisterTargets\"\r\n     ],\r\n     \"Resource\": \"*\"\r\n   }\r\n ]\r\n}\r\nEOF\r\n\r\n}\r\n\r\nresource \"aws_iam_instance_profile\" \"ecsInstanceProfile\" {\r\n name = \"ecsInstanceProfile-${random_id.code.hex}\"\r\n role = \"${aws_iam_role.ecsInstanceRole.name}\"\r\n}<\/pre>\n<p>Dynamically looking up the current ECS-optimized AMI like this is a goldmine in itself. Before Terraform, I had to look this up on a webpage on a regular basis to keep my cluster instances current and it was a pain. With a dynamic lookup like this, running <code>terraform plan<\/code> every so often will identify if a new AMI is available and if any resources depending on it will need to be updated and\/or replaced.<\/p>\n<p>It is a good idea to run a <code>terraform plan<\/code> periodically to ensure there are no errors in your code. At this point, running <code>terraform plan<\/code> should have output similar to:<\/p>\n<pre class=\"brush:php; wrap-lines:false\">$ terraform plan\r\nRefreshing Terraform state in-memory prior to plan...\r\nThe refreshed state will be used to calculate this plan, but will not be\r\npersisted to local or remote state storage.\r\n\r\ndata.aws_ami.ecs_ami: Refreshing state...\r\n\r\n------------------------------------------------------------------------\r\n\r\nAn execution plan has been generated and is shown below.\r\nResource actions are indicated with the following symbols:\r\n  + create\r\n\r\nTerraform will perform the following actions:\r\n\r\n  + aws_ecs_cluster.ecs_cluster\r\n      id:                    &lt;computed&gt;\r\n      name:                  \"ecs-cluster\"\r\n\r\n  + aws_iam_instance_profile.ecsInstanceProfile\r\n      id:                    &lt;computed&gt;\r\n      arn:                   &lt;computed&gt;\r\n      create_date:           &lt;computed&gt;\r\n      name:                  \"ecsInstanceProfile-${random_id.code.hex}\"\r\n      path:                  \"\/\"\r\n      role:                  \"${aws_iam_role.ecsInstanceRole.name}\"\r\n      roles.#:               &lt;computed&gt;\r\n      unique_id:             &lt;computed&gt;\r\n\r\n  + aws_iam_role.ecsInstanceRole\r\n      id:                    &lt;computed&gt;\r\n      arn:                   &lt;computed&gt;\r\n      assume_role_policy:    \"{\\n \\\"Version\\\": \\\"2008-10-17\\\",\\n \\\"Statement\\\": [\\n   {\\n     \\\"Sid\\\": \\\"\\\",\\n     \\\"Effect\\\": \\\"Allow\\\",\\n     \\\"Principal\\\": {\\n       \\\"Service\\\": \\\"ec2.amazonaws.com\\\"\\n     },\\n     \\\"Action\\\": \\\"sts:AssumeRole\\\"\\n   }\\n ]\\n}\\n\"\r\n      create_date:           &lt;computed&gt;\r\n      force_detach_policies: \"false\"\r\n      name:                  \"ecsInstanceRole-${random_id.code.hex}\"\r\n      path:                  \"\/\"\r\n      unique_id:             &lt;computed&gt;\r\n\r\n  + aws_iam_role.ecsServiceRole\r\n      id:                    &lt;computed&gt;\r\n      arn:                   &lt;computed&gt;\r\n      assume_role_policy:    \"{\\n \\\"Version\\\": \\\"2008-10-17\\\",\\n \\\"Statement\\\": [\\n   {\\n     \\\"Sid\\\": \\\"\\\",\\n     \\\"Effect\\\": \\\"Allow\\\",\\n     \\\"Principal\\\": {\\n       \\\"Service\\\": \\\"ecs.amazonaws.com\\\"\\n     },\\n     \\\"Action\\\": \\\"sts:AssumeRole\\\"\\n   }\\n ]\\n}\\n\"\r\n      create_date:           &lt;computed&gt;\r\n      force_detach_policies: \"false\"\r\n      name:                  \"ecsServiceRole-${random_id.code.hex}\"\r\n      path:                  \"\/\"\r\n      unique_id:             &lt;computed&gt;\r\n\r\n  + aws_iam_role_policy.ecsInstanceRolePolicy\r\n      id:                    &lt;computed&gt;\r\n      name:                  \"ecsInstanceRolePolicy-${random_id.code.hex}\"\r\n      policy:                \"{\\n \\\"Version\\\": \\\"2012-10-17\\\",\\n \\\"Statement\\\": [\\n   {\\n     \\\"Effect\\\": \\\"Allow\\\",\\n     \\\"Action\\\": [\\n       \\\"ecs:CreateCluster\\\",\\n       \\\"ecs:DeregisterContainerInstance\\\",\\n       \\\"ecs:DiscoverPollEndpoint\\\",\\n       \\\"ecs:Poll\\\",\\n       \\\"ecs:RegisterContainerInstance\\\",\\n       \\\"ecs:StartTelemetrySession\\\",\\n       \\\"ecs:Submit*\\\",\\n       \\\"ecr:GetAuthorizationToken\\\",\\n       \\\"ecr:BatchCheckLayerAvailability\\\",\\n       \\\"ecr:GetDownloadUrlForLayer\\\",\\n       \\\"ecr:BatchGetImage\\\",\\n       \\\"logs:CreateLogStream\\\",\\n       \\\"logs:PutLogEvents\\\"\\n     ],\\n     \\\"Resource\\\": \\\"*\\\"\\n   }\\n ]\\n}\\n\"\r\n      role:                  \"${aws_iam_role.ecsInstanceRole.id}\"\r\n\r\n  + aws_iam_role_policy.ecsServiceRolePolicy\r\n      id:                    &lt;computed&gt;\r\n      name:                  \"ecsServiceRolePolicy-${random_id.code.hex}\"\r\n      policy:                \"{\\n \\\"Version\\\": \\\"2012-10-17\\\",\\n \\\"Statement\\\": [\\n   {\\n     \\\"Effect\\\": \\\"Allow\\\",\\n     \\\"Action\\\": [\\n       \\\"ec2:AuthorizeSecurityGroupIngress\\\",\\n       \\\"ec2:Describe*\\\",\\n       \\\"elasticloadbalancing:DeregisterInstancesFromLoadBalancer\\\",\\n       \\\"elasticloadbalancing:DeregisterTargets\\\",\\n       \\\"elasticloadbalancing:Describe*\\\",\\n       \\\"elasticloadbalancing:RegisterInstancesWithLoadBalancer\\\",\\n       \\\"elasticloadbalancing:RegisterTargets\\\"\\n     ],\\n     \\\"Resource\\\": \\\"*\\\"\\n   }\\n ]\\n}\\n\"\r\n      role:                  \"${aws_iam_role.ecsServiceRole.id}\"\r\n\r\n  + random_id.code\r\n      id:                    &lt;computed&gt;\r\n      b64:                   &lt;computed&gt;\r\n      b64_std:               &lt;computed&gt;\r\n      b64_url:               &lt;computed&gt;\r\n      byte_length:           \"4\"\r\n      dec:                   &lt;computed&gt;\r\n      hex:                   &lt;computed&gt;\r\n\r\n\r\nPlan: 7 to add, 0 to change, 0 to destroy.\r\n\r\n------------------------------------------------------------------------\r\n\r\nNote: You didn't specify an \"-out\" parameter to save this plan, so Terraform\r\ncan't guarantee that exactly these actions will be performed if\r\n\"terraform apply\" is subsequently run.\r\n\r\nReleasing state lock. This may take a few moments...<\/pre>\n<p>At this time, the plan is to create seven new resources. The output from Terraform is color coded to help recognize what will be created, changed, destroyed, or read. Green for created (or destroyed and created if needed), yellow if it will be changed in place, red if it will be deleted, and cyan for data resources that will be read.<\/p>\n<p>Next up, we\u2019ll create the VPC and look up the default security group that is created automatically by AWS so that we can assign other resources to it for intra-VPC communications.<\/p>\n<pre class=\"brush:php\">\/\/ shared\/main.tf\r\n\/*\r\n * Create VPC \r\n *\/\r\nresource \"aws_vpc\" \"vpc\" {\r\n cidr_block = \"10.0.0.0\/16\"\r\n\r\n tags = {\r\n   Name = \"vpc-terraform\"\r\n }\r\n}\r\n\r\n\/*\r\n * Get default security group for reference later\r\n *\/\r\ndata \"aws_security_group\" \"vpc_default_sg\" {\r\n name   = \"default\"\r\n vpc_id = \"${aws_vpc.vpc.id}\"\r\n}<\/pre>\n<p>Now that we have a VPC, we need to set up public and private subnets in multiple availability zones. Terraform has an ability to loop over lists and create multiple instances of a resource. For most resources, you can set a <code>count<\/code> attribute to specify how many of that instance should be created.<\/p>\n<p>If a single instance is normally referenced with the naming format of <code>resource_type.resource_name.attribute<\/code>, for references that are created with <code>count &gt; 1<\/code> you must also specify the index of the instance you want to reference, such as <code>resource_type.resource_name.index.attribute<\/code> (for example, <code>aws_subnet.private_subnet.0.id<\/code>).<\/p>\n<p>When we create our subnets below, we\u2019ll do a little Terraform-fu to generate subnets for as many availability zones as are specified in the var <code>var.aws_zones<\/code>.<\/p>\n<pre class=\"brush:php\">\/\/ shared\/main.tf\r\n\/*\r\n * Create public and private subnets for each availability zone\r\n *\/\r\nresource \"aws_subnet\" \"public_subnet\" {\r\n count             = \"${length(var.aws_zones)}\"\r\n vpc_id            = \"${aws_vpc.vpc.id}\"\r\n availability_zone = \"${element(var.aws_zones, count.index)}\"\r\n cidr_block        = \"10.0.${(count.index + 1) * 10}.0\/24\"\r\n\r\n tags {\r\n   Name = \"public-${element(var.aws_zones, count.index)}\"\r\n }\r\n}\r\n\r\nresource \"aws_subnet\" \"private_subnet\" {\r\n count             = \"${length(var.aws_zones)}\"\r\n vpc_id            = \"${aws_vpc.vpc.id}\"\r\n availability_zone = \"${element(var.aws_zones, count.index)}\"\r\n cidr_block        = \"10.0.${(count.index + 1) * 11}.0\/24\"\r\n\r\n tags {\r\n   Name = \"private-${element(var.aws_zones, count.index)}\"\r\n }\r\n}<\/pre>\n<p>Given <code>var.aws_zones = [\u201cus-east-1c\u201d, \u201cus-east-1d\u201d, \u201cus-east-1e\u201d]<\/code>, this will create six subnets: three public and three private.<\/p>\n<p>!Sign up for a free Codeship Account<\/p>\n<p>A VPC requires an Internet Gateway for the public subnets to be able to route out to the internet and a NAT gateway for private subnets to be able to do the same. We need to create these resources and set up routing tables for each of the six subnets to properly use them.<\/p>\n<p>We\u2019ll also allocate an Elastic IP (static IP address) to assign to our NAT instance so that our private subnet traffic \u201ccomes\u201d from the same IP address. While we\u2019re at it, we\u2019ll designate that any of our private subnets can be used for hosting RDS instances by creating a DB subnet group.<\/p>\n<pre class=\"brush:php; wrap-lines:false\">\/\/ shared\/main.tf\r\n\/*\r\n * Create internet gateway for VPC\r\n *\/\r\nresource \"aws_internet_gateway\" \"internet_gateway\" {\r\n vpc_id = \"${aws_vpc.vpc.id}\"\r\n}\r\n\r\n\/*\r\n * Create NAT gateway and allocate Elastic IP for it\r\n *\/\r\nresource \"aws_eip\" \"gateway_eip\" {}\r\n\r\nresource \"aws_nat_gateway\" \"nat_gateway\" {\r\n allocation_id = \"${aws_eip.gateway_eip.id}\"\r\n subnet_id     = \"${aws_subnet.public_subnet.0.id}\"\r\n depends_on    = [\"aws_internet_gateway.internet_gateway\"]\r\n}\r\n\r\n\/*\r\n * Routes for private subnets to use NAT gateway\r\n *\/\r\nresource \"aws_route_table\" \"nat_route_table\" {\r\n vpc_id = \"${aws_vpc.vpc.id}\"\r\n}\r\n\r\nresource \"aws_route\" \"nat_route\" {\r\n route_table_id         = \"${aws_route_table.nat_route_table.id}\"\r\n destination_cidr_block = \"0.0.0.0\/0\"\r\n nat_gateway_id         = \"${aws_nat_gateway.nat_gateway.id}\"\r\n}\r\n\r\nresource \"aws_route_table_association\" \"private_route\" {\r\n count          = \"${length(var.aws_zones)}\"\r\n subnet_id      = \"${element(aws_subnet.private_subnet.*.id, count.index)}\"\r\n route_table_id = \"${aws_route_table.nat_route_table.id}\"\r\n}\r\n\r\n\/*\r\n * Routes for public subnets to use internet gateway\r\n *\/\r\nresource \"aws_route_table\" \"igw_route_table\" {\r\n vpc_id = \"${aws_vpc.vpc.id}\"\r\n}\r\n\r\nresource \"aws_route\" \"igw_route\" {\r\n route_table_id         = \"${aws_route_table.igw_route_table.id}\"\r\n destination_cidr_block = \"0.0.0.0\/0\"\r\n gateway_id             = \"${aws_internet_gateway.internet_gateway.id}\"\r\n}\r\n\r\nresource \"aws_route_table_association\" \"public_route\" {\r\n count          = \"${length(var.aws_zones)}\"\r\n subnet_id      = \"${element(aws_subnet.public_subnet.*.id, count.index)}\"\r\n route_table_id = \"${aws_route_table.igw_route_table.id}\"\r\n}\r\n\r\n\/*\r\n * Create DB Subnet Group for private subnets\r\n *\/\r\nresource \"aws_db_subnet_group\" \"db_subnet_group\" {\r\n name       = \"db-subnet\"\r\n subnet_ids = [\"${aws_subnet.private_subnet.*.id}\"]\r\n}<\/pre>\n<p>With our ECS cluster and network in place, we can create an auto-scaling group to launch EC2 instances into the ECS cluster. The ECS-optimized AMI looks for the ECS cluster name in the file <code>\/etc\/ecs\/ecs.config<\/code>, so we need to create our instances with a simple shell script in the User Data field to put the ECS cluster name in place on startup. For this, we\u2019ll use a template file and a data resource to render it for use. Create a file named <code>shared\/user-data.sh<\/code> with the following contents:<\/p>\n<pre class=\"brush:php\">#!\/bin\/bash\r\necho ECS_CLUSTER=${ecs_cluster_name} &gt;&gt; \/etc\/ecs\/ecs.config<\/pre>\n<p>Now add the following to the <code>shared\/main.tf<\/code> file:<\/p>\n<pre class=\"brush:php; wrap-lines:false\">\/\/ shared\/main.tf\r\n\/*\r\n * Generate user_data from template file\r\n *\/\r\ndata \"template_file\" \"user_data\" {\r\n template = \"${file(\"${path.module}\/user-data.sh\")}\"\r\n\r\n vars {\r\n   ecs_cluster_name = \"${aws_ecs_cluster.ecs_cluster.name}\"\r\n }\r\n}\r\n\r\n\/*\r\n * Create Launch Configuration\r\n *\/\r\nresource \"aws_launch_configuration\" \"as_conf\" {\r\n image_id             = \"${data.aws_ami.ecs_ami.id}\"\r\n instance_type        = \"t2.micro\"\r\n security_groups      = [\"${data.aws_security_group.vpc_default_sg.id}\"]\r\n iam_instance_profile = \"${aws_iam_instance_profile.ecsInstanceProfile.id}\"\r\n\r\n root_block_device {\r\n   volume_size = \"8\"\r\n }\r\n\r\n user_data = \"${data.template_file.user_data.rendered}\"\r\n\r\n lifecycle {\r\n   create_before_destroy = true\r\n }\r\n}\r\n\r\n\/*\r\n * Create Auto Scaling Group\r\n *\/\r\nresource \"aws_autoscaling_group\" \"asg\" {\r\n name                      = \"asg-ecs-enviroment\"\r\n availability_zones        = \"${var.aws_zones}\"\r\n vpc_zone_identifier       = [\"${aws_subnet.private_subnet.*.id}\"]\r\n min_size                  = \"3\"\r\n max_size                  = \"3\"\r\n desired_capacity          = \"3\"\r\n launch_configuration      = \"${aws_launch_configuration.as_conf.id}\"\r\n health_check_type         = \"EC2\"\r\n health_check_grace_period = \"120\"\r\n default_cooldown          = \"30\"\r\n\r\n lifecycle {\r\n   create_before_destroy = true\r\n }\r\n}<\/pre>\n<p>The services Terraform environment will need several values from the shared environment so we need to define them as outputs. Edit the <code>outputs.tf<\/code> file and add the following:<\/p>\n<pre class=\"brush:php\">\/\/ shared\/outputs.tf\r\noutput \"aws_zones\" {\r\n value = [\"${var.aws_zones}\"]\r\n}\r\n\r\noutput \"db_subnet_group_name\" {\r\n value = \"${aws_db_subnet_group.db_subnet_group.name}\"\r\n}\r\n\r\noutput \"ecs_cluster_name\" {\r\n value = \"${aws_ecs_cluster.ecs_cluster.name}\"\r\n}\r\n\r\noutput \"ecsServiceRole_arn\" {\r\n value = \"${aws_iam_role.ecsServiceRole.arn}\"\r\n}\r\n\r\noutput \"private_subnet_ids\" {\r\n value = [\"${aws_subnet.private_subnet.*.id}\"]\r\n}\r\n\r\noutput \"public_subnet_ids\" {\r\n value = [\"${aws_subnet.public_subnet.*.id}\"]\r\n}\r\n\r\noutput \"vpc_default_sg_id\" {\r\n value = \"${data.aws_security_group.vpc_default_sg.id}\"\r\n}\r\n\r\noutput \"vpc_id\" {\r\n value = \"${aws_vpc.vpc.id}\"\r\n}<\/pre>\n<p>That concludes the shared resources definition, so let\u2019s go ahead and run another <code>terraform plan<\/code> to check that everything looks okay, and then run <code>terraform apply<\/code>.<\/p>\n<pre class=\"brush:php; wrap-lines:false\">$ terraform plan\r\nRefreshing Terraform state in-memory prior to plan...\r\n\u2026\u2026\r\nPlan: 30 to add, 0 to change, 0 to destroy.\r\n\u2026\u2026 \r\nReleasing state lock. This may take a few moments\u2026\r\n\r\n$ terraform apply\r\ndata.aws_ami.ecs_ami: Refreshing state...\r\nrandom_id.code: Creating...\r\n  b64:         \"\" =&gt; \"&lt;computed&gt;\"\r\n  b64_std:     \"\" =&gt; \"&lt;computed&gt;\"\r\n  b64_url:     \"\" =&gt; \"&lt;computed&gt;\"\r\n  byte_length: \"\" =&gt; \"4\"\r\n  dec:         \"\" =&gt; \"&lt;computed&gt;\"\r\n  hex:         \"\" =&gt; \"&lt;computed&gt;\"\r\nrandom_id.code: Creation complete after 0s (ID: lbOvJw)\r\naws_ecs_cluster.ecs_cluster: Creating...\r\n  name: \"\" =&gt; \"ecs-cluster\"\r\naws_iam_role.ecsServiceRole: Creating...\r\n  arn:                   \"\" =&gt; \"&lt;computed&gt;\"\r\n  assume_role_policy:    \"\" =&gt; \"{\\n \\\"Version\\\": \\\"2008-10-17\\\",\\n \\\"Statement\\\": [\\n   {\\n     \\\"Sid\\\": \\\"\\\",\\n     \\\"Effect\\\": \\\"Allow\\\",\\n     \\\"Principal\\\": {\\n       \\\"Service\\\": \\\"ecs.amazonaws.com\\\"\\n     },\\n     \\\"Action\\\": \\\"sts:AssumeRole\\\"\\n   }\\n ]\\n}\\n\"\r\n  create_date:           \"\" =&gt; \"&lt;computed&gt;\"\r\n  force_detach_policies: \"\" =&gt; \"false\"\r\n  name:                  \"\" =&gt; \"ecsServiceRole-95b3af27\"\r\n  path:                  \"\" =&gt; \"\/\"\r\n  unique_id:             \"\" =&gt; \"&lt;computed&gt;\"\r\naws_eip.gateway_eip: Creating...\r\n  allocation_id:     \"\" =&gt; \"&lt;computed&gt;\"\r\n  association_id:    \"\" =&gt; \"&lt;computed&gt;\"\r\n  domain:            \"\" =&gt; \"&lt;computed&gt;\"\r\n  instance:          \"\" =&gt; \"&lt;computed&gt;\"\r\n  network_interface: \"\" =&gt; \"&lt;computed&gt;\"\r\n  private_ip:        \"\" =&gt; \"&lt;computed&gt;\"\r\n  public_ip:         \"\" =&gt; \"&lt;computed&gt;\"\r\n  vpc:               \"\" =&gt; \"&lt;computed&gt;\"\r\naws_iam_role.ecsInstanceRole: Creating...\r\n  arn:                   \"\" =&gt; \"&lt;computed&gt;\"\r\n  assume_role_policy:    \"\" =&gt; \"{\\n \\\"Version\\\": \\\"2008-10-17\\\",\\n \\\"Statement\\\": [\\n   {\\n     \\\"Sid\\\": \\\"\\\",\\n     \\\"Effect\\\": \\\"Allow\\\",\\n     \\\"Principal\\\": {\\n       \\\"Service\\\": \\\"ec2.amazonaws.com\\\"\\n     },\\n     \\\"Action\\\": \\\"sts:AssumeRole\\\"\\n   }\\n ]\\n}\\n\"\r\n  create_date:           \"\" =&gt; \"&lt;computed&gt;\"\r\n  force_detach_policies: \"\" =&gt; \"false\"\r\n  name:                  \"\" =&gt; \"ecsInstanceRole-95b3af27\"\r\n  path:                  \"\" =&gt; \"\/\"\r\n  unique_id:             \"\" =&gt; \"&lt;computed&gt;\"\r\naws_vpc.vpc: Creating...\r\n  assign_generated_ipv6_cidr_block: \"\" =&gt; \"false\"\r\n  cidr_block:                       \"\" =&gt; \"10.0.0.0\/16\"\r\n  default_network_acl_id:           \"\" =&gt; \"&lt;computed&gt;\"\r\n  default_route_table_id:           \"\" =&gt; \"&lt;computed&gt;\"\r\n  default_security_group_id:        \"\" =&gt; \"&lt;computed&gt;\"\r\n  dhcp_options_id:                  \"\" =&gt; \"&lt;computed&gt;\"\r\n  enable_classiclink:               \"\" =&gt; \"&lt;computed&gt;\"\r\n  enable_classiclink_dns_support:   \"\" =&gt; \"&lt;computed&gt;\"\r\n  enable_dns_hostnames:             \"\" =&gt; \"&lt;computed&gt;\"\r\n  enable_dns_support:               \"\" =&gt; \"true\"\r\n  instance_tenancy:                 \"\" =&gt; \"&lt;computed&gt;\"\r\n  ipv6_association_id:              \"\" =&gt; \"&lt;computed&gt;\"\r\n  ipv6_cidr_block:                  \"\" =&gt; \"&lt;computed&gt;\"\r\n  main_route_table_id:              \"\" =&gt; \"&lt;computed&gt;\"\r\n  tags.%:                           \"\" =&gt; \"1\"\r\n  tags.Name:                        \"\" =&gt; \"vpc-terraform\"\r\naws_ecs_cluster.ecs_cluster: Creation complete after 0s (ID: arn:aws:ecs:us-east-1:462818068088:cluster\/ecs-cluster)\r\ndata.template_file.user_data: Refreshing state...\r\naws_iam_role.ecsInstanceRole: Creation complete after 0s (ID: ecsInstanceRole-95b3af27)\r\naws_iam_role_policy.ecsInstanceRolePolicy: Creating...\r\n  name:   \"\" =&gt; \"ecsInstanceRolePolicy-95b3af27\"\r\n  policy: \"\" =&gt; \"{\\n \\\"Version\\\": \\\"2012-10-17\\\",\\n \\\"Statement\\\": [\\n   {\\n     \\\"Effect\\\": \\\"Allow\\\",\\n     \\\"Action\\\": [\\n       \\\"ecs:CreateCluster\\\",\\n       \\\"ecs:DeregisterContainerInstance\\\",\\n       \\\"ecs:DiscoverPollEndpoint\\\",\\n       \\\"ecs:Poll\\\",\\n       \\\"ecs:RegisterContainerInstance\\\",\\n       \\\"ecs:StartTelemetrySession\\\",\\n       \\\"ecs:Submit*\\\",\\n       \\\"ecr:GetAuthorizationToken\\\",\\n       \\\"ecr:BatchCheckLayerAvailability\\\",\\n       \\\"ecr:GetDownloadUrlForLayer\\\",\\n       \\\"ecr:BatchGetImage\\\",\\n       \\\"logs:CreateLogStream\\\",\\n       \\\"logs:PutLogEvents\\\"\\n     ],\\n     \\\"Resource\\\": \\\"*\\\"\\n   }\\n ]\\n}\\n\"\r\n  role:   \"\" =&gt; \"ecsInstanceRole-95b3af27\"\r\naws_iam_instance_profile.ecsInstanceProfile: Creating...\r\n  arn:         \"\" =&gt; \"&lt;computed&gt;\"\r\n  create_date: \"\" =&gt; \"&lt;computed&gt;\"\r\n  name:        \"\" =&gt; \"ecsInstanceProfile-95b3af27\"\r\n  path:        \"\" =&gt; \"\/\"\r\n  role:        \"\" =&gt; \"ecsInstanceRole-95b3af27\"\r\n  roles.#:     \"\" =&gt; \"&lt;computed&gt;\"\r\n  unique_id:   \"\" =&gt; \"&lt;computed&gt;\"\r\naws_iam_role.ecsServiceRole: Creation complete after 0s (ID: ecsServiceRole-95b3af27)\r\naws_iam_role_policy.ecsServiceRolePolicy: Creating...\r\n  name:   \"\" =&gt; \"ecsServiceRolePolicy-95b3af27\"\r\n  policy: \"\" =&gt; \"{\\n \\\"Version\\\": \\\"2012-10-17\\\",\\n \\\"Statement\\\": [\\n   {\\n     \\\"Effect\\\": \\\"Allow\\\",\\n     \\\"Action\\\": [\\n       \\\"ec2:AuthorizeSecurityGroupIngress\\\",\\n       \\\"ec2:Describe*\\\",\\n       \\\"elasticloadbalancing:DeregisterInstancesFromLoadBalancer\\\",\\n       \\\"elasticloadbalancing:DeregisterTargets\\\",\\n       \\\"elasticloadbalancing:Describe*\\\",\\n       \\\"elasticloadbalancing:RegisterInstancesWithLoadBalancer\\\",\\n       \\\"elasticloadbalancing:RegisterTargets\\\"\\n     ],\\n     \\\"Resource\\\": \\\"*\\\"\\n   }\\n ]\\n}\\n\"\r\n  role:   \"\" =&gt; \"ecsServiceRole-95b3af27\"\r\naws_iam_role_policy.ecsServiceRolePolicy: Creation complete after 1s (ID: ecsServiceRole-95b3af27:ecsServiceRolePolicy-95b3af27)\r\naws_iam_role_policy.ecsInstanceRolePolicy: Creation complete after 1s (ID: ecsInstanceRole-95b3af27:ecsInstanceRolePolicy-95b3af27)\r\naws_eip.gateway_eip: Creation complete after 1s (ID: eipalloc-25f39d17)\r\naws_iam_instance_profile.ecsInstanceProfile: Creation complete after 1s (ID: ecsInstanceProfile-95b3af27)\r\naws_vpc.vpc: Creation complete after 3s (ID: vpc-d82a38a1)\r\naws_internet_gateway.internet_gateway: Creating...\r\n  vpc_id: \"\" =&gt; \"vpc-d82a38a1\"\r\ndata.aws_security_group.vpc_default_sg: Refreshing state...\r\naws_subnet.public_subnet[0]: Creating...\r\n  assign_ipv6_address_on_creation: \"\" =&gt; \"false\"\r\n  availability_zone:               \"\" =&gt; \"us-east-1c\"\r\n  cidr_block:                      \"\" =&gt; \"10.0.10.0\/24\"\r\n  ipv6_cidr_block:                 \"\" =&gt; \"&lt;computed&gt;\"\r\n  ipv6_cidr_block_association_id:  \"\" =&gt; \"&lt;computed&gt;\"\r\n  map_public_ip_on_launch:         \"\" =&gt; \"false\"\r\n  tags.%:                          \"\" =&gt; \"1\"\r\n  tags.Name:                       \"\" =&gt; \"public-us-east-1c\"\r\n  vpc_id:                          \"\" =&gt; \"vpc-d82a38a1\"\r\naws_subnet.private_subnet[0]: Creating...\r\n  assign_ipv6_address_on_creation: \"\" =&gt; \"false\"\r\n  availability_zone:               \"\" =&gt; \"us-east-1c\"\r\n  cidr_block:                      \"\" =&gt; \"10.0.11.0\/24\"\r\n  ipv6_cidr_block:                 \"\" =&gt; \"&lt;computed&gt;\"\r\n  ipv6_cidr_block_association_id:  \"\" =&gt; \"&lt;computed&gt;\"\r\n  map_public_ip_on_launch:         \"\" =&gt; \"false\"\r\n  tags.%:                          \"\" =&gt; \"1\"\r\n  tags.Name:                       \"\" =&gt; \"private-us-east-1c\"\r\n  vpc_id:                          \"\" =&gt; \"vpc-d82a38a1\"\r\naws_subnet.private_subnet[1]: Creating...\r\n  assign_ipv6_address_on_creation: \"\" =&gt; \"false\"\r\n  availability_zone:               \"\" =&gt; \"us-east-1d\"\r\n  cidr_block:                      \"\" =&gt; \"10.0.22.0\/24\"\r\n  ipv6_cidr_block:                 \"\" =&gt; \"&lt;computed&gt;\"\r\n  ipv6_cidr_block_association_id:  \"\" =&gt; \"&lt;computed&gt;\"\r\n  map_public_ip_on_launch:         \"\" =&gt; \"false\"\r\n  tags.%:                          \"\" =&gt; \"1\"\r\n  tags.Name:                       \"\" =&gt; \"private-us-east-1d\"\r\n  vpc_id:                          \"\" =&gt; \"vpc-d82a38a1\"\r\naws_route_table.nat_route_table: Creating...\r\n  propagating_vgws.#: \"\" =&gt; \"&lt;computed&gt;\"\r\n  route.#:            \"\" =&gt; \"&lt;computed&gt;\"\r\n  vpc_id:             \"\" =&gt; \"vpc-d82a38a1\"\r\naws_subnet.private_subnet[2]: Creating...\r\n  assign_ipv6_address_on_creation: \"\" =&gt; \"false\"\r\n  availability_zone:               \"\" =&gt; \"us-east-1e\"\r\n  cidr_block:                      \"\" =&gt; \"10.0.33.0\/24\"\r\n  ipv6_cidr_block:                 \"\" =&gt; \"&lt;computed&gt;\"\r\n  ipv6_cidr_block_association_id:  \"\" =&gt; \"&lt;computed&gt;\"\r\n  map_public_ip_on_launch:         \"\" =&gt; \"false\"\r\n  tags.%:                          \"\" =&gt; \"1\"\r\n  tags.Name:                       \"\" =&gt; \"private-us-east-1e\"\r\n  vpc_id:                          \"\" =&gt; \"vpc-d82a38a1\"\r\naws_subnet.public_subnet[1]: Creating...\r\n  assign_ipv6_address_on_creation: \"\" =&gt; \"false\"\r\n  availability_zone:               \"\" =&gt; \"us-east-1d\"\r\n  cidr_block:                      \"\" =&gt; \"10.0.20.0\/24\"\r\n  ipv6_cidr_block:                 \"\" =&gt; \"&lt;computed&gt;\"\r\n  ipv6_cidr_block_association_id:  \"\" =&gt; \"&lt;computed&gt;\"\r\n  map_public_ip_on_launch:         \"\" =&gt; \"false\"\r\n  tags.%:                          \"\" =&gt; \"1\"\r\n  tags.Name:                       \"\" =&gt; \"public-us-east-1d\"\r\n  vpc_id:                          \"\" =&gt; \"vpc-d82a38a1\"\r\naws_subnet.public_subnet[2]: Creating...\r\n  assign_ipv6_address_on_creation: \"\" =&gt; \"false\"\r\n  availability_zone:               \"\" =&gt; \"us-east-1e\"\r\n  cidr_block:                      \"\" =&gt; \"10.0.30.0\/24\"\r\n  ipv6_cidr_block:                 \"\" =&gt; \"&lt;computed&gt;\"\r\n  ipv6_cidr_block_association_id:  \"\" =&gt; \"&lt;computed&gt;\"\r\n  map_public_ip_on_launch:         \"\" =&gt; \"false\"\r\n  tags.%:                          \"\" =&gt; \"1\"\r\n  tags.Name:                       \"\" =&gt; \"public-us-east-1e\"\r\n  vpc_id:                          \"\" =&gt; \"vpc-d82a38a1\"\r\naws_route_table.igw_route_table: Creating...\r\n  propagating_vgws.#: \"\" =&gt; \"&lt;computed&gt;\"\r\n  route.#:            \"\" =&gt; \"&lt;computed&gt;\"\r\n  vpc_id:             \"\" =&gt; \"vpc-d82a38a1\"\r\naws_launch_configuration.as_conf: Creating...\r\n  associate_public_ip_address:               \"\" =&gt; \"false\"\r\n  ebs_block_device.#:                        \"\" =&gt; \"&lt;computed&gt;\"\r\n  ebs_optimized:                             \"\" =&gt; \"&lt;computed&gt;\"\r\n  enable_monitoring:                         \"\" =&gt; \"true\"\r\n  iam_instance_profile:                      \"\" =&gt; \"ecsInstanceProfile-95b3af27\"\r\n  image_id:                                  \"\" =&gt; \"ami-9eb4b1e5\"\r\n  instance_type:                             \"\" =&gt; \"t2.micro\"\r\n  key_name:                                  \"\" =&gt; \"&lt;computed&gt;\"\r\n  name:                                      \"\" =&gt; \"&lt;computed&gt;\"\r\n  root_block_device.#:                       \"\" =&gt; \"1\"\r\n  root_block_device.0.delete_on_termination: \"\" =&gt; \"true\"\r\n  root_block_device.0.iops:                  \"\" =&gt; \"&lt;computed&gt;\"\r\n  root_block_device.0.volume_size:           \"\" =&gt; \"8\"\r\n  root_block_device.0.volume_type:           \"\" =&gt; \"&lt;computed&gt;\"\r\n  security_groups.#:                         \"\" =&gt; \"1\"\r\n  security_groups.3222359879:                \"\" =&gt; \"sg-22259851\"\r\n  user_data:                                 \"\" =&gt; \"6a9e54d9d2d8048547951c51c5adf62d234bc1a3\"\r\naws_route_table.nat_route_table: Creation complete after 1s (ID: rtb-7a613801)\r\naws_route_table.igw_route_table: Creation complete after 1s (ID: rtb-e66d349d)\r\naws_internet_gateway.internet_gateway: Creation complete after 2s (ID: igw-e9817490)\r\naws_subnet.public_subnet[1]: Creation complete after 2s (ID: subnet-05a7514e)\r\naws_route.igw_route: Creating...\r\n  destination_cidr_block:     \"\" =&gt; \"0.0.0.0\/0\"\r\n  destination_prefix_list_id: \"\" =&gt; \"&lt;computed&gt;\"\r\n  egress_only_gateway_id:     \"\" =&gt; \"&lt;computed&gt;\"\r\n  gateway_id:                 \"\" =&gt; \"igw-e9817490\"\r\n  instance_id:                \"\" =&gt; \"&lt;computed&gt;\"\r\n  instance_owner_id:          \"\" =&gt; \"&lt;computed&gt;\"\r\n  nat_gateway_id:             \"\" =&gt; \"&lt;computed&gt;\"\r\n  network_interface_id:       \"\" =&gt; \"&lt;computed&gt;\"\r\n  origin:                     \"\" =&gt; \"&lt;computed&gt;\"\r\n  route_table_id:             \"\" =&gt; \"rtb-e66d349d\"\r\n  state:                      \"\" =&gt; \"&lt;computed&gt;\"\r\naws_subnet.private_subnet[0]: Creation complete after 2s (ID: subnet-77cff95b)\r\naws_subnet.public_subnet[2]: Creation complete after 2s (ID: subnet-ebac68d4)\r\naws_subnet.private_subnet[2]: Creation complete after 2s (ID: subnet-51b6726e)\r\naws_subnet.public_subnet[0]: Creation complete after 2s (ID: subnet-e8cff9c4)\r\naws_route_table_association.public_route[1]: Creating...\r\n  route_table_id: \"\" =&gt; \"rtb-e66d349d\"\r\n  subnet_id:      \"\" =&gt; \"subnet-05a7514e\"\r\naws_nat_gateway.nat_gateway: Creating...\r\n  allocation_id:        \"\" =&gt; \"eipalloc-25f39d17\"\r\n  network_interface_id: \"\" =&gt; \"&lt;computed&gt;\"\r\n  private_ip:           \"\" =&gt; \"&lt;computed&gt;\"\r\n  public_ip:            \"\" =&gt; \"&lt;computed&gt;\"\r\n  subnet_id:            \"\" =&gt; \"subnet-e8cff9c4\"\r\naws_route_table_association.public_route[0]: Creating...\r\n  route_table_id: \"\" =&gt; \"rtb-e66d349d\"\r\n  subnet_id:      \"\" =&gt; \"subnet-e8cff9c4\"\r\naws_route_table_association.public_route[2]: Creating...\r\n  route_table_id: \"\" =&gt; \"rtb-e66d349d\"\r\n  subnet_id:      \"\" =&gt; \"subnet-ebac68d4\"\r\naws_subnet.private_subnet[1]: Creation complete after 2s (ID: subnet-2da45266)\r\naws_route_table_association.private_route[2]: Creating...\r\n  route_table_id: \"\" =&gt; \"rtb-7a613801\"\r\n  subnet_id:      \"\" =&gt; \"subnet-51b6726e\"\r\naws_route_table_association.private_route[1]: Creating...\r\n  route_table_id: \"\" =&gt; \"rtb-7a613801\"\r\n  subnet_id:      \"\" =&gt; \"subnet-2da45266\"\r\naws_db_subnet_group.db_subnet_group: Creating...\r\n  arn:                   \"\" =&gt; \"&lt;computed&gt;\"\r\n  description:           \"\" =&gt; \"Managed by Terraform\"\r\n  name:                  \"\" =&gt; \"db-subnet\"\r\n  name_prefix:           \"\" =&gt; \"&lt;computed&gt;\"\r\n  subnet_ids.#:          \"\" =&gt; \"3\"\r\n  subnet_ids.3804843734: \"\" =&gt; \"subnet-77cff95b\"\r\n  subnet_ids.4208861625: \"\" =&gt; \"subnet-51b6726e\"\r\n  subnet_ids.633931707:  \"\" =&gt; \"subnet-2da45266\"\r\naws_route_table_association.private_route[0]: Creating...\r\n  route_table_id: \"\" =&gt; \"rtb-7a613801\"\r\n  subnet_id:      \"\" =&gt; \"subnet-77cff95b\"\r\naws_route_table_association.public_route[0]: Creation complete after 0s (ID: rtbassoc-dc8eaca6)\r\naws_route_table_association.public_route[1]: Creation complete after 0s (ID: rtbassoc-2396b459)\r\naws_route_table_association.public_route[2]: Creation complete after 0s (ID: rtbassoc-448eac3e)\r\naws_route_table_association.private_route[2]: Creation complete after 0s (ID: rtbassoc-e991b393)\r\naws_route_table_association.private_route[0]: Creation complete after 0s (ID: rtbassoc-0e92b074)\r\naws_route_table_association.private_route[1]: Creation complete after 0s (ID: rtbassoc-578cae2d)\r\naws_route.igw_route: Creation complete after 0s (ID: r-rtb-e66d349d1080289494)\r\naws_db_subnet_group.db_subnet_group: Creation complete after 1s (ID: db-subnet)\r\naws_launch_configuration.as_conf: Creation complete after 10s (ID: terraform-006cb0894f43b7f99761fc5636)\r\naws_autoscaling_group.asg: Creating...\r\n  arn:                            \"\" =&gt; \"&lt;computed&gt;\"\r\n  default_cooldown:               \"\" =&gt; \"30\"\r\n  desired_capacity:               \"\" =&gt; \"3\"\r\n  force_delete:                   \"\" =&gt; \"false\"\r\n  health_check_grace_period:      \"\" =&gt; \"120\"\r\n  health_check_type:              \"\" =&gt; \"EC2\"\r\n  launch_configuration:           \"\" =&gt; \"terraform-006cb0894f43b7f99761fc5636\"\r\n  load_balancers.#:               \"\" =&gt; \"&lt;computed&gt;\"\r\n  max_size:                       \"\" =&gt; \"3\"\r\n  metrics_granularity:            \"\" =&gt; \"1Minute\"\r\n  min_size:                       \"\" =&gt; \"3\"\r\n  name:                           \"\" =&gt; \"asg-terraform-006cb0894f43b7f99761fc5636\"\r\n  protect_from_scale_in:          \"\" =&gt; \"false\"\r\n  target_group_arns.#:            \"\" =&gt; \"&lt;computed&gt;\"\r\n  vpc_zone_identifier.#:          \"\" =&gt; \"3\"\r\n  vpc_zone_identifier.3804843734: \"\" =&gt; \"subnet-77cff95b\"\r\n  vpc_zone_identifier.4208861625: \"\" =&gt; \"subnet-51b6726e\"\r\n  vpc_zone_identifier.633931707:  \"\" =&gt; \"subnet-2da45266\"\r\n  wait_for_capacity_timeout:      \"\" =&gt; \"10m\"\r\naws_nat_gateway.nat_gateway: Still creating... (10s elapsed)\r\naws_autoscaling_group.asg: Still creating... (10s elapsed)\r\naws_nat_gateway.nat_gateway: Still creating... (20s elapsed)\r\naws_autoscaling_group.asg: Still creating... (20s elapsed)\r\naws_nat_gateway.nat_gateway: Still creating... (30s elapsed)\r\naws_autoscaling_group.asg: Still creating... (30s elapsed)\r\naws_nat_gateway.nat_gateway: Still creating... (40s elapsed)\r\naws_autoscaling_group.asg: Still creating... (40s elapsed)\r\naws_nat_gateway.nat_gateway: Still creating... (50s elapsed)\r\naws_autoscaling_group.asg: Still creating... (50s elapsed)\r\naws_nat_gateway.nat_gateway: Still creating... (1m0s elapsed)\r\naws_autoscaling_group.asg: Still creating... (1m0s elapsed)\r\naws_nat_gateway.nat_gateway: Still creating... (1m10s elapsed)\r\naws_autoscaling_group.asg: Still creating... (1m10s elapsed)\r\naws_nat_gateway.nat_gateway: Still creating... (1m20s elapsed)\r\naws_autoscaling_group.asg: Creation complete after 1m19s (ID: asg-terraform-006cb0894f43b7f99761fc5636)\r\naws_nat_gateway.nat_gateway: Still creating... (1m30s elapsed)\r\naws_nat_gateway.nat_gateway: Creation complete after 1m38s (ID: nat-0fad1218a735c4ded)\r\naws_route.nat_route: Creating...\r\n  destination_cidr_block:     \"\" =&gt; \"0.0.0.0\/0\"\r\n  destination_prefix_list_id: \"\" =&gt; \"&lt;computed&gt;\"\r\n  egress_only_gateway_id:     \"\" =&gt; \"&lt;computed&gt;\"\r\n  gateway_id:                 \"\" =&gt; \"&lt;computed&gt;\"\r\n  instance_id:                \"\" =&gt; \"&lt;computed&gt;\"\r\n  instance_owner_id:          \"\" =&gt; \"&lt;computed&gt;\"\r\n  nat_gateway_id:             \"\" =&gt; \"nat-0fad1218a735c4ded\"\r\n  network_interface_id:       \"\" =&gt; \"&lt;computed&gt;\"\r\n  origin:                     \"\" =&gt; \"&lt;computed&gt;\"\r\n  route_table_id:             \"\" =&gt; \"rtb-7a613801\"\r\n  state:                      \"\" =&gt; \"&lt;computed&gt;\"\r\naws_route.nat_route: Creation complete after 0s (ID: r-rtb-7a6138011080289494)\r\n\r\nApply complete! Resources: 30 added, 0 changed, 0 destroyed.\r\nReleasing state lock. This may take a few moments...\r\n\r\nOutputs:\r\n\r\naws_zones = [\r\n    us-east-1c,\r\n    us-east-1d,\r\n    us-east-1e\r\n]\r\ndb_subnet_group_name = db-subnet\r\necsServiceRole_arn = arn:aws:iam::462818068088:role\/ecsServiceRole-95b3af27\r\necs_cluster_name = ecs-cluster\r\nprivate_subnet_ids = [\r\n    subnet-77cff95b,\r\n    subnet-2da45266,\r\n    subnet-51b6726e\r\n]\r\npublic_subnet_ids = [\r\n    subnet-e8cff9c4,\r\n    subnet-05a7514e,\r\n    subnet-ebac68d4\r\n]\r\nvpc_default_sg_id = sg-22259851\r\nvpc_id = vpc-d82a38a1<\/pre>\n<p>And just like that, the ECS cluster is ready for services to be deployed. Taking a look in AWS web console we can see there are three instances available and zero services running:<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/10\/image2.png\"><img decoding=\"async\" class=\"aligncenter wp-image-18943\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/10\/image2.png\" alt=\"\" width=\"860\" height=\"140\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/10\/image2.png 1039w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/10\/image2-300x49.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/10\/image2-768x125.png 768w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/10\/image2-1024x167.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Just for fun and also to show another very cool feature of Terraform, let\u2019s completely destroy everything we just created and recreate it.<\/p>\n<pre class=\"brush:php\">$ terraform destroy\r\n\u2026\u2026 \r\nAn execution plan has been generated and is shown below.\r\nResource actions are indicated with the following symbols:\r\n  - destroy\r\n\r\nTerraform will perform the following actions:\r\n\r\n  - aws_autoscaling_group.asg\r\n\r\n  - aws_db_subnet_group.db_subnet_group\r\n\r\n  - aws_ecs_cluster.ecs_cluster\r\n\r\n  - aws_eip.gateway_eip\r\n\r\n  - aws_iam_instance_profile.ecsInstanceProfile\r\n\r\n  - aws_iam_role.ecsInstanceRole\r\n\r\n  - aws_iam_role.ecsServiceRole\r\n\r\n  - aws_iam_role_policy.ecsInstanceRolePolicy\r\n\r\n  - aws_iam_role_policy.ecsServiceRolePolicy\r\n\r\n  - aws_internet_gateway.internet_gateway\r\n\r\n  - aws_launch_configuration.as_conf\r\n\r\n  - aws_nat_gateway.nat_gateway\r\n\r\n  - aws_route.igw_route\r\n\r\n  - aws_route.nat_route\r\n\r\n  - aws_route_table.igw_route_table\r\n\r\n  - aws_route_table.nat_route_table\r\n\r\n  - aws_route_table_association.private_route[0]\r\n\r\n  - aws_route_table_association.private_route[1]\r\n\r\n  - aws_route_table_association.private_route[2]\r\n\r\n  - aws_route_table_association.public_route[0]\r\n\r\n  - aws_route_table_association.public_route[1]\r\n\r\n  - aws_route_table_association.public_route[2]\r\n\r\n  - aws_subnet.private_subnet[0]\r\n\r\n  - aws_subnet.private_subnet[1]\r\n\r\n  - aws_subnet.private_subnet[2]\r\n\r\n  - aws_subnet.public_subnet[0]\r\n\r\n  - aws_subnet.public_subnet[1]\r\n\r\n  - aws_subnet.public_subnet[2]\r\n\r\n  - aws_vpc.vpc\r\n\r\n  - random_id.code\r\n\r\n\r\nPlan: 0 to add, 0 to change, 30 to destroy.\r\n\r\nDo you really want to destroy?\r\n  Terraform will destroy all your managed infrastructure, as shown above.\r\n  There is no undo. Only 'yes' will be accepted to confirm.\r\n\r\n  Enter a value: yes\r\n\u2026\u2026 \r\nDestroy complete! Resources: 30 destroyed.\r\n\r\n$ terraform apply\r\ndata.aws_ami.ecs_ami: Refreshing state...\r\nrandom_id.code: Creating...\r\n....\r\nApply complete! Resources: 30 added, 0 changed, 0 destroyed.\r\n....<\/pre>\n<p>Beautiful. With just two commands, we can destroy everything and recreate it.<\/p>\n<h2>Summing It Up<\/h2>\n<p>Today we did a lot of work. Well, to be honest we did a lot of configuring and let the robots in our computers do the work. And that is exactly how I like it. To have done all of that work manually in the AWS console would have taken hours.<\/p>\n<p>In the next post, we\u2019ll complete this tutorial by defining the actual Docker service to build on this shared environment and have something to play with.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td>Published on Web Code Geeks with permission by Phillip Shipley, partner at our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\" target=\"_blank\" rel=\"noopener\">WCG program<\/a>. See the original article here: <a href=\"https:\/\/blog.codeship.com\/shared-resources-for-your-terraformed-docker-environment-on-aws\/\" target=\"_blank\" rel=\"noopener\">Shared Resources for Your Terraformed Docker Environment on AWS<\/a><\/p>\n<p>Opinions expressed by Web Code Geeks contributors are their own.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In Part 1 of this series, we laid the groundwork for Terraforming infrastructure on Amazon. Today we\u2019ll define our actual infrastructure consisting of networks, servers, etc. Have fun! Shared Resources Declaration Since our service depends on underlying resources like the VPC and EC2 instances, we\u2019ll create the shared environment first. Make sure you\u2019re in the &hellip;<\/p>\n","protected":false},"author":177,"featured_media":10356,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[325,217],"class_list":["post-18941","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","tag-amazon-aws","tag-docker"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Shared Resources for Your Terraformed Docker Environment on AWS - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"In Part 1 of this series, we laid the groundwork for Terraforming infrastructure on Amazon. Today we\u2019ll define our actual infrastructure consisting of\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Shared Resources for Your Terraformed Docker Environment on AWS - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"In Part 1 of this series, we laid the groundwork for Terraforming infrastructure on Amazon. Today we\u2019ll define our actual infrastructure consisting of\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2017-10-12T09:15:54+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/01\/docker-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Phillip Shipley\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Phillip Shipley\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"23 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/\"},\"author\":{\"name\":\"Phillip Shipley\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/10c965829d30e960ace15d97e738b032\"},\"headline\":\"Shared Resources for Your Terraformed Docker Environment on AWS\",\"datePublished\":\"2017-10-12T09:15:54+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/\"},\"wordCount\":871,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/01\/docker-logo.jpg\",\"keywords\":[\"Amazon AWS\",\"Docker\"],\"articleSection\":[\"DevOps\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/\",\"name\":\"Shared Resources for Your Terraformed Docker Environment on AWS - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/01\/docker-logo.jpg\",\"datePublished\":\"2017-10-12T09:15:54+00:00\",\"description\":\"In Part 1 of this series, we laid the groundwork for Terraforming infrastructure on Amazon. Today we\u2019ll define our actual infrastructure consisting of\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/01\/docker-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/01\/docker-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"DevOps\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/devops\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Shared Resources for Your Terraformed Docker Environment on AWS\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/10c965829d30e960ace15d97e738b032\",\"name\":\"Phillip Shipley\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a5e188393958c4505bb06d9e79ed99a47d1cd42551142f02ef364d8268449ef8?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a5e188393958c4505bb06d9e79ed99a47d1cd42551142f02ef364d8268449ef8?s=96&d=mm&r=g\",\"caption\":\"Phillip Shipley\"},\"description\":\"Phillip Shipley is the IT Applications Development manager at SIL International, Inc. He spends the majority of his work time developing web applications and has a particular passion for APIs and integration. When he\u2019s not building software, he\u2019s probably building LEGO with his son.\",\"url\":\"https:\/\/www.webcodegeeks.com\/author\/phillip-shipley\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Shared Resources for Your Terraformed Docker Environment on AWS - Web Code Geeks - 2026","description":"In Part 1 of this series, we laid the groundwork for Terraforming infrastructure on Amazon. Today we\u2019ll define our actual infrastructure consisting of","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/","og_locale":"en_US","og_type":"article","og_title":"Shared Resources for Your Terraformed Docker Environment on AWS - Web Code Geeks - 2026","og_description":"In Part 1 of this series, we laid the groundwork for Terraforming infrastructure on Amazon. Today we\u2019ll define our actual infrastructure consisting of","og_url":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2017-10-12T09:15:54+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/01\/docker-logo.jpg","type":"image\/jpeg"}],"author":"Phillip Shipley","twitter_card":"summary_large_image","twitter_creator":"@webcodegeeks","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Phillip Shipley","Est. reading time":"23 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/"},"author":{"name":"Phillip Shipley","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/10c965829d30e960ace15d97e738b032"},"headline":"Shared Resources for Your Terraformed Docker Environment on AWS","datePublished":"2017-10-12T09:15:54+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/"},"wordCount":871,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/01\/docker-logo.jpg","keywords":["Amazon AWS","Docker"],"articleSection":["DevOps"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/","url":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/","name":"Shared Resources for Your Terraformed Docker Environment on AWS - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/01\/docker-logo.jpg","datePublished":"2017-10-12T09:15:54+00:00","description":"In Part 1 of this series, we laid the groundwork for Terraforming infrastructure on Amazon. Today we\u2019ll define our actual infrastructure consisting of","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/01\/docker-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/01\/docker-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/devops\/shared-resources-terraformed-docker-environment-aws\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"DevOps","item":"https:\/\/www.webcodegeeks.com\/category\/devops\/"},{"@type":"ListItem","position":3,"name":"Shared Resources for Your Terraformed Docker Environment on AWS"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/10c965829d30e960ace15d97e738b032","name":"Phillip Shipley","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a5e188393958c4505bb06d9e79ed99a47d1cd42551142f02ef364d8268449ef8?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a5e188393958c4505bb06d9e79ed99a47d1cd42551142f02ef364d8268449ef8?s=96&d=mm&r=g","caption":"Phillip Shipley"},"description":"Phillip Shipley is the IT Applications Development manager at SIL International, Inc. He spends the majority of his work time developing web applications and has a particular passion for APIs and integration. When he\u2019s not building software, he\u2019s probably building LEGO with his son.","url":"https:\/\/www.webcodegeeks.com\/author\/phillip-shipley\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/18941","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/177"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=18941"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/18941\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/10356"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=18941"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=18941"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=18941"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}