diff --git a/README.md b/README.md index 56b06daf85cb5be95fddc251dbad4059a3e86b14..87b0792cd980400585fee6df4eeb2880fc4d9bf7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# # Lab: Cloud provisioning/orchestration - Terraform and AWS +## Lab: Cloud provisioning/orchestration - Terraform and AWS Lab with Terraform and any Cloud @@ -82,16 +82,20 @@ resource "aws_instance" "app_server" { } ``` -To find `<your-AWS-AMI-ID>`, you can query the AMI Catalog via +<a name="AMI-query"></a>To find `<your-AWS-AMI-ID>`, you can query the AMI Catalog via a. [AWS dashboard](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#AMICatalog:), searching "Ubuntu", selecting "Quickstart AMIs" and filtering by "Free-tier", - b. or with CLI, and get the most recent AMI: + b. or (preferred) with CLI, and get the 2 most recent AMIs: ``` shell lcl$ aws ec2 describe-images --region us-east-1 \ --filters "Name=root-device-type,Values=ebs" \ "Name=name,Values= ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server*" \ - --query "reverse(sort_by(Images, &ImageId))[:1].[ImageId]" --output text + --query "reverse(sort_by(Images, &ImageId))[:2].[ImageId]" --output text + ami-0fa37863afb290840 + ami-0e2512bd9da751ea8 ``` +:bulb: In the following task(s), we use the first AMI found. + Initialize your sandbox with: ``` shell @@ -163,9 +167,7 @@ Do you want to perform these actions? Enter a value: yes aws_instance.app_server: Creating... -aws_instance.app_server: Still creating... [10s elapsed] -aws_instance.app_server: Still creating... [20s elapsed] -aws_instance.app_server: Still creating... [30s elapsed] +... aws_instance.app_server: Creation complete after 38s [id=i-0155ba9d77ee0a854] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. @@ -182,7 +184,7 @@ You can verify via the AWS dashboard that one EC2 instance has been created. The state of the resources acted upon is locally stored. Let's see what's in our sandbox: ``` shell -$ tree -a +lcl$ tree -a . ├── .terraform │ └── providers @@ -196,13 +198,13 @@ $ tree -a following commands: ``` shell -$ terraform state list +lcl$ terraform state list aws_instance.app_server ``` It confirms that we're tracking one AWS instance. Let's dig a bit more: ``` shell -$ terraform show +lcl$ terraform show # aws_instance.app_server: resource "aws_instance" "app_server" { ami = "ami-0fa37863afb290840" @@ -232,9 +234,83 @@ resource "aws_instance" "app_server" { ``` The above command output provides useful runtime (state) information, like the -instance IP's address. +instance IP's address. Indeed, there is a kind of *digital twin* stored inside +the file `terraform.tfstate`. :question: Is that instance accessible via SSH? Give it a try. If not, why? +Now, stop the running instance (its ID is shown above ;-): + +``` shell +lcl$ aws ec2 stop-instances --instance-ids i-0155ba9d77ee0a854 +``` + +wait some seconds and test again: + +``` shell +lcl$ terraform show | grep instance_state + instance_state = "running" +``` + +How come? We just discovered that TF read only the local status of a +resource. So, let's refresh it, and check again: + +``` shell +lcl$ terraform refresh +aws_instance.app_server: Refreshing state... [id=i-0155ba9d77ee0a854] +lcl$ terraform show | grep instance_state + instance_state = "stopped" +``` + +Ah-ha! + +Hold on a second: our TF plan does not specify the desired status of a +resource. What happens if we reapply the plan? Lets' try: + +``` shell +lcl$ terraform apply -auto-approve +aws_instance.app_server: Refreshing state... [id=i-0155ba9d77ee0a854] + +No changes. Your infrastructure matches the configuration. + +Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed. + +Apply complete! Resources: 0 added, 0 changed, 0 destroyed. +lcl$ terraform show | grep instance_state + instance_state = "stopped" +``` + +From the above commands' output we see that + * the local state is refreshed before doing anything, + * no changes are applied, and + * huh?... the resource is still stopped. + +Concerning the last point above, think about the basic objectives of TF: as a +provisioning tool it is concerned with the *existence* of a resource, not with +its *runtime* state. This latter is the business of configuration management +tools. :bulb: There is no way with TF to specify a resource's desired runtime +state. + ### Task #4: change your infrastructure ### + +**Goal:** modify the resource created before, and learn how to apply changes +to a Terraform project. + +Restart your managed instance: + +``` shell +lcl$ aws ec2 start-instances --instance-ids i-0155ba9d77ee0a854 +``` + +Refresh TF's view of the world: + +``` shell +lcl$ terraform refresh +aws_instance.app_server: Refreshing state... [id=i-0155ba9d77ee0a854] +lcl$ terraform show | grep instance_state + instance_state = "running" +``` + +Modify the resource's `ami` in `main.tf` (here we use the second one found +from the [catalog query done above](#AMI-query))