текст перекладу
У цій статті я розкажу вам, як я автоматизував розгортання надійної інфраструктури AWS за допомогою Terraform та налаштував розгортання додатків за допомогою Ansible. Цей проєкт підкреслює синергію між інфраструктурою як кодом (IaC) та інструментами для керування конфігураціями, щоб досягти масштабованих, повторюваних та ефективних робочих процесів.
Огляд проєкту
Проєкт включав наступне:
- Автоматизація інфраструктури AWS за допомогою Terraform для створення:
- Віртуальної приватної мережі (VPC) з публічними підмережами в кількох зонах доступності.
- Балансувальника навантаження (ALB) для розподілу навантаження.
- EC2 екземплярів, налаштованих для хостингу статичного вебсайту.
- Серверу Ansible для керування конфігурацією.
- Розгортання та налаштування додатків за допомогою Ansible для:
- Встановлення та налаштування Apache на веб-серверах.
- Розгортання файлів статичного сайту на веб-серверах.
Ось діаграма архітектури інфраструктури на високому рівні:
Архітектура проєкту
Крок 1: Налаштування інфраструктури AWS за допомогою Terraform
Terraform було використано для визначення та створення всієї інфраструктури AWS. Ось огляд ресурсів Terraform:
Визначені ресурси Terraform:
- Провайдер, VPC та підмережі
provider "aws" {
region = "us-east-1"
}
# Створення VPC
resource "aws_vpc" "project_vpc" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "project_vpc"
}
}
# Створення інтернет-шлюзу
resource "aws_internet_gateway" "project_igw" {
vpc_id = aws_vpc.project_vpc.id
tags = {
Name = "project_igw"
}
}
# Створення публічної підмережі 1
resource "aws_subnet" "public_subnet_1" {
vpc_id = aws_vpc.project_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags = {
Name = "public_subnet_1"
}
}
# Створення публічної підмережі 2
resource "aws_subnet" "public_subnet_2" {
vpc_id = aws_vpc.project_vpc.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-east-1b"
map_public_ip_on_launch = true
tags = {
Name = "public_subnet_2"
}
}
2.
текст перекладу
Групи безпеки
- Дозволити доступ по SSH та HTTP до екземплярів і ALB.
# група безпеки та правило
resource "aws_security_group" "instance_security_group" {
name = "instance_security_group"
description = "Allow security rules for ec2 instance"
vpc_id = aws_vpc.project_vpc.id
tags = {
Name = "Allow inbound and outbound rules"
}
}
# Правила безпеки для екземпляра
resource "aws_vpc_security_group_ingress_rule" "allow_ssh_from_my_ip" {
security_group_id = aws_security_group.instance_security_group.id
cidr_ipv4 = "175.157.23.47/32"
from_port = 22
ip_protocol = "tcp"
to_port = 22
tags = {
Name = "Allow SSH from my ip"
}
}
# Дозволити SSH з групи безпеки Ansible
resource "aws_security_group_rule" "allow_ssh_from_ansible_sg" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
security_group_id = aws_security_group.instance_security_group.id
source_security_group_id = aws_security_group.ansible_sg.id
description = "Allow SSH from Ansible security group"
}
resource "aws_vpc_security_group_ingress_rule" "allow_http" {
security_group_id = aws_security_group.instance_security_group.id
cidr_ipv4 = "0.0.0.0/0"
from_port = 80
ip_protocol = "tcp"
to_port = 80
tags = {
Name = "Allow HTTP"
}
}
resource "aws_vpc_security_group_ingress_rule" "allow_icmp" {
security_group_id = aws_security_group.instance_security_group.id
cidr_ipv4 = "0.0.0.0/0"
from_port = -1
to_port = -1
ip_protocol = "icmp"
tags = {
Name = "Allow ICMP"
}
}
resource "aws_vpc_security_group_egress_rule" "allow_all_outbound_traffic" {
security_group_id = aws_security_group.instance_security_group.id
cidr_ipv4 = "0.0.0.0/0"
ip_protocol = "-1"
tags = {
Name = "Allow all outbound traffic"
}
}
# група безпеки для балансувальника навантаження
resource "aws_security_group" "alb_sg" {
name = "alb_sg"
description = "Allow security rules for application load balancer"
vpc_id = aws_vpc.project_vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
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"]
}
}
# група безпеки для Ansible
resource "aws_security_group" "ansible_sg" {
name = "ansible_sg"
description = "Allow security rules for ansible"
vpc_id = aws_vpc.project_vpc.id
}
resource "aws_vpc_security_group_ingress_rule" "allow_ssh_my_ip" {
security_group_id = aws_security_group.ansible_sg.id
cidr_ipv4 = "175.157.23.47/32"
from_port = 22
ip_protocol = "tcp"
to_port = 22
tags = {
Name = "Allow SSH from my ip"
}
}
resource "aws_vpc_security_group_ingress_rule" "allow_http_ansible" {
security_group_id = aws_security_group.ansible_sg.id
cidr_ipv4 = "0.0.0.0/0"
from_port = 80
ip_protocol = "tcp"
to_port = 80
tags = {
Name = "Allow http ansible"
}
}
resource "aws_vpc_security_group_egress_rule" "allow_ansible_outbound" {
security_group_id = aws_security_group.ansible_sg.id
cidr_ipv4 = "0.0.0.0/0"
ip_protocol = "-1"
tags = {
Name = "Allow SSH from my ip"
}
}
3.
текст перекладу
**Балансувальник навантаження додатків
# створення групи цілей для ALB
resource "aws_lb_target_group" "target_group_alb" {
name = "load-balancer-target"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.project_vpc.id
}
# приєднання екземплярів до групи цілей
resource "aws_lb_target_group_attachment" "attachment_1" {
target_group_arn = aws_lb_target_group.target_group_alb.arn
target_id = aws_instance.web01.id
port = 80
}
resource "aws_lb_target_group_attachment" "attachment_2" {
target_group_arn = aws_lb_target_group.target_group_alb.arn
target_id = aws_instance.web02.id
port = 80
}
# створення балансувальника навантаження додатка
resource "aws_lb" "alb" {
name = "alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb_sg.id]
subnets = [aws_subnet.public_subnet_1.id, aws_subnet.public_subnet_2.id]
tags = {
Environment = "production"
}
}
# створення слухача для ALB
resource "aws_lb_listener" "alb_listener" {
load_balancer_arn = aws_lb.alb.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.target_group_alb.arn
}
}
output "alb_dns_name" {
value = aws_lb.alb.dns_name
}
4.
текст перекладу
EC2 Екземпляри
# сервер Ansible
resource "aws_instance" "ansible_server" {
ami = "ami-0e2c8caa4b6378d8c"
instance_type = "t2.micro"
key_name = aws_key_pair.ec2_key_pair.key_name
subnet_id = aws_subnet.public_subnet_1.id
vpc_security_group_ids = [aws_security_group.ansible_sg.id]
tags = {
Name = "Ansible Server"
}
}
output "ansible_server_public_ip" {
value = aws_instance.ansible_server.public_ip
}
# web01
resource "aws_instance" "web01" {
ami = "ami-0e2c8caa4b6378d8c"
instance_type = "t2.micro"
key_name = aws_key_pair.ec2_key_pair.key_name
subnet_id = aws_subnet.public_subnet_1.id
vpc_security_group_ids = [aws_security_group.instance_security_group.id]
tags = {
Name = "web01"
}
}
output "web01_public_ip" {
value = aws_instance.web01.public_ip
}
# web02
resource "aws_instance" "web02" {
ami = "ami-0e2c8caa4b6378d8c"
instance_type = "t2.micro"
key_name = aws_key_pair.ec2_key_pair.key_name
subnet_id = aws_subnet.public_subnet_2.id
vpc_security_group_ids = [aws_security_group.instance_security_group.id]
tags = {
Name = "web02"
}
}
output "web02_public_ip" {
value = aws_instance.web02.public_ip
}
Коли скрипти Terraform були готові, я виконав наступні команди для розгортання інфраструктури:
terraform init
terraform plan
terraform apply
Крок 2: Налаштування розгортання за допомогою Ansible
Після створення інфраструктури я використав Ansible для налаштування веб-серверів і розгортання статичного вебсайту.
Ansible.cfg
Конфігурація для Ansible
[defaults]
host_key_checking = False
inventory = ./inventory
forks = 5
[privilage_escalation]
become = True
become_method = sudo
Файл інвентаризації
Файл інвентаризації визначає цільові хости для Ansible:
all:
hosts:
web01:
ansible_host: 10.0.1.189
web02:
ansible_host: 10.0.2.195
children:
webservers:
hosts:
web01:
web02:
Playbook Ansible
Ось playbook для встановлення Apache і розгортання статичного вебсайту:
---
- name: Provisioning webservers
hosts: webservers
become: yes
tasks:
- name: Instll Apache2
ansible.builtin.apt:
name: apache2
state: present
- name: Start Apache2 service
ansible.builtin.service:
name: apache2
state: started
enabled: yes
- name: Copy index.html file
ansible.builtin.copy:
src: 2137_barista_cafe/
dest: /var/www/html/
Виконання Playbook
Далі, відповідно до структури вашого проєкту, виконайте playbook.
Результат
Після успішного виконання playbook:
- Вебсервер Apache було встановлено та запущено на обох EC2 екземплярах.
- Файли статичного сайту було скопійовано до
/var/www/html/
. - Балансувальник навантаження додатка розподіляв трафік між двома веб-серверами.
Відвідування DNS-імені ALB у браузері показало розгорнутий статичний вебсайт.
Труднощі, з якими я зіткнувся
- Проблеми з підключенням по SSH: Спочатку SSH не працював через неправильні правила групи безпеки. Я переконався, що групі безпеки сервера Ansible дозволено доступ до групи безпеки веб-серверів.
- Помилки доступу: Під час завдання копіювання файлів виникли проблеми з правами доступу. Додавання директиви
become: yes
вирішило це. - Управління станом Terraform: Для забезпечення консистентності файлів стану необхідна правильна конфігурація бекенду.
Основні висновки
- Поєднання Terraform і Ansible є потужним підходом для керування хмарною інфраструктурою та конфігурацією.
- Налагодження проблем з SSH і доступами вимагає глибокого розуміння правил груп безпеки та прав доступу користувачів.
- Модульне розділення конфігурацій Terraform і Ansible підвищує повторне використання та зручність для читання.
Висновок
Цей проєкт демонструє, як інструменти IaC, такі як Terraform, і інструменти для керування конфігурацією, такі як Ansible, можуть спростити розгортання в хмарі.
текст перекладу
Автоматизуючи надання інфраструктури та налаштування конфігурації, ми можемо досягти масштабованих, ефективних і повторюваних робочих процесів для сучасних додатків.
Цей проєкт повністю хардкодований...
Не соромтесь поділитися своїми думками або задати питання в коментарях. Давайте з’єднаємось і обговоримо більше про автоматизацію та практики DevOps!
Перекладено з: Automating AWS Infrastructure and Deployment with Terraform and Ansible