Skip to content

Commit ef40a6d

Browse files
authored
Merge pull request #1 from SPHTech-Platform/setup-aws-verified-module
[PFMENG-1278] Setup AWS Verified Access Terraform module
2 parents a371425 + 4ca75c1 commit ef40a6d

File tree

15 files changed

+571
-0
lines changed

15 files changed

+571
-0
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2022-present SPH Media
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,51 @@
11
# Terraform Modules Template
2+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
3+
## Requirements
4+
5+
| Name | Version |
6+
|------|---------|
7+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3 |
8+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.24 |
9+
10+
## Providers
11+
12+
| Name | Version |
13+
|------|---------|
14+
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.24.0 |
15+
16+
## Modules
17+
18+
No modules.
19+
20+
## Resources
21+
22+
| Name | Type |
23+
|------|------|
24+
| [aws_verifiedaccess_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/verifiedaccess_group) | resource |
25+
| [aws_verifiedaccess_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/verifiedaccess_instance) | resource |
26+
| [aws_verifiedaccess_instance_trust_provider_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/verifiedaccess_instance_trust_provider_attachment) | resource |
27+
| [aws_verifiedaccess_trust_provider.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/verifiedaccess_trust_provider) | resource |
28+
29+
## Inputs
30+
31+
| Name | Description | Type | Default | Required |
32+
|------|-------------|------|---------|:--------:|
33+
| <a name="input_authorization_endpoint"></a> [authorization\_endpoint](#input\_authorization\_endpoint) | The OIDC authorization endpoint. | `string` | `null` | no |
34+
| <a name="input_client_id"></a> [client\_id](#input\_client\_id) | The client identifier. | `string` | `null` | no |
35+
| <a name="input_client_secret"></a> [client\_secret](#input\_client\_secret) | The client secret. | `string` | `null` | no |
36+
| <a name="input_group_policy_document"></a> [group\_policy\_document](#input\_group\_policy\_document) | he policy document that is associated with this resource. | `string` | `null` | no |
37+
| <a name="input_issuer"></a> [issuer](#input\_issuer) | The OIDC issuer. | `string` | `null` | no |
38+
| <a name="input_policy_reference_name"></a> [policy\_reference\_name](#input\_policy\_reference\_name) | The type of trust provider can be either user or device-based. | `string` | n/a | yes |
39+
| <a name="input_scope"></a> [scope](#input\_scope) | OpenID Connect (OIDC) scopes are used by an application during authentication to authorize access to details of a user. | `string` | `null` | no |
40+
| <a name="input_tags"></a> [tags](#input\_tags) | Key-value mapping of resource tags. | `map(string)` | `{}` | no |
41+
| <a name="input_token_endpoint"></a> [token\_endpoint](#input\_token\_endpoint) | The OIDC token endpoint. | `string` | `null` | no |
42+
| <a name="input_trust_provider_type"></a> [trust\_provider\_type](#input\_trust\_provider\_type) | The type of trust provider can be either user or device-based. | `string` | n/a | yes |
43+
| <a name="input_user_info_endpoint"></a> [user\_info\_endpoint](#input\_user\_info\_endpoint) | The OIDC user info endpoint. | `string` | `null` | no |
44+
| <a name="input_user_trust_provider_type"></a> [user\_trust\_provider\_type](#input\_user\_trust\_provider\_type) | The type of user-based trust provider. | `string` | `"iam-identity-center"` | no |
45+
46+
## Outputs
47+
48+
| Name | Description |
49+
|------|-------------|
50+
| <a name="output_verifiedaccess_group_id"></a> [verifiedaccess\_group\_id](#output\_verifiedaccess\_group\_id) | The ID of the Verified Access group to associate the endpoint with. |
51+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

examples/main.tf

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#Setup AWS Verified Access with IAM Identity Center provider
2+
module "verified_access_iam_identity_center" {
3+
source = "../"
4+
5+
policy_reference_name = "IAM"
6+
trust_provider_type = "user"
7+
user_trust_provider_type = "iam-identity-center"
8+
9+
group_policy_document = <<EOT
10+
permit(principal, action, resource)
11+
when {
12+
context.IAM.user.email.address like "*@abc.com"
13+
};
14+
EOT
15+
16+
tags = {
17+
Name = "IAM-Identity-Center"
18+
}
19+
}
20+
21+
#Setup AWS Verified Access with OIDC provider
22+
module "verified_access_oidc" {
23+
source = "../"
24+
25+
policy_reference_name = "OKTA"
26+
trust_provider_type = "user"
27+
user_trust_provider_type = "oidc"
28+
29+
authorization_endpoint = "https://dev-12345678.okta.com/oauth2/v1/authorize"
30+
client_id = "test-client-id"
31+
client_secret = "sdfdf333000000"
32+
issuer = "https://dev-12345678.okta.com"
33+
scope = "openid profile groups"
34+
token_endpoint = "https://dev-12345678.okta.com/oauth2/v1/token"
35+
user_info_endpoint = "https://dev-12345678.okta.com/oauth2/v1/userinfo"
36+
37+
group_policy_document = <<EOT
38+
permit(principal, action, resource)
39+
when {
40+
context.http_request.http_method != "INVALID_METHOD"
41+
};
42+
EOT
43+
44+
tags = {
45+
Name = "OIDC"
46+
}
47+
}
48+
49+
#AWS Verified Access Endpoints
50+
51+
#Network Interface Endpoint Type
52+
module "verified_access_eni_endpoint" {
53+
source = "../modules/endpoint"
54+
55+
verified_access_group_id = module.verified_access_iam_identity_center.verifiedaccess_group_id
56+
57+
description = "example"
58+
application_domain = "example.my-domain.com"
59+
domain_certificate_arn = module.acm.acm_certificate_arn
60+
endpoint_domain_prefix = "example"
61+
security_group_ids = [module.verified_access_sg.security_group_id]
62+
63+
endpoint_type = "network-interface"
64+
network_interface_id = "eni-xys3d2c29ad06"
65+
port = 443
66+
protocol = "https"
67+
68+
tags = {
69+
Name = "User manager endpoint"
70+
}
71+
}
72+
73+
#Internal Load Balancer Endpoint Type
74+
module "verified_access_elb_endpoint" {
75+
source = "../modules/endpoint"
76+
77+
verified_access_group_id = module.verified_access_oidc.verifiedaccess_group_id
78+
79+
description = "student-portal"
80+
81+
application_domain = "example.my-domain.com"
82+
domain_certificate_arn = module.acm.acm_certificate_arn
83+
endpoint_domain_prefix = "example"
84+
security_group_ids = [module.verified_access_sg.security_group_id]
85+
86+
endpoint_type = "load-balancer"
87+
load_balancer_arn = module.alb.arn
88+
port = 443
89+
protocol = "https"
90+
subnet_ids = module.vpc.private_subnets
91+
92+
tags = {
93+
Name = "student-portal"
94+
}
95+
}
96+
97+
module "vpc" {
98+
source = "terraform-aws-modules/vpc/aws"
99+
version = "~> 5.1"
100+
101+
name = "test-vpc"
102+
cidr = "10.0.0.0/16"
103+
104+
azs = ["ap-southeast-1a", "ap-southeast-1b", "ap-southeast-1c"]
105+
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
106+
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
107+
108+
enable_nat_gateway = true
109+
enable_vpn_gateway = true
110+
111+
tags = {
112+
Terraform = "true"
113+
Environment = "dev"
114+
}
115+
}
116+
117+
module "verified_access_sg" {
118+
source = "terraform-aws-modules/security-group/aws"
119+
version = "~> 5.1"
120+
121+
name = "verified-access-sg"
122+
vpc_id = module.vpc.vpc_id
123+
124+
ingress_cidr_blocks = ["0.0.0.0/0"]
125+
126+
ingress_rules = [
127+
"https-443-tcp"
128+
]
129+
130+
egress_rules = ["all-all"]
131+
}
132+
133+
module "acm" {
134+
source = "terraform-aws-modules/acm/aws"
135+
version = "~> 4.0"
136+
137+
domain_name = "my-domain.com"
138+
zone_id = "xyz1234B9AZ6SHAE"
139+
140+
validation_method = "DNS"
141+
142+
subject_alternative_names = [
143+
"*.my-domain.com"
144+
]
145+
146+
wait_for_validation = true
147+
148+
tags = {
149+
Name = "my-domain.com"
150+
}
151+
}
152+
153+
module "alb" {
154+
source = "terraform-aws-modules/alb/aws"
155+
version = "~> 9.1"
156+
157+
name = "my-alb"
158+
vpc_id = module.vpc.vpc_id
159+
subnets = module.vpc.private_subnets
160+
internal = true
161+
162+
# Allow traffic from Verified Access security group
163+
security_groups = [module.verified_access_sg.security_group_id]
164+
165+
listeners = {
166+
https = {
167+
port = 443
168+
protocol = "HTTPS"
169+
certificate_arn = module.acm.acm_certificate_arn
170+
forward = {
171+
target_group_key = "ex-instance"
172+
}
173+
}
174+
}
175+
176+
tags = {
177+
Environment = "Development"
178+
Project = "Example"
179+
}
180+
}

examples/providers.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
provider "aws" {
2+
region = "ap-southeast-1"
3+
}

examples/versions.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
terraform {
2+
required_version = ">= 1.3"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = "~> 5.24"
8+
}
9+
}
10+
}

main.tf

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
resource "aws_verifiedaccess_trust_provider" "this" {
2+
description = "${var.trust_provider_type} based trust provider"
3+
policy_reference_name = var.policy_reference_name
4+
trust_provider_type = var.trust_provider_type
5+
user_trust_provider_type = var.user_trust_provider_type
6+
7+
dynamic "oidc_options" {
8+
for_each = var.user_trust_provider_type == "oidc" ? [1] : []
9+
content {
10+
authorization_endpoint = var.authorization_endpoint
11+
client_id = var.client_id
12+
client_secret = var.client_secret
13+
issuer = var.issuer
14+
scope = var.scope
15+
token_endpoint = var.token_endpoint
16+
user_info_endpoint = var.user_info_endpoint
17+
}
18+
}
19+
20+
tags = var.tags
21+
}
22+
23+
resource "aws_verifiedaccess_instance" "this" {
24+
description = "Verified access instance"
25+
tags = var.tags
26+
}
27+
28+
resource "aws_verifiedaccess_instance_trust_provider_attachment" "this" {
29+
verifiedaccess_instance_id = aws_verifiedaccess_instance.this.id
30+
verifiedaccess_trust_provider_id = aws_verifiedaccess_trust_provider.this.id
31+
}
32+
33+
resource "aws_verifiedaccess_group" "this" {
34+
verifiedaccess_instance_id = aws_verifiedaccess_instance.this.id
35+
policy_document = var.group_policy_document != null ? var.group_policy_document : null
36+
tags = var.tags
37+
38+
# Must attach a TrustProvider to Instance before you can create a Group
39+
depends_on = [
40+
aws_verifiedaccess_instance_trust_provider_attachment.this
41+
]
42+
}

modules/.gitkeep

Whitespace-only changes.

modules/endpoint/README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
2+
## Requirements
3+
4+
| Name | Version |
5+
|------|---------|
6+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3 |
7+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.24 |
8+
9+
## Providers
10+
11+
| Name | Version |
12+
|------|---------|
13+
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.24.0 |
14+
15+
## Modules
16+
17+
No modules.
18+
19+
## Resources
20+
21+
| Name | Type |
22+
|------|------|
23+
| [aws_verifiedaccess_endpoint.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/verifiedaccess_endpoint) | resource |
24+
25+
## Inputs
26+
27+
| Name | Description | Type | Default | Required |
28+
|------|-------------|------|---------|:--------:|
29+
| <a name="input_application_domain"></a> [application\_domain](#input\_application\_domain) | The DNS name for users to reach your application. | `string` | n/a | yes |
30+
| <a name="input_attachment_type"></a> [attachment\_type](#input\_attachment\_type) | The type of attachment. Currently, only vpc is supported. | `string` | `"vpc"` | no |
31+
| <a name="input_description"></a> [description](#input\_description) | The description for verified application | `string` | `null` | no |
32+
| <a name="input_domain_certificate_arn"></a> [domain\_certificate\_arn](#input\_domain\_certificate\_arn) | The ARN of the public TLS/SSL certificate in AWS Certificate Manager to associate with the endpoint | `string` | n/a | yes |
33+
| <a name="input_endpoint_domain_prefix"></a> [endpoint\_domain\_prefix](#input\_endpoint\_domain\_prefix) | A custom identifier that is prepended to the DNS name that is generated for the endpoint | `string` | n/a | yes |
34+
| <a name="input_endpoint_type"></a> [endpoint\_type](#input\_endpoint\_type) | The type of Verified Access endpoint to create. Currently load-balancer or network-interface are supported. | `string` | n/a | yes |
35+
| <a name="input_load_balancer_arn"></a> [load\_balancer\_arn](#input\_load\_balancer\_arn) | The ARN of the internal load balancer. | `string` | `null` | no |
36+
| <a name="input_network_interface_id"></a> [network\_interface\_id](#input\_network\_interface\_id) | The ID of the network interface | `string` | `null` | no |
37+
| <a name="input_port"></a> [port](#input\_port) | The IP port number. | `number` | `null` | no |
38+
| <a name="input_protocol"></a> [protocol](#input\_protocol) | The IP protocol. | `string` | `null` | no |
39+
| <a name="input_security_group_ids"></a> [security\_group\_ids](#input\_security\_group\_ids) | List of the the security groups IDs to associate with the Verified Access endpoint. | `list(string)` | n/a | yes |
40+
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | The IDs of the subnets. | `list(string)` | `[]` | no |
41+
| <a name="input_tags"></a> [tags](#input\_tags) | Key-value mapping of resource tags. | `map(string)` | `{}` | no |
42+
| <a name="input_verified_access_group_id"></a> [verified\_access\_group\_id](#input\_verified\_access\_group\_id) | The ID of the Verified Access group to associate the endpoint with. | `string` | n/a | yes |
43+
44+
## Outputs
45+
46+
| Name | Description |
47+
|------|-------------|
48+
| <a name="output_endpoint_domain"></a> [endpoint\_domain](#output\_endpoint\_domain) | A DNS name that is generated for the endpoint. |
49+
| <a name="output_endpoint_id"></a> [endpoint\_id](#output\_endpoint\_id) | The ID of the AWS Verified Access endpoint. |
50+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

modules/endpoint/main.tf

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
resource "aws_verifiedaccess_endpoint" "this" {
2+
description = var.description
3+
application_domain = var.application_domain
4+
domain_certificate_arn = var.domain_certificate_arn
5+
6+
verified_access_group_id = var.verified_access_group_id
7+
8+
attachment_type = var.attachment_type
9+
endpoint_domain_prefix = var.endpoint_domain_prefix
10+
security_group_ids = var.security_group_ids
11+
endpoint_type = var.endpoint_type
12+
13+
dynamic "network_interface_options" {
14+
for_each = var.endpoint_type == "network-interface" ? [1] : []
15+
content {
16+
network_interface_id = var.network_interface_id
17+
port = var.port
18+
protocol = var.protocol
19+
}
20+
}
21+
22+
dynamic "load_balancer_options" {
23+
for_each = var.endpoint_type == "load-balancer" ? [1] : []
24+
content {
25+
load_balancer_arn = var.load_balancer_arn
26+
port = var.port
27+
protocol = var.protocol
28+
subnet_ids = var.subnet_ids
29+
}
30+
}
31+
32+
tags = var.tags
33+
}

0 commit comments

Comments
 (0)