RBCloud & DevOpsTHE PRACTICAL LEARNING LIBRARY
By Ravindra BagaleResources

CHAPTER 57 / 60

Project 2 — Provision EC2, S3, RDS and permissions

Create the infrastructure and prove each connection before installing the full application.

Concept + practical labBy Ravindra Bagale · ~5 min read · lab time additional

Step 1: EC2 and PHP

Use Ubuntu 24.04 LTS for the simplest reference deployment. Install Nginx, PHP-FPM, PHP MySQL/cURL/XML/mbstring extensions, unzip and a MySQL client. Verify PHP is at least 8.2. AL2023 can also be used, but select a supported PHP 8.2+ package family available in your pinned repository and adapt the FPM service/socket. Do not assume its unversioned PHP default meets the application requirement.

bash
sudo apt update
sudo apt install -y nginx php-fpm php-cli php-mysql php-curl php-xml php-mbstring unzip mysql-client
php -v
php -m

Step 2: private bucket and role

Create the private bucket as taught in the S3 chapter. Copy project/config/iam-policy.json, replace its bucket placeholder and create a policy. Create an EC2-trusted role, attach that policy and assign its instance profile to the web instance. The DeleteObject permission is used to compensate if a database insert fails after an upload. Versioning may retain previous objects/delete markers, so reconciliation still matters. Do not add S3FullAccess. The sample explicitly uses SSE-S3 for uploads; adapt both code and permissions if your bucket requires SSE-KMS.

Step 3: RDS and SQL

Create private RDS MySQL, its subnet group and security group. Download the RDS CA bundle and verify its source. Connect from EC2 using hostname verification, then apply schema.sql as a setup administrator.

bash
mysql -h DB_ENDPOINT -u ADMIN -p --ssl-mode=VERIFY_IDENTITY \
 --ssl-ca=/etc/ssl/certs/rds-global-bundle.pem < schema.sql

Create an application account with a generated password in an administrative SQL session. Use the correct host scope for your network; the example below permits matching network connections but relies on the private SG boundary and authentication.

sql
CREATE USER 'reels_app'@'%' IDENTIFIED BY 'REPLACE_WITH_A_GENERATED_PASSWORD' REQUIRE SSL;
GRANT SELECT, INSERT, UPDATE ON reels.posts TO 'reels_app'@'%';
SHOW GRANTS FOR 'reels_app'@'%';

Never paste a real password into shared notes. MySQL client history can retain SQL statements; use an approved secret/bootstrap process for real deployments.

Step 4: prove access

Verify the instance role with aws sts get-caller-identity. Test a permitted S3 key and a forbidden prefix. Connect as reels_app and verify SELECT works while CREATE TABLE is denied. Query SHOW SESSION STATUS LIKE 'Ssl_cipher' and confirm TLS is negotiated.

Ravindra’s Tip

पहले तीन छोटे tests करो: EC2 से database connect, role से S3 access, और Nginx से page load। ये तीनों ठीक हों, तभी पूरा application जोड़ो—debugging आसान होगी।

Official references

RDS trust certificates PHP SDK installation

Interview and revision check

Why does S3 access succeeding not prove RDS will work?

S3 uses AWS API authorization; RDS also requires private connectivity, TLS and database credentials/privileges.

Ravindra Bagale · Cloud & DevOps Academy · Handbook and project downloads