@@ -308,7 +308,7 @@ resource "aws_iam_role" "eks_node_role" {
308308
309309#### 5. Deploy Infrastructure
310310
311- **IMPORTANT**: Deploy in TWO separate PRs due to "one environment per PR" constraint.
311+ **IMPORTANT**: Deploy in MULTIPLE separate PRs due to "one environment per PR" constraint and Terraform dependency requirements .
312312
313313##### Step 5a: Deploy Global Resources (ECR Repositories)
314314
@@ -326,32 +326,115 @@ git push origin terraform/deploy-global
326326# Workflow automatically applies > ECR repositories created
327327```
328328
329- ##### Step 5b: Deploy Dev Environment (EKS Cluster)
329+ ##### Step 5b: Deploy Dev Environment - Part 1 (EKS Cluster Only )
330330
331- After global deployment completes, deploy dev infrastructure:
331+ **CRITICAL**: You MUST comment out resources that depend on EKS cluster data before first deployment to avoid "data source not found" errors.
332+
333+ Files that MUST be commented out:
334+ - **ALL resources in `terraform/environments/dev/helm.tf`** (ArgoCD, NGINX Ingress, Metrics Server, Prometheus/Grafana)
335+ - **ALL resources in `terraform/environments/dev/security-groups.tf`** (they reference EKS cluster data)
336+ - **kubernetes and helm providers in `terraform/environments/dev/providers.tf`** (keep only: aws, random, null)
332337
333338```bash
334- # Create PR for dev environment
339+ # Prepare dev environment configuration
335340git checkout main
336341git pull origin main
337- git checkout -b terraform/deploy-dev
338- echo "# Deploy EKS" >> terraform/environments/dev/eks.tf
342+ git checkout -b terraform/deploy-dev-eks
343+
344+ # Comment out the files mentioned above
345+ # In terraform/environments/dev/:
346+ # - Comment out ALL resources in helm.tf
347+ # - Comment out ALL resources in security-groups.tf
348+ # - Comment out kubernetes and helm providers in providers.tf
349+
350+ # Commit the changes
339351git add terraform/environments/dev/
340- git commit -m "terraform(dev): create EKS cluster and VPC "
341- git push origin terraform/deploy-dev
352+ git commit -m "terraform(dev): prepare for EKS cluster creation (commented dependent resources) "
353+ git push origin terraform/deploy-dev-eks
342354
343355# Create PR > Review terraform plan > Merge to main
344- # Workflow automatically applies > EKS cluster + VPC + Helm components deployed
345- # This takes ~15-20 minutes (EKS cluster creation)
356+ # Workflow automatically applies > EKS cluster + VPC created
357+ # WARNING: This takes ~15-20 minutes (EKS cluster creation)
346358```
347359
348- **Why Two PRs?**
360+ **Why comment out resources?**
361+
362+ - Helm provider needs EKS cluster endpoint (doesn' t exist yet)
363+ - Security groups reference EKS cluster data sources (doesn' t exist yet)
364+ - Terraform will fail with "data source not found" errors if these are active on first apply
365+
366+ ##### Step 5c: Deploy Dev Environment - Part 2 (Helm Components)
367+
368+ After EKS cluster is created, uncomment the resources and deploy Helm components:
369+
370+ ```bash
371+ # Wait for Step 5b to complete (check GitHub Actions)
372+ git checkout main
373+ git pull origin main
374+ git checkout -b terraform/deploy-dev-helm
349375
376+ # Uncomment previously commented resources:
377+ # In terraform/environments/dev/:
378+ # - Uncomment ALL resources in helm.tf
379+ # - Uncomment ALL resources in security-groups.tf
380+ # - Uncomment kubernetes and helm providers in providers.tf
381+
382+ # Commit the changes
383+ git add terraform/environments/dev/
384+ git commit -m "terraform(dev): deploy Helm components (ArgoCD, Ingress, Monitoring)"
385+ git push origin terraform/deploy-dev-helm
386+
387+ # Create PR > Review terraform plan > Merge to main
388+ # Workflow automatically applies > ArgoCD, NGINX Ingress, Metrics Server, Prometheus & Grafana deployed
389+ ```
390+
391+ **Why Three PRs?**
392+
393+ - **PR 1 (global)**: ECR must exist before image CI can push
394+ - **PR 2 (dev-eks)**: EKS cluster must exist before Helm/Kubernetes providers can work
395+ - **PR 3 (dev-helm)**: Clean separation, allows reviewing infrastructure vs application layer changes
350396- Terraform workflows enforce one environment change per PR
351- - ECR must exist before image CI can push
352- - Clear separation of concerns (global resources vs environment-specific)
353397
354- To create new environments (qa, prod), copy `dev/` and adjust configuration (see [terraform/README.md](terraform/README.md))
398+ ##### Creating Additional Environments (QA, Prod)
399+
400+ To create a new environment based on dev:
401+
402+ ```bash
403+ # 1. Copy dev folder
404+ cp -r terraform/environments/dev terraform/environments/qa
405+
406+ # 2. Create S3 bucket (follow Step 1)
407+ aws s3api create-bucket --bucket <your-name>-kubernetes-tf-state-qa-bucket --region eu-west-1 --create-bucket-configuration LocationConstraint=eu-west-1
408+ # + enable versioning and encryption
409+
410+ # 3. Update terraform/environments/qa/backend.tf with new S3 bucket name
411+
412+ # 4. Update terraform/environments/qa/local-vars.tf:
413+ # project_name = "<your-name>-microservices-demo-qa"
414+ # tags = { env = "qa", ... }
415+
416+ # 5. Configure/remove IAM boundary policies in terraform/environments/qa/iam.tf (see Step 4b)
417+
418+ # 6. Comment out resources (CRITICAL - same as Step 5b):
419+ # - ALL resources in terraform/environments/qa/helm.tf
420+ # - ALL resources in terraform/environments/qa/security-groups.tf
421+ # - kubernetes/helm providers in terraform/environments/qa/providers.tf
422+
423+ # 7. Create PR for EKS cluster
424+ git checkout -b terraform/deploy-qa-eks
425+ git add terraform/environments/qa/
426+ git commit -m "terraform(qa): create EKS cluster"
427+ git push origin terraform/deploy-qa-eks
428+ # Create PR > Merge > Wait 15-20 min
429+
430+ # 8. Uncomment resources and create PR for Helm components
431+ git checkout -b terraform/deploy-qa-helm
432+ # Uncomment helm.tf, security-groups.tf, providers.tf
433+ git add terraform/environments/qa/
434+ git commit -m "terraform(qa): deploy Helm components"
435+ git push origin terraform/deploy-qa-helm
436+ # Create PR > Merge
437+ ```
355438
356439#### 6. Configure Branch Protection
357440
@@ -363,7 +446,7 @@ To create new environments (qa, prod), copy `dev/` and adjust configuration (see
363446
364447This ensures all changes go through PR review and automated checks (Terraform plan, CI builds, Helm validation).
365448
366- #### 7. Verify Infrastructure & Access ArgoCD
449+ #### 7. Verify Infrastructure
367450
368451After infrastructure deployment completes (Step 5), Terraform automatically installs via Helm:
369452
@@ -388,34 +471,7 @@ kubectl get pods -n ingress-nginx
388471kubectl get pods -n monitoring
389472```
390473
391- **Access ArgoCD UI**:
392-
393- ```bash
394- # Get ArgoCD LoadBalancer URL
395- kubectl get svc argocd-server -n argocd -o jsonpath=' {.status.loadBalancer.ingress[0].hostname}'
396-
397- # Get initial admin password
398- kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 -d
399-
400- # Login via browser: http://<LoadBalancer-URL>
401- # Username: admin
402- # Password: <password-from-above>
403- ```
404-
405- **Deploy ArgoCD Application for microservices**:
406-
407- ```bash
408- # Apply ArgoCD Application manifest
409- kubectl apply -f argocd/dev/microservices-demo-dev.yaml -n argocd
410-
411- # Verify Application is created
412- kubectl get applications -n argocd
413-
414- # Check sync status in ArgoCD UI or CLI
415- argocd app get microservices-demo-dev
416- ```
417-
418- ArgoCD will automatically sync the Helm chart from `helm/` directory using environment-specific values (`values-dev.yaml`).
474+ **Note**: For accessing ArgoCD UI, Grafana, and other services, see [Step 9: Access Deployed Services](#9-access-deployed-services).
419475
420476#### 8. First Application Build & Deployment
421477
@@ -461,15 +517,88 @@ kubectl get pods -n dev
461517
462518# Check services
463519kubectl get svc -n dev
520+ ```
521+
522+ #### 9. Access Deployed Services
523+
524+ After successful deployment, you can access the following services:
525+
526+ ##### Frontend (Microservices Application)
464527
465- # Get frontend LoadBalancer URL
466- kubectl get svc frontend -n dev -o jsonpath=' {.status.loadBalancer.ingress[0].hostname}'
528+ ```bash
529+ # Get frontend Ingress URL
530+ kubectl get ingress -n dev
531+
532+ # Output example:
533+ # NAME CLASS HOSTS ADDRESS PORTS AGE
534+ # frontend nginx * a1234567890abcdef.eu-west-1.elb.amazonaws.com 80 5m
535+
536+ # Access in browser using the ADDRESS column
537+ # http://<ADDRESS-from-above>
467538
468- # Or use port -forward for testing
539+ # Alternative: Port -forward for testing
469540kubectl port-forward -n dev svc/frontend 8080:8080
470541# Access: http://localhost:8080
471542```
472543
544+ ##### ArgoCD UI
545+
546+ ```bash
547+ # Get ArgoCD LoadBalancer URL
548+ kubectl get svc -n argocd
549+
550+ # Look for argocd-server with type LoadBalancer and EXTERNAL-IP
551+ # Access: http://<EXTERNAL-IP>
552+
553+ # Get initial admin password (base64 decode)
554+ kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 -d
555+ echo # Print newline
556+
557+ # Login credentials:
558+ # Username: admin
559+ # Password: [output from above command]
560+ ```
561+
562+ **Deploy your application in ArgoCD**:
563+
564+ After accessing ArgoCD UI, create the Application:
565+
566+ ```bash
567+ # Apply ArgoCD Application manifest for dev environment
568+ kubectl apply -f argocd/dev/microservices-demo-dev.yaml -n argocd
569+
570+ # Verify Application is created
571+ kubectl get applications -n argocd
572+
573+ # In ArgoCD UI you should see "microservices-demo-dev" application
574+ # Click on it to see all microservices being synced
575+ ```
576+
577+ The ArgoCD Application will automatically sync the Helm chart from `helm/` directory using environment-specific values (`values-dev.yaml`).
578+
579+ ##### Grafana (Monitoring Dashboard)
580+
581+ ```bash
582+ # Get Grafana LoadBalancer URL
583+ kubectl get svc -n monitoring
584+
585+ # Look for kube-prometheus-stack-grafana with type LoadBalancer and EXTERNAL-IP
586+ # Access: http://<EXTERNAL-IP>
587+
588+ # Login credentials:
589+ # Username: admin
590+ # Password: admin123
591+ # (password is hardcoded in terraform/environments/dev/helm.tf)
592+ ```
593+
594+ **Pre-configured Dashboards**:
595+ - Kubernetes Cluster Monitoring
596+ - Pod Metrics
597+ - Node Exporter
598+ - Prometheus Stats
599+
600+ **Note**: LoadBalancer EXTERNAL-IP may take 2-3 minutes to provision after deployment. If you see `<pending>`, wait and retry.
601+
473602## Local Testing
474603
475604Test all microservices locally before pushing to AWS using Docker Compose.
0 commit comments