If the management and provision of IT Infrastructure is handled by the code (configuration file), then this is Infrastructure as Code (IaC). Here are some questions, Why do we need IaC?, What problems does IaC solve? I will try to answer all these questions in one go.
The first problem we face is “environment drift”. IaC has evolved to solve this problem. Atlassian defines environment drift as follows:
Cloud applications usually have separate deployment environments for the stages of their release lifecycle. It’s common to have development, staging, and production environments. These environments are composed of networked resources like application servers, load balancers, and databases. Environment drift occurs when the infrastructure between these different environments falls out of sync.
Without IaC, we have to face the pain of managing infrastructure. Historically, in the early stages of IT Infrastructure management, all processes were manual. Here, the manual management part continues to evolve. What does it mean? We can explain how manual management has different meanings in three different eras, these eras are Traditional, Virtualization and Cloud. During these eras, manual management has evolved from physical management to cloud computing, but it is still manual. Although the management of infrastructure parts has become more flexible with Cloud Computing, our needs have become increasingly complex. The main reason for the increase in these complexes is that we need different environments. Infrastructure scaling is getting harder and harder without an IaC practice.
We can say that some of the biggest problems in infrastructure management are:
Cost
Scalability
Availability
Inconsistency
Inconsistency is a major problem. Because we can easily handle other problems with cloud computing. But it does almost nothing to solve the inconsistency problem. Right here, IaC appears as the missing piece of the puzzle. This missing puzzle piece helps manage IT infrastructure needs while increasing consistency and reducing errors and manual configuration. At this stage, we can list the benefits of IaC.
Cost Reduction
Speed
Reduce Human Errors
Improve Infrastructure Consistency
Eliminate Configuration Drift
Detailing these benefits should be the subject of another article. Before we end this topic, let's list some popular IaC tools.
Chef
Puppet
Terraform
Ansible
AWS CloudFormation
Here we will continue our article with Terraform.
From here we will continue with a simple tutorial. Pre-requirements for this tutorial:
Terraform
#UBUNTU/DEBIAN
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
#FEDORA
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
sudo dnf -y install terraform
HC Access Key ID/Secret Acces Key
Let's go to the optional location and start writing our main.tf file.
$ mkdir tf_hc_ecs_demo
$ cd tf_hc_ecs_demo
$ vim main.tf
We write 4 main blocks in the main.tf file. The first of these is the terraform block. The other block we use under this block is required_providers. With this block, we specify the provider requirements.
terraform {
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.20.0"
}
}
}
In the second main block, we configure the authentication and region settings. After this stage, we can now start managing our infrastructure with code.
provider "huaweicloud" {
region = "ap-southeast-3"
access_key = "AK"
secret_key = "SK"
}
We use data block in the third main block. Terraform defines Data Source as follows:
Data sources allow Terraform to use information defined outside of Terraform, defined by another separate Terraform configuration, or modified by functions.
A data block requests that Terraform read from a given data source ("huaweicloud_vpc_subnet") and export the result under the given local name ("mynet"). The name is used to refer to this resource from elsewhere in the same Terraform module. In this way, we use an existing network very simply when creating ECS.
data "huaweicloud_vpc_subnet" "mynet" {
name = "default-subnet"
}
The next block in the main.tf file describes the resource you want to provision i.e. the ECS instance. This ECS code block is an example of a Terraform resource. Resources are the most important elements in Terraform as they are directly responsible for provisioning the infrastructure.
resource "huaweicloud_compute_instance" "hello_ecs" {
name = "ecs_demo"
#image_id = "blank"
image_name = "Ubuntu 18.04 server 64bit"
flavor_id = "s3.large.2"
#flavor_name = “blank”
key_pair = "local-kp"
security_group_ids = ["fa7a59fe-c13f-41ee-9dff-beffea3ec743"]
network {
uuid = data.huaweicloud_vpc_subnet.mynet.id
}
}
Let's take a closer look at this block. The resource block has two labels. One specifies the type of the resource (huaweicloud_compute_instance), and the other specifies the name of the resource (hello_ecs). Each resource takes some arguments. In this case, the arguments are:
name: Specifies a unique name for the instance.
image_id: Specifies the image ID of the desired image for the instance.
image_name: Specifies the name of the desired image for the instance.
flavor_id: Specifies the flavor ID of the desired flavor for the instance.
flavor_name: Specifies the name of the desired flavor for the instance.
key_pair: Specifies the SSH keypair name used for logging in to the instance.
security_group_ids: Specifies an array of one or more security group IDs to associate with the instance.
network.uuid: The uuid under the network block, specifies the network UUID to attach to the instance.
If you have noticed, image_name is used while image_id is the comment line. This is because one of the two needs to be defined. Likewise, this is mandatory for flavor_id and flavor_name and network is a block while uuid is an argument of the network block.
Illustrator basically shows how Terraform works.
The whole main.tf file is as follows:
terraform {
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.20.0"
}
}
}
data "huaweicloud_vpc_subnet" "mynet" {
name = "default-subnet"
}
provider "huaweicloud" {
region = "ap-southeast-3"
access_key = "AK"
secret_key = "SK"
}
resource "huaweicloud_compute_instance" "hello_ecs" {
name = "ecs_demo"
#image_id = "some_id"
image_name = "Ubuntu 18.04 server 64bit"
flavor_id = "s3.large.2"
key_pair = "local-kp"
security_group_ids = ["fa7a59fe-c13f-41ee-9dff-beffea3ec743"]
network {
uuid = data.huaweicloud_vpc_subnet.mynet.id
}
}
Now that all preparations are completed, we can deploy the HC ECS instance using Terraform. The first command we will encounter is terraform init. The terraform init command initializes a working directory containing Terraform configuration files. This is the first command that should be run after writing a new Terraform configuration or cloning an existing one from version control. At this point, you will find an additional folder .terraform popup in your workspace. This contains the downloaded binary for the HC provider.
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding huaweicloud/huaweicloud versions matching ">= 1.20.0"...
- Installing huaweicloud/huaweicloud v1.44.1...
- Installed huaweicloud/huaweicloud v1.44.1 (self-signed, key ID)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
$ tree -a
├── maint.tf
├── .terraform
│ └── providers
│ └── registry.terraform.io
│ └── huaweicloud
│ └── huaweicloud
│ └── 1.44.1
│ └── linux_amd64
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ └── terraform-provider-huaweicloud_v1.44.1
└── .terraform.lock.hcl
We can use the optional terraform plan command, which I highly recommend. The terraform plan command creates an execution plan, which lets you preview the changes that Terraform plans to make to your infrastructure.
$ terraform plan
data.huaweicloud_vpc_subnet.mynet: Reading...
data.huaweicloud_vpc_subnet.mynet: Read complete after 3s [id=b90005d9-f8c8-423f-926b-3023b71824c5]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# huaweicloud_compute_instance.hello_ecs will be created
+ resource "huaweicloud_compute_instance" "hello_ecs" {
+ access_ip_v4 = (known after apply)
+ access_ip_v6 = (known after apply)
+ availability_zone = (known after apply)
+ charging_mode = (known after apply)
+ delete_eip_on_termination = true
+ enterprise_project_id = (known after apply)
+ flavor_id = "s3.large.2"
+ flavor_name = (known after apply)
+ id = (known after apply)
+ image_id = (known after apply)
+ image_name = "Ubuntu 18.04 server 64bit"
+ key_pair = "local-kp"
+ name = "ecs_demo"
+ power_action = (known after apply)
+ public_ip = (known after apply)
+ region = (known after apply)
+ security_group_ids = [
+ "fa7a59fe-c13f-41ee-9dff-beffea3ec743",
]
+ security_groups = (known after apply)
+ spot_duration_count = (known after apply)
+ status = (known after apply)
+ stop_before_destroy = false
+ system_disk_id = (known after apply)
+ system_disk_size = (known after apply)
+ system_disk_type = (known after apply)
+ volume_attached = (known after apply)
+ network {
+ access_network = false
+ fixed_ip_v4 = (known after apply)
+ fixed_ip_v6 = (known after apply)
+ mac = (known after apply)
+ port = (known after apply)
+ source_dest_check = true
+ uuid = "b90005d9-f8c8-423f-926b-3023b71824c5"
}
+ scheduler_hints {
+ deh_id = (known after apply)
+ fault_domain = (known after apply)
+ group = (known after apply)
+ tenancy = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Once the initialization is successful, you are ready to deploy the ECS instance using Terraform. Execute the terraform apply command and answer “yes” to the confirmation prompt.
$ terraform apply
data.huaweicloud_vpc_subnet.mynet: Reading...
data.huaweicloud_vpc_subnet.mynet: Read complete after 2s [id=b90005d9-f8c8-423f-926b-3023b71824c5]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# huaweicloud_compute_instance.hello_ecs will be created
+ resource "huaweicloud_compute_instance" "hello_ecs" {
+ access_ip_v4 = (known after apply)
+ access_ip_v6 = (known after apply)
+ availability_zone = (known after apply)
+ charging_mode = (known after apply)
+ delete_eip_on_termination = true
+ enterprise_project_id = (known after apply)
+ flavor_id = "s3.large.2"
...
...
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
huaweicloud_compute_instance.hello_ecs: Creating...
huaweicloud_compute_instance.hello_ecs: Still creating... [10s elapsed]
huaweicloud_compute_instance.hello_ecs: Still creating... [20s elapsed]
huaweicloud_compute_instance.hello_ecs: Still creating... [30s elapsed]
huaweicloud_compute_instance.hello_ecs: Creation complete after 57s [id=f61feb8c-fcb8-4f3a-a39e-a82faf81115f]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Let's check the ECS in the HC console. The instance is created in the ap-southeast-3 region as specified in the Terraform configuration file.
Destroying the infrastructure managed by Terraform is as easy as executing the terraform destroy command. This command also prompts for a confirmation, and if you answer “yes" Terraform goes ahead and destroys the ECS instance.
$ terraform destroy
data.huaweicloud_vpc_subnet.mynet: Reading...
data.huaweicloud_vpc_subnet.mynet: Read complete after 3s [id=b90005d9-f8c8-423f-926b-3023b71824c5]
huaweicloud_compute_instance.hello_ecs: Refreshing state... [id=f61feb8c-fcb8-4f3a-a39e-a82faf81115f]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# huaweicloud_compute_instance.hello_ecs will be destroyed
- resource "huaweicloud_compute_instance" "hello_ecs" {
- access_ip_v4 = "192.168.0.58" -> null
- availability_zone = "ap-southeast-3c" -> null
- charging_mode = "postPaid" -> null
...
...
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
huaweicloud_compute_instance.hello_ecs: Destroying... [id=f61feb8c-fcb8-4f3a-a39e-a82faf81115f]
huaweicloud_compute_instance.hello_ecs: Still destroying... [id=f61feb8c-fcb8-4f3a-a39e-a82faf81115f, 10s elapsed]
huaweicloud_compute_instance.hello_ecs: Still destroying... [id=f61feb8c-fcb8-4f3a-a39e-a82faf81115f, 20s elapsed]
huaweicloud_compute_instance.hello_ecs: Still destroying... [id=f61feb8c-fcb8-4f3a-a39e-a82faf81115f, 30s elapsed]
huaweicloud_compute_instance.hello_ecs: Destruction complete after 54s
Destroy complete! Resources: 1 destroyed.
We have seen how we can create and destroy an ECS in HC using Terraform, an IaC tool. Although this is a simple tutorial, you can manage the entire environment as code. Of course there are best practices for this that are not considered in this article.
İletişime geçmek, yorum bırakmak veya hatalarımı düzetlmek istersen mail atabilirsin.