Você cria instâncias EC2 de forma manual?
Pare e comece a mergulhar nos assuntos de automação o mais rápido!!!
Infraestrutura como código não é o futuro, é o presente. O mundo Cloud contribuiu muito para a evolução das formas de implementação, trazendo grandes inovações e beneficiando muito o Business das empresas. Como resultado, os tomadores de decisões direcionam diariamente o time de recrutadores para procurar profissionais com essas habilidades. Algumas das características: habilidade de inovar, agilidade e aproveitar melhor o tempo no dia a dia de suas atividades nas empresas.
Nesse blog post, será demonstrado os passos para a criação de uma instância EC2 na AWS utilizando o Terraform.
Vamos colocar a mão na massa? #pracima
É importante acessar o post Criando VPC com uma subnet pública utilizando Terraform, para preparar o ambiente da sua conta na AWS da melhor forma antes de prosseguir.
Arquitetura
Criando um usuário IAM na AWS
1. Acesse o serviço de IAM na sua conta na AWS.
2. Em Access Management, clique em Users. Em seguida, clique em Add User.
3. Em User Name, adicione o nome de sua preferência e em Access Type, selecione Programmatic access. Clique em Next: Permissions.
4. Em Set Permissions, clique em Attach existing policies directly. Em Filter policies, pesquise por “ec2full” e selecione a política AmazonEC2FullAccess. Clique em Next: Tags.
5. Em Add Tags, clique em Next: Review.
6. Em Review, verique suas escolhas. Se estiver pendente alguma ponto, retorne e ajuste. Caso estiver tudo ok, clique em Create User para avançar.
7. Para concluir, clique em Download .csv. Copie a Access Key ID e cole-a em um bloco de notas com muito cuidado. Clique em Show, para exibir a Secret Access Key.
Obs.: Em outro momento, não será possível obter as informações coletadas acima, portanto, tenha cuidado ao executar essa etapa.
Copie a Secret Access Key e cole-a no seu bloco de notas. Clique em Close.
Preparando o ambiente
1. Faça o download do Terraform de acordo com o seu SO, clicando aqui.
2. Crie uma pasta no seu computador.
3. Mova o arquivo do Terraform que realizou o download para a pasta criada e extraia-o, obtendo o seguinte resultado:
4. Remova o arquivo .zip da pasta.
5. Utilizando o VS Code, crie os arquivos provider.tf e main.tf dentro da pasta onde se encontra o arquivo executável do Terraform.
Obs.: Caso não tiver o VS Code instalado em seu computador, clique aqui para fazer o download e realizar a instalação.
provider.tf – será destinado para adição das informações, como Region, Access Key ID e Secret Access Key.
main.tf – será destinado para adição das informações para criação da instância EC2 e do security group na AWS.
6. Prepare o arquivo provider.tf da seguinte forma:
provider "aws" {
region = "us-east-1"
access_key = "AKIA4UTEPSVVPQ7FNMYZ"
secret_key = "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"
}
region: Insira a sua região.
access_key: Insira a sua Access Key ID.
secret_key: Insira a sua Secret Access Key.
Antes de avançarmos para a preparação do arquivo main.tf, vamos realizar a criação da chave para acesso via ssh à instância EC2 que será criada.
7. Acesse o serviço do EC2 na AWS.
8. No canto esquerdo, em Network & Security, clique em Key Pairs.
9. Clique em Create key pair.
10. Em Name, insira o nome da sua chave. Ao chegar em File format, selecione pem. Feito isso, clique em Create key pair.
Obs.: Após concluir o download, mova a chave criada para a pasta que está utilizando para o armazenamento dos arquivos do Terraform.
11. Prepare o arquivo main.tf da seguinte forma:
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_instance" "tcb_blog_ec2" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
key_name = "tcb-blog" # Insira o nome da chave criada antes.
subnet_id = var.tcb_blog_subnet_public_id
vpc_security_group_ids = [aws_security_group.permitir_ssh_http.id]
associate_public_ip_address = true
tags = {
Name = "blogserver01"
# Insira o nome da instância de sua preferência.
}
}
variable "tcb_blog_vpc_id" {
default = "vpc-044a05c74d46127b6" # Orientações para copia da VPC ID abaixo.
}
variable "tcb_blog_subnet_public_id" {
default = "subnet-0f001d93c9e954103" # Orientações para copia da Subnet ID abaixo.
}
resource "aws_security_group" "permitir_ssh_http" {
name = "permitir_ssh"
description = "Permite SSH e HTTP na instancia EC2"
vpc_id = var.tcb_blog_vpc_id
ingress {
description = "SSH to EC2"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "HTTP to EC2"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "permitir_ssh_e_http"
}
}
Passos complementares:
Para copiar o VPC ID, acesse o serviço VPC. Clique em Your VPCs. Em seguida, na coluna VPC ID, copie a informação destacada e atualize a variável criada no arquivo main.tf.
Para copiar o Subnet ID, acesse o serviço VPC. Clique em Subnets. Em seguida, na coluna Subnet ID, copie a informação destacada e atualize a variável criada no arquivo main.tf.
Obs.: Durante a edição do arquivo main.tf, após, por exemplo, resource “aws_vpc”, na próximo conjunto de aspas (” “), você pode personalizar com as informaçoes de sua preferência. Em Tags, Name, personalize com o nome de sua escolha para o recurso. #pracima
Realizando a criação da instância EC2 utilizando o Terraform
Para execução dos comandos do Terraform, será utilizado o GitBash. Caso utilize o SO Windows e não tiver instalado em seu computador, clique aqui para realizar o download. Em seguida, realize a instalação.
1. Abra o Git Bash na pasta criada nos passos anteriores, clicando com o botão direito do mouse, em seguida, em Git Bash here.
2. Execute o comando ./terraform.exe init para iniciar o Terraform.
$ ./terraform.exe init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v3.23.0...
- Installed hashicorp/aws v3.23.0 (signed by HashiCorp)
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!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
3. Execute o comando ./terraform.exe plan.
$ ./terraform.exe plan
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.tcb_blog_ec2 will be created
+ resource "aws_instance" "tcb_blog_ec2" {
+ ami = "ami-011899242bb902164"
+ arn = (known after apply)
+ associate_public_ip_address = true
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = "tcb-blog"
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = "subnet-0f001d93c9e954103"
+ tags = {
+ "Name" = "blogserver01"
}
+ tenancy = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)
+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ throughput = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
+ enclave_options {
+ enabled = (known after apply)
}
+ ephemeral_block_device {
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name = (known after apply)
}
+ metadata_options {
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
}
+ network_interface {
+ delete_on_termination = (known after apply)
+ device_index = (known after apply)
+ network_interface_id = (known after apply)
}
+ root_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ throughput = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
}
# aws_security_group.permitir_ssh_http will be created
+ resource "aws_security_group" "permitir_ssh_http" {
+ arn = (known after apply)
+ description = "Permite SSH e HTTP na instancia EC2"
+ egress = [
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = ""
+ from_port = 0
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "-1"
+ security_groups = []
+ self = false
+ to_port = 0
},
]
+ id = (known after apply)
+ ingress = [
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = "HTTP to EC2"
+ from_port = 80
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_groups = []
+ self = false
+ to_port = 80
},
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = "SSH to EC2"
+ from_port = 22
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_groups = []
+ self = false
+ to_port = 22
},
]
+ name = "permitir_ssh"
+ owner_id = (known after apply)
+ revoke_rules_on_delete = false
+ tags = {
+ "Name" = "permitir_ssh_e_http"
}
+ vpc_id = "vpc-044a05c74d46127b6"
}
Plan: 2 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
4. Execute o comando ./terraform.exe apply.
$ ./terraform.exe apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.tcb_blog_ec2 will be created
+ resource "aws_instance" "tcb_blog_ec2" {
+ ami = "ami-011899242bb902164"
+ arn = (known after apply)
+ associate_public_ip_address = true
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = "tcb-blog"
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = "subnet-0f001d93c9e954103"
+ tags = {
+ "Name" = "blogserver01"
}
+ tenancy = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)
+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ throughput = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
+ enclave_options {
+ enabled = (known after apply)
}
+ ephemeral_block_device {
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name = (known after apply)
}
+ metadata_options {
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
}
+ network_interface {
+ delete_on_termination = (known after apply)
+ device_index = (known after apply)
+ network_interface_id = (known after apply)
}
+ root_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ throughput = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
}
# aws_security_group.permitir_ssh_http will be created
+ resource "aws_security_group" "permitir_ssh_http" {
+ arn = (known after apply)
+ description = "Permite SSH e HTTP na instancia EC2"
+ egress = [
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = ""
+ from_port = 0
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "-1"
+ security_groups = []
+ self = false
+ to_port = 0
},
]
+ id = (known after apply)
+ ingress = [
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = "HTTP to EC2"
+ from_port = 80
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_groups = []
+ self = false
+ to_port = 80
},
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = "SSH to EC2"
+ from_port = 22
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_groups = []
+ self = false
+ to_port = 22
},
]
+ name = "permitir_ssh"
+ owner_id = (known after apply)
+ revoke_rules_on_delete = false
+ tags = {
+ "Name" = "permitir_ssh_e_http"
}
+ vpc_id = "vpc-044a05c74d46127b6"
}
Plan: 2 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
5. Verifique se não existe nenhuma pendência no arquivo main.tf. Caso sim, retorne e ajuste o que for necessário. Caso não, digite yes para confirmar a execução das ações. Em seguide, aperte Enter.
Enter a value: yes
aws_security_group.permitir_ssh_https: Creating...
aws_security_group.permitir_ssh_https: Creation complete after 6s [id=sg-09f146782860f4c4b]
aws_instance.tcb_blog_ec2: Creating...
aws_instance.tcb_blog_ec2: Still creating... [10s elapsed]
aws_instance.tcb_blog_ec2: Still creating... [20s elapsed]
aws_instance.tcb_blog_ec2: Still creating... [30s elapsed]
aws_instance.tcb_blog_ec2: Creation complete after 39s [id=i-0151d5e3a8fafcd98]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Ao concluir essas etapas, você realizou a criação da instância EC2 e do security group com sucesso. Trabalho sensacional! #pracima
Para verificar a criação da instância na AWS Management Console, acesse o serviço EC2, em EC2 Dashboard, clique em Instances (running).
Agora, vamos iniciar a etapa de acesso à instância via ssh.
Selecione a instância que realizou a criação. Em detalhes, Public IPv4 Address, clique no ícone destacado para copiar o IP para a sua área de transferência.
Abra o Git Bash na pasta com os arquivos do Terraform e a chave, executando o comando ssh -i <nome-da-chave> nome-do-usuário@ip-publico-da-instância.
$ ssh -i tcb-blog.pem ubuntu@54.172.5.45
Após executar, digite Yes para avançar.
$ ssh -i tcb-blog.pem ubuntu@54.172.5.45
load pubkey "tcb-blog.pem": invalid format
The authenticity of host '54.172.5.45 (54.172.5.45)' can't be established.
ECDSA key fingerprint is SHA256:6TIpngTtKpj7fJ5pTT9HBHopgBhvWdDePGlsyoLdPq0.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Feito isso, você terá a comprovação do acesso bem sucedido à sua instância criada na AWS utilizando o Terraform.
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-1035-aws x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue Jan 12 12:06:12 UTC 2021
System load: 0.0 Processes: 100
Usage of /: 16.2% of 7.69GB Users logged in: 0
Memory usage: 20% IPv4 address for eth0: 10.0.1.94
Swap usage: 0%
1 update can be installed immediately.
0 of these updates are security updates.
To see these additional updates run: apt list --upgradable
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
ubuntu@ip-10-0-1-94:~$
Para deletar a instância EC2 e o security group que foram criados, execute o comando ./terraform.exe destroy.
$ ./terraform.exe destroy
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# aws_instance.tcb_blog_ec2 will be destroyed
- resource "aws_instance" "tcb_blog_ec2" {
- ami = "ami-011899242bb902164" -> null
- arn = "arn:aws:ec2:us-east-1:868867872106:instance/i-0151d5e3a8fafcd98" -> null
- associate_public_ip_address = true -> null
- availability_zone = "us-east-1d" -> null
- cpu_core_count = 1 -> null
- cpu_threads_per_core = 1 -> null
- disable_api_termination = false -> null
- ebs_optimized = false -> null
- get_password_data = false -> null
- hibernation = false -> null
- id = "i-0151d5e3a8fafcd98" -> null
- instance_state = "running" -> null
- instance_type = "t2.micro" -> null
- ipv6_address_count = 0 -> null
- ipv6_addresses = [] -> null
- key_name = "tcb-blog" -> null
- monitoring = false -> null
- primary_network_interface_id = "eni-0c04decdf541f1b88" -> null
- private_dns = "ip-10-0-1-94.ec2.internal" -> null
- private_ip = "10.0.1.94" -> null
- public_dns = "ec2-54-172-5-45.compute-1.amazonaws.com" -> null
- public_ip = "54.172.5.45" -> null
- secondary_private_ips = [] -> null
- security_groups = [] -> null
- source_dest_check = true -> null
- subnet_id = "subnet-0f001d93c9e954103" -> null
- tags = {
- "Name" = "blogserver01"
} -> null
- tenancy = "default" -> null
- volume_tags = {} -> null
- vpc_security_group_ids = [
- "sg-09f146782860f4c4b",
] -> null
- credit_specification {
- cpu_credits = "standard" -> null
}
- enclave_options {
- enabled = false -> null
}
- metadata_options {
- http_endpoint = "enabled" -> null
- http_put_response_hop_limit = 1 -> null
- http_tokens = "optional" -> null
}
- root_block_device {
- delete_on_termination = true -> null
- device_name = "/dev/sda1" -> null
- encrypted = false -> null
- iops = 100 -> null
- throughput = 0 -> null
- volume_id = "vol-073bae1afd210b83f" -> null
- volume_size = 8 -> null
- volume_type = "gp2" -> null
}
}
# aws_security_group.permitir_ssh_http will be destroyed
- resource "aws_security_group" "permitir_ssh_http" {
- arn = "arn:aws:ec2:us-east-1:868867872106:security-group/sg-09f146782860f4c4b" -> null
- description = "Permite SSH e HTTP na instancia EC2" -> null
- egress = [
- {
- cidr_blocks = [
- "0.0.0.0/0",
]
- description = ""
- from_port = 0
- ipv6_cidr_blocks = []
- prefix_list_ids = []
- protocol = "-1"
- security_groups = []
- self = false
- to_port = 0
},
] -> null
- id = "sg-09f146782860f4c4b" -> null
- ingress = [
- {
- cidr_blocks = [
- "0.0.0.0/0",
]
- description = "HTTP to EC2"
- from_port = 80
- ipv6_cidr_blocks = []
- prefix_list_ids = []
- protocol = "tcp"
- security_groups = []
- self = false
- to_port = 80
},
- {
- cidr_blocks = [
- "0.0.0.0/0",
]
- description = "SSH to EC2"
- from_port = 22
- ipv6_cidr_blocks = []
- prefix_list_ids = []
- protocol = "tcp"
- security_groups = []
- self = false
- to_port = 22
},
] -> null
- name = "permitir_ssh" -> null
- owner_id = "868867872106" -> null
- revoke_rules_on_delete = false -> null
- tags = {
- "Name" = "permitir_ssh_e_http"
} -> null
- vpc_id = "vpc-044a05c74d46127b6" -> null
}
Plan: 0 to add, 0 to change, 2 to destroy.
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:
Para confirmar que deseja realmente deletar os recursos, digite Yes e aperte Enter.
Enter a value: yes
aws_instance.tcb_blog_ec2: Destroying... [id=i-0151d5e3a8fafcd98]
aws_instance.tcb_blog_ec2: Still destroying... [id=i-0151d5e3a8fafcd98, 10s elapsed]
aws_instance.tcb_blog_ec2: Still destroying... [id=i-0151d5e3a8fafcd98, 20s elapsed]
aws_instance.tcb_blog_ec2: Still destroying... [id=i-0151d5e3a8fafcd98, 30s elapsed]
aws_instance.tcb_blog_ec2: Still destroying... [id=i-0151d5e3a8fafcd98, 40s elapsed]
aws_instance.tcb_blog_ec2: Destruction complete after 43s
aws_security_group.permitir_ssh_https: Destroying... [id=sg-09f146782860f4c4b]
aws_security_group.permitir_ssh_https: Destruction complete after 2s
Destroy complete! Resources: 2 destroyed.
Recursos deletados com sucesso! #pracima
Deseja aprofundar os seus conhecimentos nos provedores de Cloud?
Participe da MultiCloud Experience!!
Evento Totalmente Gratuito e com um conteúdo muito enriquecedor para a Sua Carreira.
Clique aqui para se inscrever e receber todas as informações.
Até mais!