Как развернуть ресурсы AWS с помощью Boto3, Terraform и CloudFormation
Давайте поговорим обо всех трех, прежде чем мы начнем:
Boto3 (AWS SDK для Python)
Вы используете AWS SDK для Python (Boto3) для создания, настройки и управления сервисами AWS, такими как Amazon Elastic Compute Cloud (Amazon EC2) и Amazon Simple Storage Service (Amazon S3). SDK предоставляет объектно-ориентированный API, а также низкоуровневый доступ к сервисам AWS.
Terraform
Terraform - это инфраструктура с открытым исходным кодом в виде инструмента кода, который обеспечивает последовательный рабочий процесс CLI для управления сотнями облачных сервисов, специфичных для поставщиков. Terraform кодирует облачные API в декларативные файлы конфигурации.
Советы:
- Обеспечивает бесперебойную работу инфраструктуры
- С легкостью обновляет инфраструктуру
- Без проблем разрушает инфраструктуру
- Он проверяет ошибки кода одним нажатием кнопки
- Он планирует инфраструктуры перед развертыванием.
- Он отслеживает записи из файла состояния
CloudFormation
AWS CloudFormation дает вам простой способ смоделировать набор связанных ресурсов AWS и сторонних поставщиков, быстро и согласованно предоставить их и управлять ими на протяжении всего их жизненного цикла, рассматривая инфраструктуру как код. Шаблон CloudFormation описывает желаемые ресурсы и их зависимости, поэтому вы можете запускать и настраивать их вместе как стек. Вы можете использовать шаблон для создания, обновления и удаления всего стека как единого целого так часто, как вам нужно, вместо того, чтобы управлять ресурсами по отдельности. Вы можете управлять стеками и выделять их для нескольких учетных записей AWS и регионов AWS.
Примечание. CloudFormation - это проприетарный инструмент IAC AWS, другими словами, собственный шаблон AWS, что означает, что его можно использовать только на платформе AWS. Так что это может не подойти вам, если AWS не является вашим поставщиком облака.
Terraform + CloudFormation
Наконец, с AWS мы можем использовать CloudFormation. Вместе с другими поставщиками облачных услуг мы можем воспользоваться другими ресурсами. В любом случае, terraform можно рассматривать как центр IaC для всех наших облачных проектов, мы можем
- беспрепятственное предоставление инфраструктуры
- легко обновлять инфраструктуру
- без проблем разрушить инфраструктуру
- проверить коды ошибок одним нажатием кнопки
- спланировать инфраструктуры перед развертыванием
- отслеживать записи из файла состояния
Выполнение всего вышеперечисленного с использованием Terraform и создание инфраструктуры вместе с собственным инструментом IaC от любых конкретных почти всех облачных провайдеров!
Напоминание:. Это должно быть частью 1 проекта, поскольку я углублюсь в AWS CDK с Terraform и попытаюсь подготовить VPC с помощью CDK с Terraform.
Вот варианты, которые я хотел бы затронуть в этом проекте.
Предпосылки
- Учетная запись AWS - с пользователем без полномочий root (с учетом безопасности)
- Ваш локальный компьютер Windows 10 с установленным Python3 или просто найдите и установите Python из Магазина Windows.
- Установите Visual Studio Code здесь.
- AWSCLI установил ссылку здесь.
- Установите Terraform здесь
Давайте начнем работать над ними по очереди.
Создание пользователя без полномочий root
В соответствии с передовой практикой AWS пользователю root не рекомендуется выполнять повседневные задачи, даже административные. Пользователь root, скорее, используется для создания вашего первого пользователя, групп и ролей IAM. Затем вам нужно надежно заблокировать учетные данные пользователя root и использовать их для выполнения лишь нескольких задач управления учетными записями и службами.
Примечание. Если вы хотите узнать больше о том, почему мы не должны использовать пользователя root для операций, и подробнее об учетной записи AWS, прочтите здесь.
- Во-вторых, создайте пользователя под IAM.
- Перед созданием выберите программный доступ для этого пользователя
- когда появляется сообщение Успешно загрузите CSV-файл для учетных данных для дальнейшего использования. (Идентификатор ключа доступа и Секретный ключ доступа)
- Проверьте установку, открыв VS Code и удерживая ctrl и ~, чтобы открыть внутри PowerShell.
Затем используйте следующие команды, чтобы проверить установку
$ aws --version aws-cli/2.2.1 Python/3.8.8 Windows/10 exe/AMD64 prompt/off
Чтобы использовать AWS cli, нам необходимо настроить его с помощью ключа доступа AWS, секретного ключа доступа, региона по умолчанию и выходной формат:
$ aws configure AWS Access Key ID [****************46P7]: AWS Secret Access Key [****************SoXF]: Default region name [us-east-1]: Default output format [json]:
Пришло время установить Terraform (альтернативные методы ссылка).
Легкий путь
Уф, это было много работы! Было бы ужасно делать это каждый раз, когда вам приходилось устанавливать новое программное обеспечение на ваше устройство. Вместо этого воспользуемся менеджером пакетов. Есть несколько менеджеров пакетов, которые вы можете использовать для установки Terraform в Windows. Для Windows мне больше всего нравится Chocolatey. Он упрощает установку, удаление и обновление программного обеспечения, как однострочную команду, и Terraform не является исключением.
Чтобы установить Terraform с Chocolatey, выполните следующие действия:
- Откройте командную строку CMD / PowerShell от имени администратора и установите Chocolatey с помощью команды со их страницы установки.
- Как только это будет завершено, запустите
choco install terraform
. Если хотите, вы также можете поставить-y
в конце, чтобы автоматически согласиться на его установку на свое устройство.
После выполнения этой команды вы получите что-то вроде этого:
Chocolatey v0.10.13 2 validations performed. 1 success(es), 1 warning(s), and 0 error(s).
Installing the following packages: terraform By installing you accept licenses for the packages. Progress: Downloading terraform 0.12.6... 100%
terraform v0.12.6 [Approved] Downloading terraform 64 bit from 'https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_windows Download of terraform_0.12.6_windows_amd64.zip (15.32 MB) completed. --SNIP--
Другой способ
Попробуйте этот метод Подсистема Windows для Linux. Это позволяет запускать команды Linux в Windows и, если вы хотите создать отдельную тестовую среду.
- Установите WSL через Microsoft Store, выполните поиск в Ubuntu и установите последнюю версию.
2. В оболочке WSL запустите apt-get install unzip
. Это понадобится вам для извлечения двоичных файлов Terraform позже.
3. Загрузите Terraform, запустив wget https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_linux_amd64.zip
. Не забудьте заменить версию и архитектуру на те, которые лучше всего подходят вашему устройству. Вы можете найти полный список релизов Terraform здесь.
4. Запустите unzip terraform_0.12.6_linux_amd64.zip terraform
, чтобы распаковать содержимое zip-архива в папку с именем terraform.
5. После того, как ZIP-файл будет распакован, вам нужно переместить его в другое место, доступное по системному пути. К счастью, в Linux есть папка, в которую пользователи могут добавлять двоичные файлы по умолчанию. Переместите туда двоичный файл Terraform, запустив mv terraform /usr/local/bin/
. Папка / usr / local / bin уже задана в вашем системном пути.
6. Убедитесь, что установка прошла успешно, запустив
$ terraform version Terraform v0.14.3 + provider registry.terraform.io/hashicorp/aws v3.21.0. Note:If you are using WSL also use this command to generate private key $ ssh-keygen $ cat .ssh/id_rsa <-- to make sure your key exist in that path -----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gt . . . -----END OPENSSH PRIVATE KEY-----
Установка Python3 и Boto3
Хотя в вашей системе может быть предустановлен Python2. Однако для этого проекта рекомендуется установить последнюю версию Python3.
Для более подробной установки посетите здесь
Убедитесь, что вы действительно проверяете установку после установки
$pip install boto3 python3 --version Python 3.9.4 pip3 --version pip 20.2.3 from C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1264.0_x64__qbz5n2kfra8p0\lib\site-packages\pip (python 3.9) pip3 show boto3 Name: boto3 Version: 1.17.62 Summary: The AWS SDK for Python Home-page: https://github.com/boto/boto3 Author: Amazon Web Services Author-email: None License: Apache License 2.0 Location: c:\users\msun_\appdata\local\packages\pythonsoftwarefoundation.python.3.9_qbz5n2kfra8p0\localcache\local-packages\python39\site-packages Requires: s3transfer, jmespath, botocore Required-by:
Boto3 для предоставления нашего VPC
Пришло время создать файл Python с помощью Python и выполнить наш первый скрипт Boto3 для развертывания ресурсов в AWS.
Сначала создайте папку и переключитесь на нее
$ mkdir Boto3forVPC && cd Boto3forVPC/
vim vpc.py
Запустите следующий сценарий, чтобы развернуть нужные ресурсы на AWS.
$ python3 vpc.py ec2.Vpc(id='vpc-005382a4c773378a7') [ec2.Tag(resource_id='vpc-005382a4c773378a7', key='Name', value='boto3_vpc')] ec2.InternetGateway(id='igw-0e1ca1c17c56dea96') ec2.RouteTable(id='rtb-0b0b2afb80ba70677') ec2.Route(route_table_id='rtb-0b0b2afb80ba70677', destination_cidr_block='0.0.0.0/0') ec2.Subnet(id='subnet-0b3fcb0b24adadd8b') ec2.SecurityGroup(id='sg-03090bf8dcd216d50') [ec2.Instance(id='i-0db6a00626adcd7d7')]
Через несколько минут перекрестная проверка в консоли AWS
Bastian Host- Ec2, VPC с именем boto3_vpc
, подключенный к нему InternetGateway и связанная с ним подсеть, также создаются таблица маршрутов (с общедоступным маршрутом).
Группа безопасности и разрешите входящее правило SSH через VPC через ваш собственный IP-адрес (Примечания: для вашей собственной безопасности вы должны никогда не раскрывать свой IP-адрес )
Создайте файл для локального хранения ключа и вызовите функцию boto3 ec2 для создания пары ключей с именем ec2-keypair
, затем запишите ключ и сохраните его в файле ec2-keypair.pem
$ ls ec2-keypair.pem vpc.py Its time to destroy the resources we have just created using vim vpc_destroy.py & copy the code below.
используйте команду ниже, чтобы уничтожить ресурсы, которые мы создали ранее, в зависимости от вашего vpc_id
$ python3 vpc_destroy.py --vpc_id vpc-005382a4c773378a7 --region us-east-1 --services ec2 type: <class 'str'> [vpc_destroy.py:243 - <module>() ] calling destroy_services with ec2 [credentials.py:1217 - load() ] Found credentials in shared credentials file: ~/.aws/credentials [vpc_destroy.py:58 - destroy_ec2() ] instance deletion list: ['i-0db6a00626adcd7d7'] [vpc_destroy.py:60 - destroy_ec2() ] Waiting for instances to terminate [vpc_destroy.py:246 - <module>() ] calling delete_vpc with vpc-005382a4c773378a7 [vpc_destroy.py:162 - delete_vpc() ] no ENIs remaining destroyed vpc-005382a4c773378a7 in us-east-1
Примечания. Как показано выше, вы должны предоставить vpc_id, регион и услуги. Если вы хотите узнать больше о том, как эта очистка VPC с помощью Boto3, пожалуйста, обратитесь к этому сообщению
Примечания. Убедитесь, что каждый раз, когда вы применяете vpc.py для создания нового VPC, вам необходимо указывать новое имя пары ключей . В противном случае создание не может быть выполнено должным образом. Для этого вы можете использовать AWS или AWS CLI.
Для AWS CLI примените код ниже
$ aws ec2 delete-key-pair --key-name <name of your key pair>
Здесь я также хотел бы предоставить Terraforming VPC и Terraforming VPC с использованием AWS CloudFormation.
Причина в том, чтобы предоставить различные способы предоставления VPC для удовлетворения различных потребностей и требований. Также давайте разберемся, какой вариант более действенный и действенный.
Начнем с Terraforming VPC
Во-первых, нам нужно создать с помощью vi vpc.tf
файл в той же папке или создать отдельный, используя следующий код:
Во-вторых, вам также потребуется создать vi variables.tf
файл, чтобы предоставить дополнительные настройки.
В-третьих, вам также нужно будет создать vi terraform.tfvars
файл, чтобы указать необходимые переменные.
Наконец, вам также необходимо создать файл vi outputs.tf
для вывода на консоль после создания.
Теперь пришло время терра из нашего vpc
$ terraform init
Это инициализирует и установит необходимые плагины для запуска terraform.
Обязательно проверяет синтаксис всех файлов terraform в вашем каталоге.
$ terraform validate Success! The configuration is valid.
Затем мы спланируем нашу инфраструктуру terraform, чтобы убедиться, какие ресурсы будут развернуты с использованием этого кода.
$ terraform plan 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: # aws_instance.bastion_host will be created + resource “aws_instance” “bastion_host” { + ami = “ami-0742b4e673072066f” + 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_initiated_shutdown_behavior = (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 = “ec2-keypair” + 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 = (known after apply) + tags_all = (known after apply) + tenancy = (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) + tags = (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) + tags = (known after apply) + throughput = (known after apply) + volume_id = (known after apply) + volume_size = (known after apply) + volume_type = (known after apply) } } # aws_internet_gateway.igw will be created + resource “aws_internet_gateway” “igw” { + arn = (known after apply) + id = (known after apply) + owner_id = (known after apply) + tags = { + “Environment” = “Development” + “Name” = “boto3_vpc” } + tags_all = { + “Environment” = “Development” + “Name” = “boto3_vpc” } + vpc_id = (known after apply) } # aws_key_pair.bastion_host_key will be created + resource “aws_key_pair” “bastion_host_key” { + arn = (known after apply) + fingerprint = (known after apply) + id = (known after apply) + key_name = “ec2-keypair” + key_pair_id = (known after apply) + public_key = (known after apply) + tags_all = (known after apply) } # aws_route_table.public_route_table will be created + resource “aws_route_table” “public_route_table” { + arn = (known after apply) + id = (known after apply) + owner_id = (known after apply) + propagating_vgws = (known after apply) + route = [ + { + carrier_gateway_id = “” + cidr_block = “0.0.0.0/0” + destination_prefix_list_id = “” + egress_only_gateway_id = “” + gateway_id = (known after apply) + instance_id = “” + ipv6_cidr_block = “” + local_gateway_id = “” + nat_gateway_id = “” + network_interface_id = “” + transit_gateway_id = “” + vpc_endpoint_id = “” + vpc_peering_connection_id = “” }, ] + tags = { + “Environment” = “var.environment_tag” } + tags_all = { + “Environment” = “var.environment_tag” } + vpc_id = (known after apply) } # aws_route_table_association.public_rt_association[0] will be created + resource “aws_route_table_association” “public_rt_association” { + id = (known after apply) + route_table_id = (known after apply) + subnet_id = (known after apply) } # aws_security_group.bastion_host will be created + resource “aws_security_group” “bastion_host” { + arn = (known after apply) + description = “Managed by Terraform” + egress = [ + { + cidr_blocks = [] + description = “” + from_port = 22 + ipv6_cidr_blocks = [] + prefix_list_ids = [] + protocol = “var.protocol” + security_groups = [] + self = false + to_port = 22 }, ] + id = (known after apply) + ingress = [ + { + cidr_blocks = [ + “72.137.76.221/32”, ] + description = “” + from_port = 22 + ipv6_cidr_blocks = [] + prefix_list_ids = [] + protocol = “tcp” + security_groups = [] + self = false + to_port = 22 }, ] + name = (known after apply) + name_prefix = (known after apply) + owner_id = (known after apply) + revoke_rules_on_delete = false + tags_all = (known after apply) + vpc_id = (known after apply) } # aws_subnet.public_subnet[0] will be created + resource “aws_subnet” “public_subnet” { + arn = (known after apply) + assign_ipv6_address_on_creation = false + availability_zone = “us-east-1a” + availability_zone_id = (known after apply) + cidr_block = “172.16.1.0/24” + id = (known after apply) + ipv6_cidr_block_association_id = (known after apply) + map_public_ip_on_launch = false + owner_id = (known after apply) + tags = { + “Environment” = “var.environment_tag” } + tags_all = { + “Environment” = “var.environment_tag” } + vpc_id = (known after apply) } # aws_vpc.main will be created + resource “aws_vpc” “main” { + arn = (known after apply) + assign_generated_ipv6_cidr_block = false + cidr_block = “172.16.0.0/16” + default_network_acl_id = (known after apply) + default_route_table_id = (known after apply) + default_security_group_id = (known after apply) + dhcp_options_id = (known after apply) + enable_classiclink = (known after apply) + enable_classiclink_dns_support = (known after apply) + enable_dns_hostnames = true + enable_dns_support = true + id = (known after apply) + instance_tenancy = “default” + ipv6_association_id = (known after apply) + ipv6_cidr_block = (known after apply) + main_route_table_id = (known after apply) + owner_id = (known after apply) + tags = { + “Environment” = “Development” + “Name” = “boto3_vpc” } + tags_all = { + “Environment” = “Development” + “Name” = “boto3_vpc” } } # tls_private_key.public_key will be created + resource “tls_private_key” “public_key” { + algorithm = “RSA” + ecdsa_curve = “P224” + id = (known after apply) + private_key_pem = (sensitive value) + public_key_fingerprint_md5 = (known after apply) + public_key_openssh = (known after apply) + public_key_pem = (known after apply) + rsa_bits = 4096 } Plan: 9 to add, 0 to change, 0 to destroy. Changes to Outputs: + cidr_block = “172.16.0.0/16” + gateway_id = (known after apply) + key_name = “ec2-keypair” + route_table_id = (known after apply) + subnet_id = (known after apply) + tags = { + Environment = “Development” } + vpc_security_group_ids = [ + (known after apply), ]
Когда вы будете готовы, давайте подготовим инфраструктуру с помощью приведенной ниже команды.
$ terraform apply --auto-approve
Затем давайте дважды проверим наши ресурсы, которые были созданы в консоли AWS.
Создан VPC с именем boto3_vpc
Пора прояснить инфраструктуру, созданную с помощью Terraform
$ terraform destroy . . Enter a value: yes
Теперь мы подготовим VPC с помощью CloudFormation.
Вот официальный шаблон AWS для VPC в качестве справки.
Примечание. Сначала создайте пару ключей, поскольку CloudFormation не может ее создать. Он понадобится вам для доступа к экземплярам EC2.
$ aws ec2 create-key-pair --key-name ec2-keypair { "KeyFingerprint": "ab:b2:0c:81:9e:1e:07:d5:15:bb:a9:b1:41:b0:5d:e2:af:b5:38:23", "KeyMaterial": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAmB0Ani+OiUMiqrlgrMc50oGo9KjsVj3MNnxbmFSyMNxuLrSp\nXLiRsSHcJK7cH6IxOXuSOE0fczJmhFQZnFLTpkOqx7ELpRBDSTFdnYfqXf5oxrjs\nf5OZRXuZqjncgxxd7f/KLEBrn5xBR03aiUkc/w5lYTR0JMjWIlIsPxIxRwF9NZ/o\n2AA6K/gX2lqteFV9mUizq0Z301Ryd/RNyeABEHhJ4fuJTb1MlBc1wEGZj2pM0aVr\n67nRV0RZhTP8uj9MKg1OAvb5yaZuvBiccoiUOshoYjgrPJsnuywH6kNLHNahbrjj\n9XirKQdQ4TogqJnaW/Vd3d9J8IwNA8LcYs88owIDAQABAoIBACxeaUu6u2y2NGpv\n4A8FnYwVXd7fVvBg3iwWYfEw4zj1Uv40nCH7hCOSqM/aYUKo4IrPzHq3pDDJxrVa\ngo3iavHYUvwkXC0tbTLwP0ov1uDL0GwGjJU5zD9EKjJI5lUn9Q3yylnWAI5x2Wif\nANuCg/6xiEiuMCJ6olsodNeAyvbWuIhR+uyFfVE4vEdoqK4l8UYWQNACOnppKgaJ\nrbcKnfi+dj0AejQInpk8Ov6UUdTEINQZ4JG/d/2DFYWktGBmHVhEm9h4WIr9HRV6\nQT6LklIZYF6e9W379Z5ZXX1aGUdSeHPAefFkNwPrNCMjLCRur+C16dUAzO6jBRpG\nYZPcauECgYEA3F/9ioQ0x4//wAQkzZb81tFqRRjKTSggx2+lTKkb/UhXtCN67XJD\nMzJoGOIVPVbHdcmpP0v0cG7g71e0gyRZ7zN0m28n6L415UXOx2/PL3qZoRb3TcAq\njm4uaTxp0pCXLRmfryqiCcZzu6cmxG6YujmtKNdBrGjuvIqNdZCutu8CgYEAsLQR\nNcvxBxAGFwSWZv5ztf5agmpgK8j9gVxcO3Qc0QIU67o78hgvVkNhYgopWt4UmKzi\nPRMMVRwX82iNpLFXwqgKQnIcueYiYXdC8F9+FSByq1TnkTFtLQJwJlRln0/TreNO\n6XN+gZBmldacExyqPAz93+vZo4lvu1LcbXybNY0CgYAkPf0afKeZcksjLwtGbGBk\ni8goWO1cRw8s/WV3+A/MVctmqrcaucHnd5C7FuNbVRw0eNfGux0WKIYBlrDvKFlK\nB3JT5bHwiueeLx7UmcS/EDCX14kQVlwpVGF5mR/mKzVRi3dBfYdsiCCcad7sSyv+\n5GFf6Ba63f71LuwYu5SgLQKBgQCTxzQxcorz5iHBtFN4dUseJEdblE0zsRbZzf1Q\nt421+nC2p/ykPjewhA94Z5koZlyBRuy6OSjyMNmS9pim6K3FnLVf1oFRszaDnrL7\nxlDyqD1eLlavpc9xef2DAMgwURlt7pE7Shy9jJ9OprnGfg2cxRy43U0ZqMIpvmWc\npz5CrQKBgCttNZrapWuh8Y6QXlMDp5sCovUAj9Fw5J11j0yZyf+i704hnEuv+/5H\nvzFuvTwaRlSIoz1Frnvhb9NF+9NYqrno2T3GOATRgThgHKN9soqJism5tG/jLGDS\n2x9P99HC94Ybd13IKDXrLK/gCVh97Zlel21CY2+Pu6K/6L3kjogH\n-----END RSA PRIVATE KEY-----", "KeyName": "ec2-keypair", "KeyPairId": "key-023bd02d2f97b4a31" }
После создания пары ключей самое время создать стек с помощью AWS-CLI с CloudFormation и кодом ниже:
Используя следующий код, вы можете развернуть аналогичные ресурсы в CloudFormation.
$ aws cloudformation create-stack — stack-name cfvpc — template-body file://vpc.yaml StackId: arn:aws:cloudformation:us-east-1:050411548990:stack/cfvpc/56c90c50-ab72–11eb-b620–0adbfd4180bb
Затем мы перепроверим наши ресурсы в консоли AWS. ›› CloudFormation на вкладке «Ресурсы»:
Вы можете проверить все ресурсы здесь и щелкнуть ресурсы, чтобы перейти в их прямое местоположение, где они были созданы, преимущество CloudFormation, где вы можете проверять, редактировать и уничтожать ресурсы в AWS.
Примечания. Используя CloudFormation, мы также сможем распечатывать выходные данные для справки в будущем.
Параметры
Примечания. Параметры позволяют нам записывать параметры, которые мы вводим изначально.
Шаблон
Примечание. В этом разделе мы можем сохранить исходный файл шаблона CloudFormation в качестве резервной копии.
Пришло время очистить и удалить инфраструктуру.
aws cloudformation delete-stack --stack-name cfvpc
Теперь все убрано.
Воспользуйтесь преимуществами Terraform и CloudFormation, чтобы выполнить Terraforming CloudFormation для предоставления VPC
Для реализации этого проекта нам нужно будет создать новый каталог и перейти в него.
$ mkdir tf_cf_vpc && cd tf_cf_vpc/
Для CloudFormation мы по-прежнему будем использовать наш vpc.yaml
файл, созданный ранее.
Нам также нужно создать наш tf_cf_vpc.tf
file, используя код ниже
Наконец, мы готовы терраформировать нашу инфраструктуру, используя оба инструмента IaC.
$ terraform init
Затем проверьте наш код:
$ terraform validate Success! The configuration is valid.
После этого давайте спланируем нашу инфраструктуру и убедимся в желаемых ресурсах:
$ terraform plan 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: # aws_cloudformation_stack.tf_cf_vpc will be created + resource “aws_cloudformation_stack” “tf_cf_vpc” { + id = (known after apply) + name = “TfCfVpc” + outputs = (known after apply) + parameters = { + “InstanceType” = “t3.nano” + “KeyName” = “tf_cf_keypair” } + policy_body = (known after apply) + tags_all = (known after apply) + template_body = <<-EOT Description: This CloudFormation YAML file will provision a VPC Parameters: KeyName: Description: Name of an existing EC2 KeyPair to enable SSH access to the instance Type: AWS::EC2::KeyPair::KeyName Default: ec2-keypair InstanceType: Description: EC2 instance type Type: String Default: t2.micro EnvironmentName: Description: An environment name that is prefixed to resource names Type: String Default: Development VpcCIDR: Description: Please enter the IP range (CIDR notation) for this VPC Type: String Default: “172.16.0.0/16” PublicSubnet1CIDR: Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone Type: String Default: “172.16.1.0/24” Mappings: AWSRegionToAMI: us-east-1: AMIID: ami-0742b4e673072066f Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: Ref: VpcCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: — Key: Name Value: Ref: EnvironmentName InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: — Key: Name Value: Ref: EnvironmentName InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: Ref: InternetGateway VpcId: Ref: VPC PublicSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC AvailabilityZone: !Select [ 0, !GetAZs ‘’ ] CidrBlock: Ref: PublicSubnet1CIDR MapPublicIpOnLaunch: true Tags: — Key: Name Value: !Sub ${EnvironmentName} Public Subnet (AZ1) PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: Ref: VPC Tags: — Key: Name Value: !Sub ${EnvironmentName} Public Routes DefaultPublicRoute: Type: AWS::EC2::Route DependsOn: InternetGatewayAttachment Properties: RouteTableId: Ref: PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: Ref: InternetGateway PublicSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: Ref: PublicRouteTable SubnetId: Ref: PublicSubnet1 VPCEC2SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: only allow SSH traffic GroupName: SSH-ONLY SecurityGroupIngress: — CidrIp: 72.137.76.221/32 FromPort: 22 IpProtocol: tcp ToPort: 22 Tags: - Key: Name Value: CloudFormationSecurityGroup VpcId: Ref: VPC VPCEC2: Type: AWS::EC2::Instance Properties: ImageId: !FindInMap — AWSRegionToAMI — !Ref AWS::Region — AMIID InstanceType: !Ref InstanceType SecurityGroupIds: — !GetAtt “VPCEC2SecurityGroup.GroupId” SubnetId: !Ref PublicSubnet1 KeyName: Ref: KeyName Outputs: VPC: Description: A reference to the created VPC Value: Ref: VPC PublicSubnet1: Description: A reference to the public subnet in the 1st Availability Zone Value: Ref: PublicSubnet1 VPCEC2SecurityGroup: Description: Security group with no ingress rule Value: Ref: VPCEC2SecurityGroup InternetGateway: Description: InternetGateway Information Value: Ref: InternetGateway PublicRouteTable: Description: Public Route Table Information Value: Ref: PublicRouteTable VPCEC2: Description: EC2 Information Value: Ref: VPCEC2 EOT } # aws_key_pair.bastion_host_key will be created + resource “aws_key_pair” “bastion_host_key” { + arn = (known after apply) + fingerprint = (known after apply) + id = (known after apply) + key_name = “tf_cf_keypair” + key_pair_id = (known after apply) + public_key = (known after apply) + tags_all = (known after apply) } # tls_private_key.public_key will be created + resource “tls_private_key” “public_key” { + algorithm = “RSA” + ecdsa_curve = “P224” + id = (known after apply) + private_key_pem = (sensitive value) + public_key_fingerprint_md5 = (known after apply) + public_key_openssh = (known after apply) + public_key_pem = (known after apply) + rsa_bits = 4096 } Plan: 3 to add, 0 to change, 0 to destroy. ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Note: You didn’t use the -out option to save this plan, so Terraform can’t guarantee to take exactly these actions if you run “terraform apply” now. Then run the following to deploy resources in AWS $ terraform apply --auto-approve
Затем мы проверим и дважды проверим ресурсы, созданные в консоли AWS.
Создан IGW, который прикреплен к Development
InternetGateway
Подсеть и свяжите ее с таблицей маршрутов
Подсеть с таблицей маршрутизации
Таблица маршрутов с общедоступным маршрутом
Таблица маршрутов с общедоступным маршрутом
Группа безопасности и разрешите входящее правило SSH через VPC через ваш собственный IP-адрес (Примечания: для вашей собственной безопасности вы должны никогда не раскрывать свой IP-адрес )
SSH с вашим собственным IP-адресом:
EC2 создан!
Примечание. Здесь мы обновим одно значение InstanceType в нашем .tf-файле и проверим возможности терраформирования. Наряду с CloudFormation мы можем воспользоваться преимуществами гибкости Terraform и встроенного и простого выделения ресурсов AWS от CloudFormation.
Здесь мы сделаем обновление файла tf_cf_vpc.tf
и изменим InstanceType from t2.micro >> to t3.large
Давайте спланируем это еще раз, чтобы увидеть разницу:
$ terraform plan 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: # aws_cloudformation_stack.tf_cf_vpc will be created + resource “aws_cloudformation_stack” “tf_cf_vpc” { + id = (known after apply) + name = “TfCfVpc” + outputs = (known after apply) + parameters = { + “InstanceType” = “t3.large” + “KeyName” = “tf_cf_keypair” } + policy_body = (known after apply) + tags_all = (known after apply) + template_body = <<-EOT Description: This CloudFormation YAML file will provision a VPC Parameters: KeyName: Description: Name of an existing EC2 KeyPair to enable SSH access to the instance Type: AWS::EC2::KeyPair::KeyName Default: ec2-keypair InstanceType: Description: EC2 instance type Type: String Default: t2.micro EnvironmentName: Description: An environment name that is prefixed to resource names Type: String Default: Development VpcCIDR: Description: Please enter the IP range (CIDR notation) for this VPC Type: String Default: “172.16.0.0/16” PublicSubnet1CIDR: Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone Type: String Default: “172.16.1.0/24” Mappings: AWSRegionToAMI: us-east-1: AMIID: ami-0742b4e673072066f Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: Ref: VpcCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: — Key: Name Value: Ref: EnvironmentName InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: — Key: Name Value: Ref: EnvironmentName InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: Ref: InternetGateway VpcId: Ref: VPC PublicSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC AvailabilityZone: !Select [ 0, !GetAZs ‘’ ] CidrBlock: Ref: PublicSubnet1CIDR MapPublicIpOnLaunch: true Tags: — Key: Name Value: !Sub ${EnvironmentName} Public Subnet (AZ1) PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: Ref: VPC Tags: — Key: Name Value: !Sub ${EnvironmentName} Public Routes DefaultPublicRoute: Type: AWS::EC2::Route DependsOn: InternetGatewayAttachment Properties: RouteTableId: Ref: PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: Ref: InternetGateway PublicSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: Ref: PublicRouteTable SubnetId: Ref: PublicSubnet1 VPCEC2SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: only allow SSH traffic GroupName: SSH-ONLY SecurityGroupIngress: — CidrIp: 72.137.76.221/32 FromPort: 22 IpProtocol: tcp ToPort: 22 Tags: - Key: Name Value: CloudFormationSecurityGroup VpcId: Ref: VPC VPCEC2: Type: AWS::EC2::Instance Properties: ImageId: !FindInMap — AWSRegionToAMI — !Ref AWS::Region — AMIID InstanceType: !Ref InstanceType SecurityGroupIds: — !GetAtt “VPCEC2SecurityGroup.GroupId” SubnetId: !Ref PublicSubnet1 KeyName: Ref: KeyName Outputs: VPC: Description: A reference to the created VPC Value: Ref: VPC PublicSubnet1: Description: A reference to the public subnet in the 1st Availability Zone Value: Ref: PublicSubnet1 VPCEC2SecurityGroup: Description: Security group with no ingress rule Value: Ref: VPCEC2SecurityGroup InternetGateway: Description: InternetGateway Information Value: Ref: InternetGateway PublicRouteTable: Description: Public Route Table Information Value: Ref: PublicRouteTable VPCEC2: Description: EC2 Information Value: Ref: VPCEC2 EOT } # aws_key_pair.bastion_host_key will be created + resource “aws_key_pair” “bastion_host_key” { + arn = (known after apply) + fingerprint = (known after apply) + id = (known after apply) + key_name = “tf_cf_keypair” + key_pair_id = (known after apply) + public_key = (known after apply) + tags_all = (known after apply) } # tls_private_key.public_key will be created + resource “tls_private_key” “public_key” { + algorithm = “RSA” + ecdsa_curve = “P224” + id = (known after apply) + private_key_pem = (sensitive value) + public_key_fingerprint_md5 = (known after apply) + public_key_openssh = (known after apply) + public_key_pem = (known after apply) + rsa_bits = 4096 } Plan: 3 to add, 0 to change, 0 to destroy. ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Note: You didn’t use the -out option to save this plan, so Terraform can’t guarantee to take exactly these actions if you run “terraform apply” now.
Пришло время повторно подать заявку на обновление изменений instance_type, что занимает меньше времени:
$ terraform apply . . . Enter a value: yesaws_cloudformation_stack.tf_cf_vpc: Modifying... [id=arn:aws:cloudformation:us-east-1:464392538707:stack/TfCfVpc/b8b5f360-a4b5-11eb-b4b0-12d101416601] aws_cloudformation_stack.tf_cf_vpc: Still modifying... [id=arn:aws:cloudformation:us-east-1:464392...c/b8b5f360-a4b5-11eb-b4b0-12d101416601, 10s elapsed] aws_cloudformation_stack.tf_cf_vpc: Still modifying... [id=arn:aws:cloudformation:us-east-1:464392...c/b8b5f360-a4b5-11eb-b4b0-12d101416601, 20s elapsed] aws_cloudformation_stack.tf_cf_vpc: Still modifying... [id=arn:aws:cloudformation:us-east-1:464392...c/b8b5f360-a4b5-11eb-b4b0-12d101416601, 30s elapsed] aws_cloudformation_stack.tf_cf_vpc: Still modifying... [id=arn:aws:cloudformation:us-east-1:464392...c/b8b5f360-a4b5-11eb-b4b0-12d101416601, 40s elapsed] aws_cloudformation_stack.tf_cf_vpc: Still modifying... [id=arn:aws:cloudformation:us-east-1:464392...c/b8b5f360-a4b5-11eb-b4b0-12d101416601, 50s elapsed] aws_cloudformation_stack.tf_cf_vpc: Still modifying... [id=arn:aws:cloudformation:us-east-1:464392...c/b8b5f360-a4b5-11eb-b4b0-12d101416601, 1m0s elapsed] aws_cloudformation_stack.tf_cf_vpc: Still modifying... [id=arn:aws:cloudformation:us-east-1:464392...c/b8b5f360-a4b5-11eb-b4b0-12d101416601, 1m10s elapsed] aws_cloudformation_stack.tf_cf_vpc: Still modifying... [id=arn:aws:cloudformation:us-east-1:464392...c/b8b5f360-a4b5-11eb-b4b0-12d101416601, 1m20s elapsed] aws_cloudformation_stack.tf_cf_vpc: Still modifying... [id=arn:aws:cloudformation:us-east-1:464392...c/b8b5f360-a4b5-11eb-b4b0-12d101416601, 1m30s elapsed] aws_cloudformation_stack.tf_cf_vpc: Modifications complete after 1m39s [id=arn:aws:cloudformation:us-east-1:464392538707:stack/TfCfVpc/b8b5f360-a4b5-11eb-b4b0-12d101416601]Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
Давайте дважды проверим в консоли AWS в экземплярах EC2:
А теперь давайте разрушим всю инфраструктуру в последний раз:
$ terraform destroy — auto-approve
Резюме
Давайте подведем итоги нашего проекта и того, чего мы достигли.
Архитектура проекта
Как видно из архитектуры проекта, мы рассмотрим 4 различных способа предоставления VPC с помощью инструментов Infra-as-code.
- Boto3
- CloudFormation (собственный AWS)
- Terraform (родной для облака)
- Terraform + CloudFormation
Прежде всего, используя Boto3, может потребоваться 2 разных файла для создания vpc в первую очередь и его уничтожения в конце дня. С учетом сказанного, это может быть проблемой с точки зрения менеджмента.
Во-вторых, мы создали инфраструктуру VPC с помощью CloudFormation. Поскольку он является родным для AWS, он отлично работал. Однако, что касается обновлений, нам может потребоваться поработать с одним и тем же файлом для параметров, как, скажем,. Но этим все еще можно было хорошо управлять.
В-третьих, Terraform как инструмент IaC действительно сиял своей гибкостью. От создания инфраструктуры до обновления до разрушения в конце дня - каждое движение было безупречным. Однако нам нужно потратить время на создание инфраструктуры, используя Terraform как совершенно новый язык. С учетом сказанного, это может занять много времени.
Наконец, мой предпочтительный способ: Terraform + CloudFormation для AWS. Используя преимущества всех аспектов Terraform, мы улучшаем нашу инфраструктуру AWS с помощью CloudFormation. Шаблоны были легко доступны на официальном веб-сайте AWS, а также во многих блогах и веб-сайтах, посвященных облачным технологиям. Мы можем просто применить файл CloudFormation .yaml
с Terraform.
Что еще более важно, гибкость Terraform остается в силе. Например, в проекте мы обновляем наш InstanceType, используя параметры в .tf
файле. Эта инфраструктура для AWS - лучшее из обоих миров (или, может быть, трех).
Terraform + Cloud Native IaC Tool для вашего облачного провайдера должен стать лучшим выбором в облаке!
Я буду делать больше проектов по миграции, используя Terraform | GCP | AWS | Ansible | Python | более.
Спасибо за чтение! Пожалуйста, дайте мне знать свои мысли в комментариях, и не стесняйтесь делиться, если вы нашли это полезным.
Не стесняйтесь связаться со мной в Linkedin, если у вас возникнут какие-либо проблемы с этим.
Больше контента на plainenglish.io