diff --git a/infrastructure/stacks/api-layer/csoc_log_forwarding.tf b/infrastructure/stacks/api-layer/csoc_log_forwarding.tf index 8fb7246c0..391cf5681 100644 --- a/infrastructure/stacks/api-layer/csoc_log_forwarding.tf +++ b/infrastructure/stacks/api-layer/csoc_log_forwarding.tf @@ -22,6 +22,12 @@ data "aws_iam_policy_document" "cwl_subscription_assume_role" { variable = "aws:SourceAccount" values = [data.aws_caller_identity.current.account_id] } + + condition { + test = "StringLike" + variable = "aws:SourceArn" + values = ["arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:*"] + } } } @@ -74,6 +80,17 @@ resource "aws_iam_role_policy_attachment" "cwl_to_csoc_destination" { policy_arn = aws_iam_policy.cwl_to_csoc_destination.arn } +# Wait for IAM role to propagate across AWS +# This prevents "Make sure you have given CloudWatch Logs permission to assume the provided role" errors +resource "time_sleep" "wait_for_iam_propagation" { + depends_on = [ + aws_iam_role.cwl_subscription_role, + aws_iam_role_policy_attachment.cwl_to_csoc_destination + ] + + create_duration = "10s" +} + # Create the subscription filter to forward logs to CSOC # This forwards all logs from the existing API Gateway log group to the CSOC destination # Note: A log group can have up to 2 subscription filters @@ -87,6 +104,6 @@ resource "aws_cloudwatch_log_subscription_filter" "csoc_forwarding" { depends_on = [ module.eligibility_signposting_api_gateway, aws_iam_role.cwl_subscription_role, - aws_iam_role_policy_attachment.cwl_to_csoc_destination + time_sleep.wait_for_iam_propagation ] } diff --git a/infrastructure/stacks/iams-developer-roles/github_actions_policies.tf b/infrastructure/stacks/iams-developer-roles/github_actions_policies.tf index 1402e99e2..dec843f42 100644 --- a/infrastructure/stacks/iams-developer-roles/github_actions_policies.tf +++ b/infrastructure/stacks/iams-developer-roles/github_actions_policies.tf @@ -326,6 +326,7 @@ resource "aws_iam_policy" "api_infrastructure" { "ec2:CreateTags", "ec2:DeleteTags", "ec2:CreateNetworkAclEntry", + "ec2:DeleteNetworkAclEntry", "ec2:CreateNetworkAcl", "ec2:AssociateRouteTable", "ec2:CreateVpc", @@ -343,6 +344,7 @@ resource "aws_iam_policy" "api_infrastructure" { "ec2:ReplaceNetworkAclAssociation", "ec2:DeleteSecurityGroup", "ec2:DeleteNetworkAcl", + "ec2:UpdateSecurityGroupRuleDescriptionsEgress", # ssm "ssm:GetParameter", diff --git a/infrastructure/stacks/iams-developer-roles/iams_permissions_boundary.tf b/infrastructure/stacks/iams-developer-roles/iams_permissions_boundary.tf index ece136c9c..9c49ea32b 100644 --- a/infrastructure/stacks/iams-developer-roles/iams_permissions_boundary.tf +++ b/infrastructure/stacks/iams-developer-roles/iams_permissions_boundary.tf @@ -46,7 +46,9 @@ data "aws_iam_policy_document" "permissions_boundary" { "ec2:CreateTags", "ec2:DeleteTags", "ec2:CreateNetworkAclEntry", + "ec2:DeleteNetworkAclEntry", "ec2:CreateNetworkAcl", + "ec2:DeleteNetworkAcl", "ec2:AssociateRouteTable", "ec2:CreateVpc", "ec2:ModifyVpcAttribute", @@ -62,7 +64,7 @@ data "aws_iam_policy_document" "permissions_boundary" { "ec2:CreateFlowLogs", "ec2:ReplaceNetworkAclAssociation", "ec2:DeleteSecurityGroup", - "ec2:DeleteNetworkAcl", + "ec2:UpdateSecurityGroupRuleDescriptionsEgress", # EventBridge - alarm forwarding to Splunk "events:PutRule", diff --git a/infrastructure/stacks/networking/vpc.tf b/infrastructure/stacks/networking/vpc.tf index e88ce7894..c374b0173 100644 --- a/infrastructure/stacks/networking/vpc.tf +++ b/infrastructure/stacks/networking/vpc.tf @@ -1,5 +1,4 @@ resource "aws_vpc" "main" { - #checkov:skip=CKV2_AWS_11: "Ensure VPC flow logging is enabled in all VPCs" cidr_block = local.vpc_cidr_block enable_dns_support = true enable_dns_hostnames = true diff --git a/infrastructure/stacks/networking/vpc_endpoints.tf b/infrastructure/stacks/networking/vpc_endpoints.tf index 0e3fde0fa..965c95349 100644 --- a/infrastructure/stacks/networking/vpc_endpoints.tf +++ b/infrastructure/stacks/networking/vpc_endpoints.tf @@ -20,12 +20,34 @@ resource "aws_security_group_rule" "main_https_in" { } resource "aws_security_group_rule" "main_https_out" { - description = "Allow VPC Endpoint to access the actual AWS Service Endpoints" + description = "Allow HTTPS access to Interface VPC Endpoints within VPC" type = "egress" from_port = local.default_port to_port = local.default_port protocol = "tcp" - cidr_blocks = [local.any_ip_cidr] + cidr_blocks = [local.vpc_cidr_block] + security_group_id = aws_security_group.main.id +} + +# Allow egress to S3 via Gateway endpoint prefix list +resource "aws_security_group_rule" "main_s3_prefix_out" { + description = "Allow HTTPS access to S3 via Gateway endpoint" + type = "egress" + from_port = local.default_port + to_port = local.default_port + protocol = "tcp" + prefix_list_ids = [aws_vpc_endpoint.gateways["s3"].prefix_list_id] + security_group_id = aws_security_group.main.id +} + +# Allow egress to DynamoDB via Gateway endpoint prefix list +resource "aws_security_group_rule" "main_dynamodb_prefix_out" { + description = "Allow HTTPS access to DynamoDB via Gateway endpoint" + type = "egress" + from_port = local.default_port + to_port = local.default_port + protocol = "tcp" + prefix_list_ids = [aws_vpc_endpoint.gateways["dynamodb"].prefix_list_id] security_group_id = aws_security_group.main.id }