Skip to content

Commit cc44693

Browse files
authored
feat: Add support for creating IAM GitHub OIDC provider and role(s) (#308)
1 parent 3c5807b commit cc44693

File tree

16 files changed

+652
-0
lines changed

16 files changed

+652
-0
lines changed

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,37 @@ module "iam_eks_role" {
156156
}
157157
```
158158

159+
`iam-github-oidc-provider`:
160+
161+
```hcl
162+
module "iam_github_oidc_provider" {
163+
source = "terraform-aws-modules/iam/aws//modules/iam-github-oidc-provider"
164+
165+
tags = {
166+
Environment = "test"
167+
}
168+
}
169+
```
170+
171+
`iam-github-oidc-role`:
172+
173+
```hcl
174+
module "iam_github_oidc_role" {
175+
source = "terraform-aws-modules/iam/aws//modules/iam-github-oidc-role"
176+
177+
# This should be updated to suit your organization, repository, references/branches, etc.
178+
subjects = ["terraform-aws-modules/terraform-aws-iam:*"]
179+
180+
policies = {
181+
S3ReadOnly = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
182+
}
183+
184+
tags = {
185+
Environment = "test"
186+
}
187+
}
188+
```
189+
159190
`iam-group-with-assumable-roles-policy`:
160191

161192
```hcl

examples/iam-github-oidc/README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# IAM GitHub OIDC
2+
3+
- Creates an IAM identity provider for GitHub OIDC
4+
- Creates an IAM role that trust the IAM GitHub OIDC provider
5+
- GitHub reference: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services
6+
- AWS IAM role reference: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_oidc.html#idp_oidc_Create_GitHub
7+
8+
Note: an IAM provider is 1 per account per given URL. This module would be provisioned once per AWS account, and multiple roles created with this provider as the trusted identity (typically 1 role per GitHub repository).
9+
10+
To run this example you need to execute:
11+
12+
```bash
13+
$ terraform init
14+
$ terraform plan
15+
$ terraform apply
16+
```
17+
18+
Run `terraform destroy` when you don't need these resources.
19+
20+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
21+
## Requirements
22+
23+
| Name | Version |
24+
|------|---------|
25+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
26+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.0 |
27+
28+
## Providers
29+
30+
| Name | Version |
31+
|------|---------|
32+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.0 |
33+
34+
## Modules
35+
36+
| Name | Source | Version |
37+
|------|--------|---------|
38+
| <a name="module_iam_github_oidc_provider"></a> [iam\_github\_oidc\_provider](#module\_iam\_github\_oidc\_provider) | ../../modules/iam-github-oidc-provider | n/a |
39+
| <a name="module_iam_github_oidc_provider_disabled"></a> [iam\_github\_oidc\_provider\_disabled](#module\_iam\_github\_oidc\_provider\_disabled) | ../../modules/iam-github-oidc-provider | n/a |
40+
| <a name="module_iam_github_oidc_role"></a> [iam\_github\_oidc\_role](#module\_iam\_github\_oidc\_role) | ../../modules/iam-github-oidc-role | n/a |
41+
| <a name="module_iam_github_oidc_role_disabled"></a> [iam\_github\_oidc\_role\_disabled](#module\_iam\_github\_oidc\_role\_disabled) | ../../modules/iam-github-oidc-role | n/a |
42+
43+
## Resources
44+
45+
| Name | Type |
46+
|------|------|
47+
| [aws_iam_policy.additional](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
48+
49+
## Inputs
50+
51+
No inputs.
52+
53+
## Outputs
54+
55+
| Name | Description |
56+
|------|-------------|
57+
| <a name="output_iam_role_arn"></a> [iam\_role\_arn](#output\_iam\_role\_arn) | ARN of IAM role |
58+
| <a name="output_iam_role_name"></a> [iam\_role\_name](#output\_iam\_role\_name) | Name of IAM role |
59+
| <a name="output_iam_role_path"></a> [iam\_role\_path](#output\_iam\_role\_path) | Path of IAM role |
60+
| <a name="output_iam_role_unique_id"></a> [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Unique ID of IAM role |
61+
| <a name="output_provider_arn"></a> [provider\_arn](#output\_provider\_arn) | The ARN assigned by AWS for this provider |
62+
| <a name="output_provider_url"></a> [provider\_url](#output\_provider\_url) | The URL of the identity provider. Corresponds to the iss claim |
63+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

examples/iam-github-oidc/main.tf

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
provider "aws" {
2+
region = local.region
3+
}
4+
5+
locals {
6+
name = "ex-iam-github-oidc"
7+
region = "eu-west-1"
8+
9+
tags = {
10+
Example = local.name
11+
GithubRepo = "terraform-aws-iam"
12+
GithubOrg = "terraform-aws-modules"
13+
}
14+
}
15+
16+
################################################################################
17+
# GitHub OIDC Provider
18+
# Note: This is one per AWS account
19+
################################################################################
20+
21+
module "iam_github_oidc_provider" {
22+
source = "../../modules/iam-github-oidc-provider"
23+
24+
tags = local.tags
25+
}
26+
27+
module "iam_github_oidc_provider_disabled" {
28+
source = "../../modules/iam-github-oidc-provider"
29+
30+
create = false
31+
}
32+
33+
################################################################################
34+
# GitHub OIDC Role
35+
################################################################################
36+
37+
module "iam_github_oidc_role" {
38+
source = "../../modules/iam-github-oidc-role"
39+
40+
# This should be updated to suit your organization, repository, references/branches, etc.
41+
subjects = ["terraform-aws-modules/terraform-aws-iam:*"]
42+
43+
policies = {
44+
additional = aws_iam_policy.additional.arn
45+
S3ReadOnly = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
46+
}
47+
48+
tags = local.tags
49+
}
50+
51+
module "iam_github_oidc_role_disabled" {
52+
source = "../../modules/iam-github-oidc-role"
53+
54+
create = false
55+
}
56+
57+
################################################################################
58+
# Supporting Resources
59+
################################################################################
60+
61+
resource "aws_iam_policy" "additional" {
62+
name = "${local.name}-additional"
63+
description = "Additional test policy"
64+
65+
policy = jsonencode({
66+
Version = "2012-10-17"
67+
Statement = [
68+
{
69+
Action = [
70+
"ec2:Describe*",
71+
]
72+
Effect = "Allow"
73+
Resource = "*"
74+
},
75+
]
76+
})
77+
78+
tags = local.tags
79+
}

examples/iam-github-oidc/outputs.tf

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
################################################################################
2+
# GitHub OIDC Provider
3+
################################################################################
4+
5+
output "provider_arn" {
6+
description = "The ARN assigned by AWS for this provider"
7+
value = module.iam_github_oidc_provider.arn
8+
}
9+
10+
output "provider_url" {
11+
description = "The URL of the identity provider. Corresponds to the iss claim"
12+
value = module.iam_github_oidc_provider.url
13+
}
14+
15+
################################################################################
16+
# GitHub OIDC Role
17+
################################################################################
18+
19+
output "iam_role_arn" {
20+
description = "ARN of IAM role"
21+
value = module.iam_github_oidc_role.arn
22+
}
23+
24+
output "iam_role_name" {
25+
description = "Name of IAM role"
26+
value = module.iam_github_oidc_role.name
27+
}
28+
29+
output "iam_role_path" {
30+
description = "Path of IAM role"
31+
value = module.iam_github_oidc_role.path
32+
}
33+
34+
output "iam_role_unique_id" {
35+
description = "Unique ID of IAM role"
36+
value = module.iam_github_oidc_role.unique_id
37+
}

examples/iam-github-oidc/variables.tf

Whitespace-only changes.

examples/iam-github-oidc/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.0"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = ">= 4.0"
8+
}
9+
}
10+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# IAM GitHub OIDC Provider
2+
3+
Creates an IAM identity provider for GitHub OIDC. See more details here https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services
4+
5+
Note: an IAM provider is 1 per account per given URL. This module would be provisioned once per AWS account, and multiple roles created with this provider as the trusted identity (typically 1 role per GitHub repository).
6+
7+
## Usage
8+
9+
```hcl
10+
module "iam_github_oidc_provider" {
11+
source = "terraform-aws-modules/iam/aws//modules/iam-github-oidc-provider"
12+
13+
tags = {
14+
Environment = "test"
15+
}
16+
}
17+
```
18+
19+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
20+
## Requirements
21+
22+
| Name | Version |
23+
|------|---------|
24+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
25+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.0 |
26+
| <a name="requirement_tls"></a> [tls](#requirement\_tls) | >= 3.0 |
27+
28+
## Providers
29+
30+
| Name | Version |
31+
|------|---------|
32+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.0 |
33+
| <a name="provider_tls"></a> [tls](#provider\_tls) | >= 3.0 |
34+
35+
## Modules
36+
37+
No modules.
38+
39+
## Resources
40+
41+
| Name | Type |
42+
|------|------|
43+
| [aws_iam_openid_connect_provider.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_openid_connect_provider) | resource |
44+
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
45+
| [tls_certificate.this](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/data-sources/certificate) | data source |
46+
47+
## Inputs
48+
49+
| Name | Description | Type | Default | Required |
50+
|------|-------------|------|---------|:--------:|
51+
| <a name="input_client_id_list"></a> [client\_id\_list](#input\_client\_id\_list) | List of client IDs (also known as audiences) for the IAM OIDC provider. Defaults to STS service if not values are provided | `list(string)` | `[]` | no |
52+
| <a name="input_create"></a> [create](#input\_create) | Controls if resources should be created (affects all resources) | `bool` | `true` | no |
53+
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to the resources created | `map(any)` | `{}` | no |
54+
| <a name="input_url"></a> [url](#input\_url) | The URL of the identity provider. Corresponds to the iss claim | `string` | `"https://token.actions.githubusercontent.com"` | no |
55+
56+
## Outputs
57+
58+
| Name | Description |
59+
|------|-------------|
60+
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN assigned by AWS for this provider |
61+
| <a name="output_url"></a> [url](#output\_url) | The URL of the identity provider. Corresponds to the iss claim |
62+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
data "aws_partition" "current" {}
2+
3+
################################################################################
4+
# GitHub OIDC Provider
5+
################################################################################
6+
7+
data "tls_certificate" "this" {
8+
count = var.create ? 1 : 0
9+
10+
url = var.url
11+
}
12+
13+
resource "aws_iam_openid_connect_provider" "this" {
14+
count = var.create ? 1 : 0
15+
16+
url = var.url
17+
client_id_list = coalescelist(var.client_id_list, ["sts.${data.aws_partition.current.dns_suffix}"])
18+
thumbprint_list = data.tls_certificate.this[0].certificates[*].sha1_fingerprint
19+
20+
tags = var.tags
21+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
################################################################################
2+
# GitHub OIDC Provider
3+
################################################################################
4+
5+
output "arn" {
6+
description = "The ARN assigned by AWS for this provider"
7+
value = try(aws_iam_openid_connect_provider.this[0].arn, null)
8+
}
9+
10+
output "url" {
11+
description = "The URL of the identity provider. Corresponds to the iss claim"
12+
value = try(aws_iam_openid_connect_provider.this[0].url, null)
13+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
variable "create" {
2+
description = "Controls if resources should be created (affects all resources)"
3+
type = bool
4+
default = true
5+
}
6+
7+
variable "tags" {
8+
description = "A map of tags to add to the resources created"
9+
type = map(any)
10+
default = {}
11+
}
12+
13+
variable "client_id_list" {
14+
description = "List of client IDs (also known as audiences) for the IAM OIDC provider. Defaults to STS service if not values are provided"
15+
type = list(string)
16+
default = []
17+
}
18+
19+
variable "url" {
20+
description = "The URL of the identity provider. Corresponds to the iss claim"
21+
type = string
22+
default = "https://token.actions.githubusercontent.com"
23+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = ">= 4.0"
8+
}
9+
tls = {
10+
source = "hashicorp/tls"
11+
version = ">= 3.0"
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)