Skip to content

Commit f8abfb2

Browse files
authored
Merge branch 'main' into feature/wfprev-469
2 parents ce298f5 + e0e4e2f commit f8abfb2

File tree

14 files changed

+220
-16
lines changed

14 files changed

+220
-16
lines changed

.github/workflows/client-build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ jobs:
6262
OPENMAPS_URL: ${{ vars.OPENMAPS_URL }}
6363
WEBADE_OAUTH2_CHECK_AUTHORIZE_URL: ${{ vars.WEBADE_OAUTH2_CHECK_AUTHORIZE_URL }}
6464
WFPREV_CHECK_TOKEN_URL: ${{ vars.WFPREV_CHECK_TOKEN_URL }}
65+
TARGET_ENV: ${{ inputs.DEFAULT_APPLICATION_ENVIRONMENT }}
6566

6667
- name: Set up Node.js
6768
uses: actions/setup-node@v4

.github/workflows/terragrunt-deploy.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ jobs:
134134

135135
- uses: peter-murray/terragrunt-github-action@v1.0.0
136136
with:
137-
terragrunt_version: ${{ env.TG_VERSION }}
137+
terragrunt_version: ${{ env.TG_VERSION }}
138138

139139
- name: Terragrunt Apply
140140
working-directory: ${{env.TG_SRC_PATH}}
@@ -179,6 +179,9 @@ jobs:
179179
# GDB Extractor Lambda Image
180180
WFPREV_GDB_EXTRACTOR_DIGEST: ${{ steps.getDigestGDB.outputs.GDB_EXTRACTOR_IMAGE }}
181181

182+
# AWS
183+
AWS_ALERT_EMAIL_LIST: ${{ vars.AWS_ALERT_EMAIL_LIST }}
184+
182185
#liquibase
183186
COMMAND: ${{ steps.liquibaseCommand.outputs.LIQUIBASE_COMMAND }}
184187
PROXY_COUNT: ${{ steps.changeLogCount.outputs.PROXY_COUNT }}

