Введение
База заказов принимает подключения из всего VPC приложения, а приложение использует административную учётную запись базы. Вы ограничите сетевой доступ и создадите отдельного пользователя, который может читать и добавлять заказы, но не удалять их.
Сначала завершите работы о подключении и SQL. Эта независимая среда содержит основной PostgreSQL, три примерных заказа и приложение. Вы проверите обе границы доступа и в конце удалите учебную базу.
Связь с сертификацией
Эта работа даёт начальную практику по следующим темам экзаменов.
- Cloud Practitioner (CLF-C02) · Задача 3.5: Понять группы безопасности как границу сетевого доступа.
- Solutions Architect – Associate (SAA-C03) · Задача 1.3: Применить минимальные привилегии и ограничить доступ к данным приложения.
Ограничение сетевого источника PostgreSQL
На этом этапе вы замените широкий входящий доступ из VPC доступом из подготовленной группы безопасности приложения.
Группа безопасности определяет, какие сетевые соединения могут достигать базы. Она не определяет SQL-операции, доступные авторизованному пользователю базы. Эту отдельную границу вы настроите на следующем этапе.
Загрузите подготовленные настройки:
cd /home/labex/project
source database.env
Проверьте группу базы и два предоставленных документа правил:
aws ec2 \
describe-security-groups \
--group-ids "$DB_SECURITY_GROUP_ID" \
--query 'SecurityGroups[].{Group:GroupName,Ingress:IpPermissions}'
cat broad-rule.json
cat application-rule.json
Текущее правило разрешает TCP-порт 5432 из 10.70.0.0/16, поэтому другие клиенты этого VPC тоже могут пытаться подключаться. Новое правило использует UserIdGroupPairs для ссылки на группу приложения. Ссылка на группу разрешает трафик от связанных с ней ресурсов, а не копирует её правила.
Удалите широкое правило и добавьте правило приложения:
aws ec2 \
revoke-security-group-ingress \
--group-id "$DB_SECURITY_GROUP_ID" \
--ip-permissions file://broad-rule.json
aws ec2 \
authorize-security-group-ingress \
--group-id "$DB_SECURITY_GROUP_ID" \
--ip-permissions file://application-rule.json
Проверьте новое соединение из источника приложения:
psql \
"service=orders-db" \
--command 'SELECT count(*) FROM orders;'
Ожидается 3. Затем проверьте предоставленный клиент вне группы приложения:
psql \
"service=orders-db-external" \
--command 'SELECT count(*) FROM orders;'
Подключение внешнего клиента должно завершиться ошибкой. Пароль базы действителен, но сетевой источник не разрешён. Подготовленные имена соединений выбирают эти два источника. Правила упражнения не меняют ваше управляющее подключение к Terminal или AWS View.
AWS View должен показывать группу приложения как источник PostgreSQL для базы вместо широкого CIDR VPC.
Создание пользователя базы для приложения
На этом этапе вы разрешите приложению читать и добавлять заказы без административных прав и права удаления.
Роль PostgreSQL может обладать привилегиями. Роль с LOGIN может аутентифицироваться как пользователь базы. Роли базы отличаются от идентичностей AWS IAM: IAM управляет ресурсом RDS, а эти SQL-разрешения регулируют операции внутри PostgreSQL.

Концептуальная схема: Сетевой доступ, вход и права SQL — отдельные границы.
Создайте orders_app с предоставленным приватным файлом пароля приложения. --set задаёт переменную psql, а :'app_password' безопасно заключает её значение в кавычки как строку SQL:
psql \
"service=orders-db" \
--set=ON_ERROR_STOP=1 \
--set=app_password="$(cat app-password.txt)" <<'SQL'
CREATE ROLE orders_app LOGIN PASSWORD :'app_password';
GRANT CONNECT ON DATABASE orders TO orders_app;
GRANT USAGE ON SCHEMA public TO orders_app;
GRANT SELECT, INSERT ON orders TO orders_app;
SQL
CONNECT разрешает подключения к базе. USAGE разрешает доступ через схему — пространство имён с таблицами. SELECT и INSERT разрешают только нужные операции с заказами. Вы не предоставили DELETE, UPDATE, CREATEDB, CREATEROLE или права суперпользователя.
Проверьте роль, передав приватное значение пароля в psql:
PGPASSWORD="$(cat app-password.txt)" psql \
"service=orders-db-app" \
--command 'SELECT current_user, count(*) FROM orders;'
Ожидаются пользователь orders_app и 3 заказа.
Попробуйте удалить несуществующий ID заказа. Оператор не удалит реальный заказ даже при случайно слишком широких правах:
PGPASSWORD="$(cat app-password.txt)" psql \
"service=orders-db-app" \
--command 'DELETE FROM orders WHERE order_id = -1;'
Ожидается permission denied for table orders. Эта ошибка возникает после успешного сетевого соединения и входа в базу, поэтому доказывает другую границу, чем отказ подключения внешнего клиента.
Использование ограниченной учётной записи в приложении
На этом этапе вы настроите роль в приложении и докажете, что обычные операции с заказами работают.
Измените пользователя базы и ссылку на файл пароля, сохранив оба поля endpoint:
jq \
'.user = "orders_app" | .password_file = "app-password.txt"' \
app-config.json > app-config.new
mv app-config.new app-config.json
Прочитайте текущий список заказов:
curl \
--silent \
--show-error \
--fail \
http://127.0.0.1:8080/application/orders | jq
Ожидаются три исходных заказа и user: orders_app.
Добавьте заказ через HTTP-endpoint приложения. Content-Type сообщает, что тело запроса имеет формат JSON:
curl \
--silent \
--show-error \
--fail \
--request POST \
--header 'Content-Type: application/json' \
--data '{"order_id":104,"customer":"Kai","total":"5.00"}' \
http://127.0.0.1:8080/application/orders
Ожидаются saved: true и ID заказа 104. Прочитайте список снова:
curl \
--silent \
--show-error \
--fail \
http://127.0.0.1:8080/application/orders | jq
Ожидаются четыре заказа, включая заказ Kai на 5.00. AWS View должен показывать те же сохранённые данные и ограниченную учётную запись приложения. Уменьшенные права сохранили необходимую функциональность.

Удаление учебной базы
На этом этапе вы удалите базу этой работы вместе с примерными заказами и SQL-пользователями.
aws rds \
delete-db-instance \
--db-instance-identifier orders-db \
--skip-final-snapshot \
--query 'DBInstance.DBInstanceIdentifier'
aws rds \
wait db-instance-deleted \
--db-instance-identifier orders-db
aws rds \
describe-db-instances \
--query 'DBInstances[].DBInstanceIdentifier'
Ожидается []. Движок и его роли удалены; старый endpoint приложения больше не подключается. Сохраните предоставленную сеть и её ограниченную группу базы. Открывать доступ заново для очистки не требуется.
Итоги
Вы ограничили подключения PostgreSQL источником приложения и дали ему отдельную ограниченную роль. Внешний клиент не смог подключиться, а роль приложения — удалить заказы, при этом обычное чтение и вставка работали. Затем вы удалили учебную базу, сохранив ограниченные правила сетевого доступа.
Следующая работа восстановит потерянные заказы из ручного снимка RDS в новую базу.


