diff --git a/modules/perforce/helix-authentication-service/README.md b/modules/perforce/helix-authentication-service/README.md
index ceb36242..0c673e23 100644
--- a/modules/perforce/helix-authentication-service/README.md
+++ b/modules/perforce/helix-authentication-service/README.md
@@ -7,6 +7,7 @@
|------|---------|
| [terraform](#requirement\_terraform) | >= 1.0 |
| [aws](#requirement\_aws) | >= 5.30 |
+| [awscc](#requirement\_awscc) | >= 1.2.0 |
| [random](#requirement\_random) | >=3.6 |
## Providers
@@ -14,6 +15,7 @@
| Name | Version |
|------|---------|
| [aws](#provider\_aws) | >= 5.30 |
+| [awscc](#provider\_awscc) | >= 1.2.0 |
| [random](#provider\_random) | >=3.6 |
## Modules
@@ -30,6 +32,7 @@ No modules.
| [aws_ecs_service.HAS_service](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_service) | resource |
| [aws_ecs_task_definition.HAS_task_definition](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition) | resource |
| [aws_iam_policy.HAS_default_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
+| [aws_iam_policy.HAS_secrets_manager_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.HAS_default_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role.HAS_task_execution_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_lb.HAS_alb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb) | resource |
@@ -42,10 +45,13 @@ No modules.
| [aws_vpc_security_group_egress_rule.HAS_service_outbound_ipv4](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_egress_rule) | resource |
| [aws_vpc_security_group_egress_rule.HAS_service_outbound_ipv6](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_egress_rule) | resource |
| [aws_vpc_security_group_ingress_rule.HAS_service_inbound_alb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource |
+| [awscc_secretsmanager_secret.has_admin_password](https://registry.terraform.io/providers/hashicorp/awscc/latest/docs/resources/secretsmanager_secret) | resource |
+| [awscc_secretsmanager_secret.has_admin_username](https://registry.terraform.io/providers/hashicorp/awscc/latest/docs/resources/secretsmanager_secret) | resource |
| [random_string.HAS](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource |
| [random_string.HAS_alb_access_logs_bucket_suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource |
| [aws_ecs_cluster.HAS_cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecs_cluster) | data source |
| [aws_iam_policy_document.HAS_default_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+| [aws_iam_policy_document.HAS_secrets_manager_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.ecs_tasks_trust_relationship](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
@@ -74,6 +80,8 @@ No modules.
| [environment](#input\_environment) | The current environment (e.g. dev, prod, etc.) | `string` | `"dev"` | no |
| [existing\_security\_groups](#input\_existing\_security\_groups) | A list of existing security group IDs to attach to the Helix Authentication Service load balancer. | `list(string)` | `[]` | no |
| [fqdn](#input\_fqdn) | The fully qualified domain name of Helix Authentication Service. | `string` | `"localhost"` | no |
+| [has\_admin\_password\_secret\_arn](#input\_has\_admin\_password\_secret\_arn) | Optionally provide the ARN of an AWS Secret for the HAS Administrator password. | `string` | `null` | no |
+| [has\_admin\_username\_secret\_arn](#input\_has\_admin\_username\_secret\_arn) | Optionally provide the ARN of an AWS Secret for the HAS Administrator username. | `string` | `null` | no |
| [internal](#input\_internal) | Set this flag to true if you do not want the Helix Authentication Service load balancer to have a public IP. | `bool` | `false` | no |
| [name](#input\_name) | The name attached to HAS module resources. | `string` | `"HAS"` | no |
| [project\_prefix](#input\_project\_prefix) | The project prefix for this workload. This is appeneded to the beginning of most resource names. | `string` | `"cgd"` | no |
diff --git a/modules/perforce/helix-authentication-service/iam.tf b/modules/perforce/helix-authentication-service/iam.tf
index fb35cdcc..b0ba35f6 100644
--- a/modules/perforce/helix-authentication-service/iam.tf
+++ b/modules/perforce/helix-authentication-service/iam.tf
@@ -37,8 +37,24 @@ data "aws_iam_policy_document" "HAS_default_policy" {
"*"
]
}
+ statement {
+ effect = "Allow"
+ actions = [
+ "secretsmanager:ListSecrets",
+ "secretsmanager:ListSecretVersionIds",
+ "secretsmanager:GetRandomPassword",
+ "secretsmanager:GetSecretValue",
+ "secretsmanager:DescribeSecret",
+ "secretsmanager:BatchGetSecretValue"
+ ]
+ resources = [
+ var.has_admin_username_secret_arn == null ? awscc_secretsmanager_secret.has_admin_username[0].secret_id : var.has_admin_username_secret_arn,
+ var.has_admin_password_secret_arn == null ? awscc_secretsmanager_secret.has_admin_password[0].secret_id : var.has_admin_password_secret_arn,
+ ]
+ }
}
+
resource "aws_iam_policy" "HAS_default_policy" {
count = var.create_HAS_default_policy ? 1 : 0
@@ -47,6 +63,8 @@ resource "aws_iam_policy" "HAS_default_policy" {
policy = data.aws_iam_policy_document.HAS_default_policy[0].json
}
+
+
# - Roles -
# HAS
resource "aws_iam_role" "HAS_default_role" {
@@ -61,9 +79,33 @@ resource "aws_iam_role" "HAS_default_role" {
tags = local.tags
}
+data "aws_iam_policy_document" "HAS_secrets_manager_policy" {
+ statement {
+ effect = "Allow"
+ actions = [
+ "secretsmanager:ListSecrets",
+ "secretsmanager:ListSecretVersionIds",
+ "secretsmanager:GetRandomPassword",
+ "secretsmanager:GetSecretValue",
+ "secretsmanager:DescribeSecret",
+ "secretsmanager:BatchGetSecretValue"
+ ]
+ resources = [
+ var.has_admin_username_secret_arn == null ? awscc_secretsmanager_secret.has_admin_username[0].secret_id : var.has_admin_username_secret_arn,
+ var.has_admin_password_secret_arn == null ? awscc_secretsmanager_secret.has_admin_password[0].secret_id : var.has_admin_password_secret_arn,
+ ]
+ }
+}
+
+resource "aws_iam_policy" "HAS_secrets_manager_policy" {
+ name = "${var.project_prefix}-HAS-secrets-manager-policy"
+ description = "Policy granting permissions for HAS task execution role to access SSM."
+ policy = data.aws_iam_policy_document.HAS_secrets_manager_policy.json
+}
+
resource "aws_iam_role" "HAS_task_execution_role" {
name = "${var.project_prefix}-HAS-task-execution-role"
assume_role_policy = data.aws_iam_policy_document.ecs_tasks_trust_relationship.json
- managed_policy_arns = ["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"]
+ managed_policy_arns = ["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy", aws_iam_policy.HAS_secrets_manager_policy.arn]
}
diff --git a/modules/perforce/helix-authentication-service/main.tf b/modules/perforce/helix-authentication-service/main.tf
index a4893695..0cf9a515 100644
--- a/modules/perforce/helix-authentication-service/main.tf
+++ b/modules/perforce/helix-authentication-service/main.tf
@@ -25,6 +25,24 @@ resource "aws_ecs_cluster_capacity_providers" "HAS_cluster_fargate_rpvodiers" {
}
}
+resource "awscc_secretsmanager_secret" "has_admin_password" {
+ count = var.has_admin_password_secret_arn == null && var.enable_web_based_administration == true ? 1 : 0
+ name = "hasAdminUserPassword"
+ description = "The password for the created HAS administrator."
+ generate_secret_string = {
+ exclude_numbers = false
+ exclude_punctuation = true
+ include_space = false
+ }
+}
+
+resource "awscc_secretsmanager_secret" "has_admin_username" {
+ count = var.has_admin_username_secret_arn == null && var.enable_web_based_administration == true ? 1 : 0
+ name = "hasAdminUsername"
+ secret_string = "perforce"
+}
+
+
resource "aws_cloudwatch_log_group" "HAS_service_log_group" {
#checkov:skip=CKV_AWS_158: KMS Encryption disabled by default
name = "${local.name_prefix}-log-group"
@@ -40,6 +58,10 @@ resource "aws_ecs_task_definition" "HAS_task_definition" {
cpu = var.container_cpu
memory = var.container_memory
+ volume {
+ name = "helix-auth-config"
+ }
+
container_definitions = jsonencode([
{
name = var.container_name,
@@ -54,7 +76,7 @@ resource "aws_ecs_task_definition" "HAS_task_definition" {
protocol = "tcp"
}
]
- environment = [
+ environment = concat([
{
name = "SVC_BASE_URL"
value = var.fqdn
@@ -62,9 +84,16 @@ resource "aws_ecs_task_definition" "HAS_task_definition" {
{
name = "ADMIN_ENABLED"
value = var.enable_web_based_administration ? "true" : "false"
- }
- ]
+ },
+ ],
+ var.enable_web_based_administration ? [
+ {
+ name = "ADMIN_PASSWD_FILE",
+ value = "/var/has/password.txt"
+ }
+ ] : []
+ )
logConfiguration = {
logDriver = "awslogs"
options = {
@@ -73,8 +102,49 @@ resource "aws_ecs_task_definition" "HAS_task_definition" {
awslogs-stream-prefix = "HAS"
}
}
-
- readonlyRootFilesystem = false
+ mountPoints = [
+ {
+ sourceVolume = "helix-auth-config"
+ containerPath = "/var/has"
+ }
+ ],
+ dependsOn = [
+ {
+ containerName = "has-config"
+ condition = "COMPLETE"
+ }
+ ]
+ },
+ {
+ name = "has-config"
+ image = "bash"
+ essential = false
+ command = ["sh", "-c", "echo $ADMIN_PASSWD | tee /var/has/password.txt"]
+ readonly_root_filesystem = false
+ secrets = var.enable_web_based_administration ? [
+ {
+ name = "ADMIN_USERNAME"
+ valueFrom = var.has_admin_username_secret_arn != null ? var.has_admin_username_secret_arn : awscc_secretsmanager_secret.has_admin_username[0].secret_id
+ },
+ {
+ name = "ADMIN_PASSWD"
+ valueFrom = var.has_admin_password_secret_arn != null ? var.has_admin_username_secret_arn : awscc_secretsmanager_secret.has_admin_password[0].secret_id
+ },
+ ] : [],
+ logConfiguration = {
+ logDriver = "awslogs"
+ options = {
+ awslogs-group = aws_cloudwatch_log_group.HAS_service_log_group.name
+ awslogs-region = data.aws_region.current.name
+ awslogs-stream-prefix = "HAS-config"
+ }
+ }
+ mountPoints = [
+ {
+ sourceVolume = "helix-auth-config"
+ containerPath = "/var/has"
+ }
+ ],
}
])
@@ -99,6 +169,8 @@ resource "aws_ecs_service" "HAS_service" {
desired_count = var.desired_container_count
force_new_deployment = true
+ enable_execute_command = true
+
load_balancer {
target_group_arn = aws_lb_target_group.HAS_alb_target_group.arn
container_name = var.container_name
diff --git a/modules/perforce/helix-authentication-service/variables.tf b/modules/perforce/helix-authentication-service/variables.tf
index a8f68e49..dc28e612 100644
--- a/modules/perforce/helix-authentication-service/variables.tf
+++ b/modules/perforce/helix-authentication-service/variables.tf
@@ -182,3 +182,15 @@ variable "create_HAS_default_policy" {
description = "Optional creation of Helix Authentication Service default IAM Policy. Default is set to true."
default = true
}
+
+variable "has_admin_username_secret_arn" {
+ type = string
+ description = "Optionally provide the ARN of an AWS Secret for the HAS Administrator username."
+ default = null
+}
+
+variable "has_admin_password_secret_arn" {
+ type = string
+ description = "Optionally provide the ARN of an AWS Secret for the HAS Administrator password."
+ default = null
+}
diff --git a/modules/perforce/helix-authentication-service/versions.tf b/modules/perforce/helix-authentication-service/versions.tf
index 27b25203..6e6672b3 100644
--- a/modules/perforce/helix-authentication-service/versions.tf
+++ b/modules/perforce/helix-authentication-service/versions.tf
@@ -6,6 +6,10 @@ terraform {
source = "hashicorp/aws"
version = ">= 5.30"
}
+ awscc = {
+ source = "hashicorp/awscc"
+ version = ">= 1.2.0"
+ }
random = {
source = "hashicorp/random"
version = ">=3.6"