Skip to content

Apply

Finally we get to create some actual infrastructure in AWS. All your hard work is about to pay off!

Warning

You may be about to incur an actual real-world financial obligation to AWS! The code/plan you're about to execute will result in commercial resources going live inside of your AWS account which cost actual money you will owe to AWS.

Please ensure you're happy to proceed for executing the next few commands.

Executing

Now all we have to do is use the apply subcommand:

1
terraform apply latest.plan

Which will instruct Terraform to start building out our live infrastructure. Hooray!

Here's the kind of output you'll see:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
$ terraform apply latest.plan 
Acquiring state lock. This may take a few moments...

aws_key_pair.httpcats: Creating...
aws_acm_certificate.cert: Creating...
aws_vpc.httpcats: Creating...
aws_key_pair.httpcats: Creation complete after 0s [id=deployment-key]
aws_vpc.httpcats: Creation complete after 2s [id=vpc-0a1f4b32aa751e728]
aws_internet_gateway.httpcats: Creating...
aws_subnet.httpcats-http-az-b: Creating...
aws_security_group.webserver: Creating...
aws_alb_target_group.cats: Creating...
aws_security_group.alb: Creating...
aws_subnet.httpcats-http-az-a: Creating...
aws_subnet.httpcats-http-az-b: Creation complete after 1s [id=subnet-094ee94d22e10f6bf]
aws_alb_target_group.cats: Creation complete after 1s [id=arn:aws:elasticloadbalancing:ap-southeast-2:040925562967:targetgroup/httpcats-web-servers/90e60d432567727a]
aws_subnet.httpcats-http-az-a: Creation complete after 1s [id=subnet-0314f41759bfa5da1]
aws_internet_gateway.httpcats: Creation complete after 1s [id=igw-0f77b86e6eaa593fa]
aws_route_table.httpcats: Creating...
aws_security_group.webserver: Creation complete after 1s [id=sg-03ad0848b17ecfa3c]
aws_security_group_rule.webserver-egress: Creating...
aws_security_group_rule.http-custom: Creating...
aws_security_group_rule.ssh: Creating...
aws_instance.meow_2: Creating...
aws_instance.meow_1: Creating...
aws_security_group.alb: Creation complete after 1s [id=sg-070192baa6a8d9777]
aws_security_group_rule.egress_all: Creating...
aws_security_group_rule.alb-https: Creating...
aws_alb.httpcats: Creating...
aws_route_table.httpcats: Creation complete after 0s [id=rtb-049538b7ee2256abb]
aws_route_table_association.httpcats-http-az-a: Creating...
aws_security_group_rule.http-custom: Creation complete after 1s [id=sgrule-3301115553]
aws_route_table_association.httpcats-http-az-b: Creating...
aws_route_table_association.httpcats-http-az-a: Creation complete after 1s [id=rtbassoc-0c636abbe3d293681]
aws_route_table_association.httpcats-http-az-b: Creation complete after 0s [id=rtbassoc-06fc4fa44d3bb97fa]
aws_security_group_rule.egress_all: Creation complete after 1s [id=sgrule-28896275]
aws_security_group_rule.ssh: Creation complete after 1s [id=sgrule-4011901088]
aws_security_group_rule.alb-https: Creation complete after 2s [id=sgrule-1491041586]
aws_security_group_rule.webserver-egress: Creation complete after 2s [id=sgrule-1557663500]
aws_acm_certificate.cert: Creation complete after 7s [id=arn:aws:acm:ap-southeast-2:040925562967:certificate/74cb5318-73ff-426d-85b0-6adf073eb243]
aws_route53_record.httpcats["httpcats.net"]: Creating...
aws_route53_record.httpcats["www.httpcats.net"]: Creating...
aws_instance.meow_2: Still creating... [10s elapsed]
aws_instance.meow_1: Still creating... [10s elapsed]
aws_alb.httpcats: Still creating... [10s elapsed]
aws_route53_record.httpcats["www.httpcats.net"]: Still creating... [10s elapsed]
aws_route53_record.httpcats["httpcats.net"]: Still creating... [10s elapsed]
aws_instance.meow_2: Still creating... [20s elapsed]
aws_instance.meow_1: Still creating... [20s elapsed]
aws_alb.httpcats: Still creating... [20s elapsed]
aws_route53_record.httpcats["httpcats.net"]: Still creating... [20s elapsed]
aws_route53_record.httpcats["www.httpcats.net"]: Still creating... [20s elapsed]
aws_instance.meow_1: Still creating... [30s elapsed]
aws_instance.meow_2: Still creating... [30s elapsed]
aws_alb.httpcats: Still creating... [30s elapsed]
aws_instance.meow_1: Creation complete after 32s [id=i-098d2d239f4cf5f81]
aws_lb_target_group_attachment.meow-a: Creating...
aws_eip.meow_1: Creating...
aws_lb_target_group_attachment.meow-a: Creation complete after 1s [id=arn:aws:elasticloadbalancing:ap-southeast-2:040925562967:targetgroup/httpcats-web-servers/90e60d432567727a-20210715021120647500000002]
aws_eip.meow_1: Creation complete after 1s [id=eipalloc-02cfb8ca4a15d9a2f]
aws_route53_record.ssh-1: Creating...
aws_route53_record.httpcats["www.httpcats.net"]: Still creating... [30s elapsed]
aws_route53_record.httpcats["httpcats.net"]: Still creating... [30s elapsed]
aws_instance.meow_2: Still creating... [40s elapsed]
aws_alb.httpcats: Still creating... [40s elapsed]
aws_instance.meow_2: Creation complete after 43s [id=i-06b8891f95d18c8c3]
aws_lb_target_group_attachment.meow-b: Creating...
aws_eip.meow_2: Creating...
aws_lb_target_group_attachment.meow-b: Creation complete after 0s [id=arn:aws:elasticloadbalancing:ap-southeast-2:040925562967:targetgroup/httpcats-web-servers/90e60d432567727a-20210715021130813500000003]
aws_route53_record.ssh-1: Still creating... [10s elapsed]
aws_eip.meow_2: Creation complete after 1s [id=eipalloc-03099ae795954b1da]
aws_route53_record.ssh-2: Creating...
aws_route53_record.httpcats["httpcats.net"]: Still creating... [40s elapsed]
aws_route53_record.httpcats["www.httpcats.net"]: Still creating... [40s elapsed]
aws_alb.httpcats: Still creating... [50s elapsed]
aws_route53_record.ssh-1: Still creating... [20s elapsed]
aws_route53_record.ssh-2: Still creating... [10s elapsed]
aws_route53_record.httpcats["www.httpcats.net"]: Still creating... [50s elapsed]
aws_route53_record.httpcats["httpcats.net"]: Still creating... [50s elapsed]
aws_route53_record.httpcats["www.httpcats.net"]: Creation complete after 53s [id=Z07304002IQEID723SY3V__9845abd68eced41b2ce6d8ebb45e7f29.www.httpcats.net._CNAME]
aws_route53_record.httpcats["httpcats.net"]: Creation complete after 53s [id=Z07304002IQEID723SY3V__1dd361ca21da159c9e69d2b310b29897.httpcats.net._CNAME]
aws_acm_certificate_validation.cert: Creating...
aws_acm_certificate_validation.cert: Creation complete after 1s [id=2021-07-15 02:11:09 +0000 UTC]
aws_alb.httpcats: Still creating... [1m0s elapsed]
aws_route53_record.ssh-1: Still creating... [30s elapsed]
aws_route53_record.ssh-2: Still creating... [20s elapsed]
aws_alb.httpcats: Still creating... [1m10s elapsed]
aws_route53_record.ssh-1: Still creating... [41s elapsed]
aws_route53_record.ssh-2: Still creating... [30s elapsed]
aws_alb.httpcats: Still creating... [1m20s elapsed]
aws_route53_record.ssh-1: Still creating... [51s elapsed]
aws_route53_record.ssh-2: Still creating... [40s elapsed]
aws_route53_record.ssh-1: Creation complete after 54s [id=Z07304002IQEID723SY3V_ssh-1_A]
aws_alb.httpcats: Still creating... [1m30s elapsed]
aws_route53_record.ssh-2: Still creating... [50s elapsed]
aws_route53_record.ssh-2: Creation complete after 53s [id=Z07304002IQEID723SY3V_ssh-2_A]
aws_alb.httpcats: Still creating... [1m40s elapsed]
aws_alb.httpcats: Still creating... [1m50s elapsed]
aws_alb.httpcats: Still creating... [2m0s elapsed]
aws_alb.httpcats: Still creating... [2m10s elapsed]
aws_alb.httpcats: Still creating... [2m21s elapsed]
aws_alb.httpcats: Creation complete after 2m23s [id=arn:aws:elasticloadbalancing:ap-southeast-2:040925562967:loadbalancer/app/httpcats-beta/0f39ca94f4d032fe]
aws_route53_record.www: Creating...
aws_alb_listener.http: Creating...
aws_alb_listener.http: Creation complete after 1s [id=arn:aws:elasticloadbalancing:ap-southeast-2:040925562967:listener/app/httpcats-beta/0f39ca94f4d032fe/dd95d3ac1f88fbc9]
aws_lb_listener_rule.cats: Creating...
aws_lb_listener_rule.cats: Creation complete after 0s [id=arn:aws:elasticloadbalancing:ap-southeast-2:040925562967:listener-rule/app/httpcats-beta/0f39ca94f4d032fe/dd95d3ac1f88fbc9/440f502cc11a4130]
aws_route53_record.www: Still creating... [10s elapsed]
aws_route53_record.www: Still creating... [20s elapsed]
aws_route53_record.www: Still creating... [30s elapsed]
aws_route53_record.www: Still creating... [40s elapsed]
aws_route53_record.www: Creation complete after 42s [id=Z07304002IQEID723SY3V_www_A]

