Імпорт ресурсів AWS RDS за допомогою Terraform
Written by:
Igor Gorovyy
DevOps Engineer Lead & Senior Solutions Architect
LinkedIn
Огляд процесу
У цій статті розглянемо процес імпорту існуючих баз даних AWS RDS в інфраструктурний код Terraform. Це важливий етап у забезпеченні підходу Infrastructure as Code (IaC) для керування хмарними ресурсами.
Коли компанія заощаджує кошти і водночас планує Disaster Recovery Plan (DRP), найпростішим сценарієм буде бекап та відновлення ресурсів. У випадку хмарної інфраструктури ресурси зазвичай відновлюються в іншому регіоні.
Ця стаття не покриває інші стратегії а підходи nbge stand-by, active-activeт DRP, оскільки це не є основною темою. Основним наміром є показати "дешево та сердито ..." механізм terraform import та його використання для імпорту ресурсів RDS.
При відновленні ресурсів виникає необхідність покриття кодом Terraform нового середовища. Механізм імпорту ресурсів у Terraform дозволяє швидко та безпечно відновити ресурси.
До версії Terraform 1.6 імпорт вимагав ручного керування станом (state) і контролю за тим, куди переміщуються ресурси. Це могло призводити до потенційних помилок. Починаючи з версії 1.6, Terraform надає більш просту та надійну систему керування імпортом ресурсів, що значно спрощує процес відновлення інфраструктури у DRP-сценаріях.
Схема процесу імпорту
graph TD;
A[Існуючий ресурс AWS RDS] -->|Команда import| B[Імпорт у Terraform]
B -->|Генерація конфігурації| C[Створення main.tf]
C -->|Перевірка змін| D[terraform plan]
D -->|Застосування змін| E[terraform apply]
E -->|Ресурс під управлінням Terraform| F[Готовий RDS]
Для чого потрібен імпорт?
Імпорт існуючих ресурсів дозволяє:
- Централізувати керування інфраструктурою за допомогою Terraform
- Відстежувати зміни конфігурацій через систему контролю версій
- Уникати ручного налаштування ресурсів та зменшувати ризик помилок
- Спрощувати розгортання та масштабування систем
- Забезпечувати ефективне відновлення після інцидентів або аварій
Основні кроки імпорту ресурсів RDS
1. Відстеження змін
- Збереження стану інфраструктури
- Terraform використовує файл
terraform.tfstate
для збереження поточного стану ресурсів. -
Це дозволяє уникнути розбіжностей між фактичним станом у хмарі та конфігурацією у коді.
-
Запобігання конфліктам
- Використання механізмів блокування змін (
terraform plan
) дозволяє уникнути одночасних конфліктних оновлень ресурсів. -
Це особливо корисно при спільній роботі кількох інженерів.
-
Історія модифікацій
- Використання Git або інших систем контролю версій допомагає відстежувати внесені зміни та швидко повертатися до попередніх конфігурацій.
- Логування змін у Terraform дозволяє відслідковувати причини та наслідки кожної модифікації.
2. Автоматизація процесів
- CI/CD інтеграція
- Terraform можна інтегрувати з системами автоматизації, такими як GitHub Actions, GitLab CI/CD, Jenkins або AWS CodePipeline.
-
Це дозволяє автоматично застосовувати зміни після проходження тестів.
-
Автоматичне тестування
terraform validate
перевіряє коректність синтаксису конфігурацій.terraform plan
дозволяє оцінити майбутні зміни перед їх застосуванням.-
terratest
використовується для модульного тестування інфраструктури. -
Планові оновлення
- Використання автоматизованих процесів оновлення інфраструктури дозволяє своєчасно застосовувати оновлення без ризику збоїв.
-
Застосування
terraform apply -auto-approve
у контрольованих середовищах спрощує оновлення конфігурацій. -
Автоматичне розгортання
- За допомогою модулів Terraform можна стандартизовано розгортати нові середовища без ручного втручання.
- Автоматичне розгортання дозволяє зменшити час виходу продукту на ринок.
3. Масштабованість
- Гнучкість розгортання
- Terraform підтримує параметризовані змінні, що дозволяє легко адаптувати конфігурації під різні середовища (dev, staging, production).
-
Використання модулів дозволяє уникнути дублювання коду.
-
Мультирегіональність
- Terraform дозволяє керувати інфраструктурою у різних регіонах AWS з однієї конфігурації.
-
Використання
provider
зalias
дозволяє легко розгортати ресурси у кількох регіонах. В нашому випадку ми переносимо ресурси в регіон "Blue" (provider = aws.Blue ) і там імпортуэмо ресурси до коду. -
Клонування середовищ
- Terraform підтримує
terraform workspace
, що дозволяє створювати незалежні середовища для тестування, не впливаючи на продакшен. - Можливість швидкого копіювання конфігурацій дозволяє легко створювати нові екземпляри інфраструктури.
Приклади коду
Імпорт існуючого RDS у Terraform
terraform plan -generate-config-out=generated-resources.tf
terraform import aws_db_instance.example_db my-existing-db
Оголошення ресурсу RDS у Terraform
import {
provider = aws.Blue
to = aws_db_instance.product1-dev-service1-migrated
id = "product1-dev-service1-migrated"
}
import {
provider = aws.Blue
to = aws_db_instance.product1-dev-service2-migrated
id = "product1-dev-service2-migrated"
}
import {
provider = aws.Blue
to = aws_db_instance.product1-dev-service3-migrated
id = "product1-dev-service3-migrated"
}
import {
provider = aws.Blue
to = aws_db_instance.product1-dev-service4-migrated
id = "product1-dev-service4-migrated"
}
import {
provider = aws.Blue
to = aws_db_instance.product1-service5-migrated
id = "product1-service5-migrated"
}
# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.
# __generated__ by Terraform
resource "aws_db_instance" "product1-dev-service1-migrated" {
provider = aws.Blue
allocated_storage = 100
allow_major_version_upgrade = null
apply_immediately = null
auto_minor_version_upgrade = false
availability_zone = "eu-west-1a"
backup_retention_period = 5
backup_target = "region"
backup_window = "20:31-21:01"
ca_cert_identifier = "rds-ca-rsa2048-g1"
character_set_name = null
copy_tags_to_snapshot = false
custom_iam_instance_profile = null
customer_owned_ip_enabled = false
db_name = "owner"
db_subnet_group_name = "multiregion-dev-vpc-blue"
dedicated_log_volume = false
delete_automated_backups = true
deletion_protection = true
domain = null
domain_auth_secret_arn = null
domain_fqdn = null
domain_iam_role_name = null
domain_ou = null
enabled_cloudwatch_logs_exports = []
engine = "postgres"
engine_lifecycle_support = "open-source-rds-extended-support"
engine_version = jsonencode(16.6)
final_snapshot_identifier = null
iam_database_authentication_enabled = false
identifier = "product1-dev-service4-migrated"
identifier_prefix = null
instance_class = "db.t4g.large"
iops = 3000
kms_key_id = "arn:aws:kms:eu-west-1:294***********8:key/1*********-8**f-4**0-8**1-**********b"
license_model = "postgresql-license"
maintenance_window = "wed:01:55-wed:02:25"
manage_master_user_password = null
master_user_secret_kms_key_id = null
max_allocated_storage = 0
monitoring_interval = 0
monitoring_role_arn = null
multi_az = false
nchar_character_set_name = null
network_type = "IPV4"
option_group_name = "default:postgres-16"
parameter_group_name = "multiregion-rds-service4-pg-16"
password = null # sensitive
performance_insights_enabled = false
performance_insights_kms_key_id = null
performance_insights_retention_period = 0
port = 5432
publicly_accessible = false
replica_mode = null
replicate_source_db = null
skip_final_snapshot = true
snapshot_identifier = null
storage_encrypted = true
storage_throughput = 125
storage_type = "gp3"
tags = {}
tags_all = {}
timezone = null
upgrade_storage_config = null
username = "service1"
vpc_security_group_ids = ["sg-0fe****************6"]
}
# __generated__ by Terraform
resource "aws_db_instance" "product1-dev-service2-migrated" {
provider = aws.Blue
allocated_storage = 605
allow_major_version_upgrade = null
apply_immediately = null
auto_minor_version_upgrade = false
availability_zone = "eu-west-1a"
backup_retention_period = 5
backup_target = "region"
backup_window = "21:14-21:44"
ca_cert_identifier = "rds-ca-rsa2048-g1"
character_set_name = null
copy_tags_to_snapshot = false
custom_iam_instance_profile = null
customer_owned_ip_enabled = false
db_name = "service2"
db_subnet_group_name = "multiregion-dev-vpc-blue"
dedicated_log_volume = false
delete_automated_backups = true
deletion_protection = true
domain = null
domain_auth_secret_arn = null
domain_fqdn = null
domain_iam_role_name = null
domain_ou = null
enabled_cloudwatch_logs_exports = []
engine = "postgres"
engine_lifecycle_support = "open-source-rds-extended-support"
engine_version = jsonencode(16.6)
final_snapshot_identifier = null
iam_database_authentication_enabled = false
identifier = "product1-dev-service2-migrated"
identifier_prefix = null
instance_class = "db.m6g.large"
iops = 12000
kms_key_id = "arn:aws:kms:eu-west-1:294***********8:key/1*********-8**f-4**0-8**1-**********b"
license_model = "postgresql-license"
maintenance_window = "sun:00:07-sun:00:37"
manage_master_user_password = null
master_user_secret_kms_key_id = null
max_allocated_storage = 0
monitoring_interval = 0
monitoring_role_arn = null
multi_az = false
nchar_character_set_name = null
network_type = "IPV4"
option_group_name = "default:postgres-16"
parameter_group_name = "multiregion-rds-pg-logical-16"
password = null # sensitive
performance_insights_enabled = false
performance_insights_kms_key_id = null
performance_insights_retention_period = 0
port = 5432
publicly_accessible = false
replica_mode = null
replicate_source_db = null
skip_final_snapshot = true
snapshot_identifier = null
storage_encrypted = true
storage_throughput = 500
storage_type = "gp3"
tags = {}
tags_all = {}
timezone = null
upgrade_storage_config = null
username = "service2"
vpc_security_group_ids = ["sg-0fe****************6"]
}
# __generated__ by Terraform
resource "aws_db_instance" "product1-service3-migrated" {
provider = aws.Blue
allocated_storage = 83
allow_major_version_upgrade = null
apply_immediately = null
auto_minor_version_upgrade = false
availability_zone = "eu-west-1a"
backup_retention_period = 1
backup_target = "region"
backup_window = "21:12-21:42"
ca_cert_identifier = "rds-ca-rsa2048-g1"
character_set_name = null
copy_tags_to_snapshot = false
custom_iam_instance_profile = null
customer_owned_ip_enabled = false
db_name = "service5"
db_subnet_group_name = "multiregion-dev-vpc-blue"
dedicated_log_volume = false
delete_automated_backups = true
deletion_protection = true
domain = null
domain_auth_secret_arn = null
domain_fqdn = null
domain_iam_role_name = null
domain_ou = null
enabled_cloudwatch_logs_exports = []
engine = "postgres"
engine_lifecycle_support = "open-source-rds-extended-support"
engine_version = jsonencode(16.6)
final_snapshot_identifier = null
iam_database_authentication_enabled = false
identifier = "product1-service5-migrated"
identifier_prefix = null
instance_class = "db.t4g.large"
iops = 3000
kms_key_id = "arn:aws:kms:eu-west-1:294***********8:key/1*********-8**f-4**0-8**1-**********b"
license_model = "postgresql-license"
maintenance_window = "thu:01:30-thu:02:00"
manage_master_user_password = null
master_user_secret_kms_key_id = null
max_allocated_storage = 0
monitoring_interval = 0
monitoring_role_arn = null
multi_az = false
nchar_character_set_name = null
network_type = "IPV4"
option_group_name = "default:postgres-16"
parameter_group_name = "multiregion-rds-dev-athena-16"
password = null # sensitive
performance_insights_enabled = false
performance_insights_kms_key_id = null
performance_insights_retention_period = 0
port = 5432
publicly_accessible = false
replica_mode = null
replicate_source_db = null
skip_final_snapshot = true
snapshot_identifier = null
storage_encrypted = true
storage_throughput = 125
storage_type = "gp3"
tags = {}
tags_all = {}
timezone = null
upgrade_storage_config = null
username = "service3"
vpc_security_group_ids = ["sg-0fe****************6"]
}
# __generated__ by Terraform
resource "aws_db_instance" "product1-dev-service4-migrated" {
provider = aws.Blue
allocated_storage = 330
allow_major_version_upgrade = null
apply_immediately = null
auto_minor_version_upgrade = false
availability_zone = "eu-west-1a"
backup_retention_period = 5
backup_target = "region"
backup_window = "00:59-01:29"
ca_cert_identifier = "rds-ca-rsa2048-g1"
character_set_name = null
copy_tags_to_snapshot = false
custom_iam_instance_profile = null
customer_owned_ip_enabled = false
db_name = "managementaccounting"multiregion-rds-pg-audit-16
db_subnet_group_name = "multiregion-dev-vpc-blue"
dedicated_log_volume = false
delete_automated_backups = true
deletion_protection = true
domain = null
domain_auth_secret_arn = null
domain_fqdn = null
domain_iam_role_name = null
domain_ou = null
enabled_cloudwatch_logs_exports = []
engine = "postgres"
engine_lifecycle_support = "open-source-rds-extended-support"
engine_version = jsonencode(16.6)
final_snapshot_identifier = null
iam_database_authentication_enabled = false
identifier = "product1-dev-service3-migrated"
identifier_prefix = null
instance_class = "db.t4g.large"
iops = 3000
kms_key_id = "arn:aws:kms:eu-west-1:294***********8:key/1*********-8**f-4**0-8**1-**********b"
license_model = "postgresql-license"
maintenance_window = "wed:23:11-wed:23:41"
manage_master_user_password = null
master_user_secret_kms_key_id = null
max_allocated_storage = 0
monitoring_interval = 0
monitoring_role_arn = null
multi_az = false
nchar_character_set_name = null
network_type = "IPV4"
option_group_name = "default:postgres-16"
parameter_group_name = "multiregion-rds-pg-audit-16"
password = null # sensitive
performance_insights_enabled = false
performance_insights_kms_key_id = null
performance_insights_retention_period = 0
port = 5432
publicly_accessible = false
replica_mode = null
replicate_source_db = null
skip_final_snapshot = true
snapshot_identifier = null
storage_encrypted = true
storage_throughput = 125
storage_type = "gp3"
tags = {}
tags_all = {}
timezone = null
upgrade_storage_config = null
username = "service4"
vpc_security_group_ids = ["sg-0fe****************6"]
}
# __generated__ by Terraform
resource "aws_db_instance" "product1-dev-service5-migrated" {
provider = aws.Blue
allocated_storage = 64
allow_major_version_upgrade = null
apply_immediately = null
auto_minor_version_upgrade = false
availability_zone = "eu-west-1a"
backup_retention_period = 5
backup_target = "region"
backup_window = "01:22-01:52"
ca_cert_identifier = "rds-ca-rsa2048-g1"
character_set_name = null
copy_tags_to_snapshot = false
custom_iam_instance_profile = null
customer_owned_ip_enabled = false
db_name = "service1"
db_subnet_group_name = "multiregion-dev-vpc-blue"
dedicated_log_volume = false
delete_automated_backups = true
deletion_protection = true
domain = null
domain_auth_secret_arn = null
domain_fqdn = null
domain_iam_role_name = null
domain_ou = null
enabled_cloudwatch_logs_exports = []
engine = "postgres"
engine_lifecycle_support = "open-source-rds-extended-support"
engine_version = jsonencode(16.6)
final_snapshot_identifier = null
iam_database_authentication_enabled = false
identifier = "product1-dev-service1-migrated"
identifier_prefix = null
instance_class = "db.t4g.large"
iops = 3000
kms_key_id = "arn:aws:kms:eu-west-1:294***********8:key/1*********-8**f-4**0-8**1-**********b"
license_model = "postgresql-license"
maintenance_window = "tue:22:05-tue:22:35"
manage_master_user_password = null
master_user_secret_kms_key_id = null
max_allocated_storage = 0
monitoring_interval = 0
monitoring_role_arn = null
multi_az = false
nchar_character_set_name = null
network_type = "IPV4"
option_group_name = "default:postgres-16"
parameter_group_name = "multiregion-rds-pg-logical-16"
password = null # sensitive
performance_insights_enabled = false
performance_insights_kms_key_id = null
performance_insights_retention_period = 0
port = 5432
publicly_accessible = false
replica_mode = null
replicate_source_db = null
skip_final_snapshot = true
snapshot_identifier = null
storage_encrypted = true
storage_throughput = 125
storage_type = "gp3"
tags = {}
tags_all = {}
timezone = null
upgrade_storage_config = null
username = "service5"
vpc_security_group_ids = ["sg-0fe****************6"]
}
Планування та застосування змін
terraform plan
terraform apply -auto-approve
Висновок
Стратегічні переваги
- Покращення керованості
- Централізоване управління всіма ресурсами через єдину конфігурацію.
- Легкість у відстеженні та контролі змін.
-
Автоматизоване оновлення та управління залежностями.
-
Оптимізація ресурсів
- Скорочення витрат за рахунок правильного планування інфраструктури.
- Автоматичне масштабування та ефективний розподіл ресурсів.
- Мінімізація ризику людських помилок через автоматизоване розгортання.
Довгострокові вигоди
- Інвестиція в майбутнє
- Полегшене розширення інфраструктури завдяки IaC.
- Забезпечення стабільності та повторюваності розгортань.
-
Відповідність стандартам безпеки та відповідності.
-
Операційні покращення
- Скорочення часу на управління інфраструктурою.
- Автоматизація процесів розгортання та оновлення.
- Підвищення загальної надійності та доступності сервісів.
References: Hashicorp