client/wfprev-war/src/main/angular/src/app/components/shared-layout/app-header/app-header.component.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ describe('AppHeaderComponent', () => {
2121
enableLocalStorageToken: true,
2222
localStorageTokenKey: 'test-oauth',
2323
allowLocalExpiredToken: false,
24-
baseUrl: 'http://test.com'
24+
baseUrl: 'http://test.com',
25+
environment: 'DEV'
2526
},
2627
webade: {
2728
oauth2Url: 'http://oauth.test',

client/wfprev-war/src/main/angular/src/app/components/shared-layout/app-header/app-header.component.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { MatButtonModule } from '@angular/material/button';
66
import { MatIconModule } from '@angular/material/icon';
77
import { CommonModule } from '@angular/common';
88
import { TokenService } from 'src/app/services/token.service';
9+
import { AppConfigService } from 'src/app/services/app-config.service';
910

1011
@Component({
1112
selector: 'wfprev-app-header',
@@ -19,17 +20,17 @@ import { TokenService } from 'src/app/services/token.service';
1920
templateUrl: './app-header.component.html',
2021
styleUrls: ['./app-header.component.scss']
2122
})
22-
export class AppHeaderComponent implements OnInit{
23+
export class AppHeaderComponent implements OnInit {
2324

2425
constructor(
2526
protected router: Router,
26-
private readonly tokenService: TokenService
27+
private readonly tokenService: TokenService,
28+
private readonly appConfigService: AppConfigService
2729
) {
2830
}
2931

30-
31-
environment:string = 'DEV'
32-
title:string = 'PREVENTION'
32+
environment: string = ''
33+
title: string = 'PREVENTION'
3334
currentUser: string = 'User_1'
3435

3536
ngOnInit(): void {
@@ -39,11 +40,16 @@ export class AppHeaderComponent implements OnInit{
3940
this.currentUser = name;
4041
}
4142
});
43+
44+
// Display no environment indicator in prod
45+
// Case sensitive checking, set the variable as upper case
46+
const env = (this.appConfigService.getConfig()?.application?.environment || '').toUpperCase();
47+
this.environment = env === 'PROD' ? '' : env;
4248
}
4349

4450

45-
onBCLogoClick(){
46-
this.router.navigate([ResourcesRoutes.LANDING]); // Navigate back to the home page
51+
onBCLogoClick() {
52+
this.router.navigate([ResourcesRoutes.LANDING]); // Navigate back to the home page
4753
}
4854

4955
onSupportLinkClick() {

client/wfprev-war/src/main/angular/src/assets/data/appConfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"application": {
3-
"baseUrl": "#{WFPREV_BASE_URL}#"
3+
"baseUrl": "#{WFPREV_BASE_URL}#",
4+
"environment": "#{TARGET_ENV}"
45
},
56

67
"webade": {

client/wfprev-war/src/main/angular/src/assets/data/appConfig.local.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"application": {
3-
"baseUrl": "http://localhost:4200/"
3+
"baseUrl": "http://localhost:4200/",
4+
"environment": "local"
45
},
56

67
"webade": {

terraform/alarms.tf

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
resource "aws_cloudwatch_metric_alarm" "high_latency" {
2+
alarm_name = "ALB-High-Latency"
3+
comparison_operator = "GreaterThanThreshold"
4+
evaluation_periods = 1
5+
metric_name = "TargetResponseTime"
6+
namespace = "AWS/ApplicationELB"
7+
period = 60 # 1 min
8+
statistic = "Average"
9+
threshold = 1 # 1 second
10+
11+
dimensions = {
12+
LoadBalancer = aws_lb.wfprev_main.arn_suffix
13+
}
14+
15+
alarm_description = "ALB target response time is high"
16+
alarm_actions = [aws_sns_topic.alb_alerts.arn]
17+
}
18+
19+
resource "aws_cloudwatch_metric_alarm" "unhealthy_targets" {
20+
alarm_name = "ALB-Unhealthy-Targets"
21+
comparison_operator = "GreaterThanThreshold"
22+
evaluation_periods = 1
23+
metric_name = "UnHealthyHostCount"
24+
namespace = "AWS/ApplicationELB"
25+
period = 60
26+
statistic = "Average"
27+
threshold = 0
28+
29+
dimensions = {
30+
TargetGroup = aws_alb_target_group.wfprev_api.arn_suffix
31+
LoadBalancer = aws_lb.wfprev_main.arn_suffix
32+
}
33+
34+
alarm_description = "ALB has unhealthy targets"
35+
alarm_actions = [aws_sns_topic.alb_alerts.arn]
36+
}
37+
38+
resource "aws_sns_topic" "alb_alerts" {
39+
name = "wfprev-alb-alerts"
40+
}
41+
42+
# List of emails
43+
locals {
44+
alert_emails = split(",", var.AWS_ALERT_EMAIL_LIST)
45+
}
46+
47+
# Create subscriptions for each email
48+
resource "aws_sns_topic_subscription" "alb_alerts_emails" {
49+
for_each = toset(local.alert_emails)
50+
51+
topic_arn = aws_sns_topic.alb_alerts.arn
52+
protocol = "email"
53+
endpoint = trim(each.key, " ")
54+
}

terraform/alb.tf

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ resource "aws_lb" "wfprev_main" {
3434
Environment = "${var.TARGET_ENV}"
3535
}
3636

37+
access_logs {
38+
bucket = aws_s3_bucket.alb_logs.bucket
39+
prefix = "wfprev-${var.TARGET_ENV}"
40+
enabled = true
41+
}
42+
3743
}
3844

3945
//////////////////////////
@@ -45,10 +51,27 @@ resource "aws_lb_listener" "wfprev_main" {
4551
protocol = "HTTP"
4652

4753
default_action {
48-
type = "fixed-response"
54+
type = "redirect"
55+
redirect {
56+
port = "443"
57+
protocol = "HTTPS"
58+
status_code = "HTTP_301" # Any HTTP request gets a 301 redirect to HTTPS
59+
}
60+
}
61+
}
62+
63+
resource "aws_lb_listener" "wfprev_main_https" {
64+
load_balancer_arn = aws_lb.wfprev_main.arn
65+
port = "443"
66+
protocol = "HTTPS"
67+
ssl_policy = "ELBSecurityPolicy-2016-08"
68+
certificate_arn = aws_acm_certificate_validation.domain_certificate_validation_ca.certificate_arn
69+
70+
default_action {
71+
type = "fixed-response"
4972
fixed_response {
5073
content_type = "text/plain"
51-
status_code = 404
74+
status_code = 404
5275
}
5376
}
5477
}
@@ -81,14 +104,22 @@ resource "aws_alb_target_group" "wfprev_api" {
81104
target_type = "ip"
82105
deregistration_delay = 30
83106

107+
stickiness {
108+
enabled = true
109+
type = "lb_cookie"
110+
cookie_duration = 3600 # 1 hour session persistence
111+
}
112+
84113
health_check {
85114
healthy_threshold = "2"
86-
interval = "300"
115+
interval = "30"
87116
protocol = "HTTP"
88117
matcher = "200"
89-
timeout = "3"
118+
timeout = "5"
90119
path = "/${aws_apigatewayv2_stage.wfprev_stage.name}/actuator/health"
91120
unhealthy_threshold = "2"
92121
}
93122
}
94123

124+
125+

terraform/certificate_manager.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,20 @@ resource "aws_acm_certificate_validation" "domain_certificate_validation" {
1616

1717
provider = aws.aws-us
1818
}
19+
20+
//NOTE: CA certificate is needed for ALB listener
21+
resource "aws_acm_certificate" "wfprev_domain_certificate_ca" {
22+
domain_name = data.aws_route53_zone.wfprev_route53_zone.name
23+
validation_method = "DNS"
24+
25+
lifecycle {
26+
create_before_destroy = true
27+
}
28+
29+
provider = aws # The default provider (ca-central-1)
30+
}
31+
32+
resource "aws_acm_certificate_validation" "domain_certificate_validation_ca" {
33+
certificate_arn = aws_acm_certificate.wfprev_domain_certificate_ca.arn
34+
validation_record_fqdns = [for record in aws_route53_record.cert_validation_record_ca : record.fqdn]
35+
}

terraform/cloudfront.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ resource "aws_cloudfront_distribution" "wfprev_app_distribution" {
107107
restriction_type = "none"
108108
}
109109
}
110+
111+
logging_config {
112+
bucket = data.aws_s3_bucket.cloudfront_logs.bucket_domain_name
113+
include_cookies = false
114+
prefix = "cloudfront-logs/"
115+
}
110116
}
111117

112118
resource "aws_cloudfront_function" "rewrite_uri" {
@@ -123,6 +129,10 @@ resource "aws_cloudfront_function" "rewrite_uri" {
123129
EOF
124130
}
125131

132+
data "aws_s3_bucket" "cloudfront_logs" {
133+
bucket = "wfprev-${var.TARGET_ENV}-cloudfront-logs"
134+
}
135+
126136
output "cloudfront_distribution_id" {
127137
value = aws_cloudfront_distribution.wfprev_app_distribution.id
128138
}

0 commit comments

Comments
 (0)