Apply complete! Resources: 32 added, 0 changed, 0 destroyed.

Terraform has finished executing the plan we made earlier and we now have our infrastructure built.

Let's review a few of the characteristics of the output we got.

Creating and Created

Check out this selection of lines from the output above:

1
2
3
4
5
aws_key_pair.httpcats: Creating...
aws_acm_certificate.cert: Creating...
aws_vpc.httpcats: Creating...
aws_key_pair.httpcats: Creation complete after 0s [id=deployment-key]
aws_vpc.httpcats: Creation complete after 2s [id=vpc-0a1f4b32aa751e728]

We can see that Terraform is using the AWS API to create some resources for us. These are:

  • aws_key_pair.httpcats
  • aws_acm_certificate.cert
  • aws_vpc.httpcats

In the output I've selected above a few things is happening.

The first thing to notice is Terraform has used the AWS Terraform provider to talk to the AWS API (using our credentials) and requested to create the resources above. We can see this when we see X: Creating..., where X is some resource in our code such as aws_key_pair.httpcats.

Then we can see that of the three resources it's requesting AWS to create, it has completed two of them: aws_key_pair.httpcats and aws_vpc.httpcats. We can see this in the form of this (more interesting) line: aws_vpc.httpcats: Creation complete after 2s [id=vpc-0a1f4b32aa751e728] that we got our VPC created and the ID is vpc-0a1f4b32aa751e728.

Note

The IDs you see in my output are unique to my AWS account. We won't see the same values.

Breaking down the Creation complete line a bit, we have X: Creation complete after N [id=Y] where X is the resource; N is the amount of time it took to create the resource and Y is the ID, if applicable, we got back from the AWS API. Y represents the ID internally to AWS and is used to manage the resource in the future if we make code changes.

State

It's repeating that we won't get a terraform.tfstate file locally after creating this file. Instead the state is stored in GitLab for us because of our terraform { backend {} } configuration in main.tf.

Summary

Like the plan subcommand apply also gives us a summary:

1
Apply complete! Resources: 32 added, 0 changed, 0 destroyed.

This is helpful because we can check this against what we expected to see and potentially detect any problems with our code or whether or not we missed something out.


Last update: August 25, 2021