diff --git a/modules/github-aws-oidc/README.md b/modules/github-aws-oidc/README.md
new file mode 100644
index 0000000..1042900
--- /dev/null
+++ b/modules/github-aws-oidc/README.md
@@ -0,0 +1,55 @@
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.6 |
+| [aws](#requirement\_aws) | ~> 5.0 |
+| [random](#requirement\_random) | >= 3.6 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | ~> 5.0 |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_dynamodb_table.state_lock_table](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dynamodb_table) | resource |
+| [aws_iam_openid_connect_provider.oidc_provider_entry](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_openid_connect_provider) | resource |
+| [aws_iam_role.organizations_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
+| [aws_iam_role_policy.organizations_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
+| [aws_kms_key.encryption_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
+| [aws_resourcegroups_group.github_foundations_rg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/resourcegroups_group) | resource |
+| [aws_s3_bucket.state_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
+| [aws_s3_bucket_server_side_encryption_configuration.state_bucket_encryption](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
+| [aws_s3_bucket_versioning.state_bucket_versioning](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [bucket\_name](#input\_bucket\_name) | The name of the s3 bucket that will store terraform state. | `string` | `"GithubFoundationState"` | no |
+| [github\_repo\_owner](#input\_github\_repo\_owner) | The owner of the github foundations organizations repository. This value should be whatever github account you plan to make the repository under. | `string` | n/a | yes |
+| [github\_thumbprints](#input\_github\_thumbprints) | A list of top intermediate certifact authority thumbprints to use for setting up an openid connect provider with github. Info on how to obtain thumbprints here: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html | `list(string)` | n/a | yes |
+| [organizations\_repo\_name](#input\_organizations\_repo\_name) | The name of the github foundations organizations repository. Defaults to `organizations` | `string` | `"organizations"` | no |
+| [organizations\_role\_name](#input\_organizations\_role\_name) | The name of the role that will be assummed by the github runner for the organizations repository. | `string` | `"GhFoundationsOrganizationsAction"` | no |
+| [rg\_name](#input\_rg\_name) | The name of the AWS resource group to create for github foundation resources. | `string` | `"GithubFoundationResources"` | no |
+| [tflock\_db\_billing\_mode](#input\_tflock\_db\_billing\_mode) | The billing mode to use for the dynamodb table storing lock file ids. Defaults to `PROVISIONED`. | `string` | `"PROVISIONED"` | no |
+| [tflock\_db\_name](#input\_tflock\_db\_name) | The name of the dynamodb table that will store lock file ids. | `string` | `"TFLockIds"` | no |
+| [tflock\_db\_read\_capacity](#input\_tflock\_db\_read\_capacity) | The read capacity to set for the dynamodb table storing lock file ids. Only required if billing mode is `PROVISIONED`. Defaults to 20. | `number` | `20` | no |
+| [tflock\_db\_write\_capacity](#input\_tflock\_db\_write\_capacity) | The write capacity to set for the dynamodb table storing lock file ids. Only required if billing mode is `PROVISIONED`. Defaults to 20. | `number` | n/a | yes |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [dynamodb\_table\_name](#output\_dynamodb\_table\_name) | The name of the dynamodb table that was created to store lock file ids. |
+| [organizations\_runner\_role](#output\_organizations\_runner\_role) | The ARN of the role that the github action runner should assume for the organizations repo |
+| [s3\_bucket\_name](#output\_s3\_bucket\_name) | The name of the s3 bucket holding terraform state. |
+| [s3\_bucket\_region](#output\_s3\_bucket\_region) | The region the s3 bucket holding terraform state was created in. |
\ No newline at end of file
diff --git a/modules/github-aws-oidc/oidc.tf b/modules/github-aws-oidc/oidc.tf
new file mode 100644
index 0000000..ef2ae57
--- /dev/null
+++ b/modules/github-aws-oidc/oidc.tf
@@ -0,0 +1,97 @@
+resource "aws_iam_openid_connect_provider" "oidc_provider_entry" {
+ url = "https://token.actions.githubusercontent.com"
+
+ client_id_list = [ "sts.amazonaws.com" ]
+
+ thumbprint_list = var.github_thumbprints
+
+ tags = local.rg_tags
+}
+
+resource "aws_iam_role" "organizations_role" {
+ name = var.organizations_role_name
+
+ assume_role_policy = jsonencode({
+ "Version" = "2012-10-17",
+ "Statement" = [
+ {
+ "Effect" = "Allow",
+ "Action" = "sts:AssumeRoleWithWebIdentity",
+ "Principal" = {
+ "Federated" = aws_iam_openid_connect_provider.oidc_provider_entry.arn
+ },
+ "Condition" = {
+ "StringEquals" = {
+ "token.actions.githubusercontent.com:aud" = [
+ "sts.amazonaws.com"
+ ]
+ },
+ "StringLike" = {
+ "token.actions.githubusercontent.com:sub": [
+ "repo:${var.github_repo_owner}/${var.organizations_repo_name}:*"
+ ]
+ }
+ }
+ }
+ ]
+})
+
+ tags = local.rg_tags
+}
+
+resource "aws_iam_role_policy" "organizations_role_policy" {
+ name = "organizations-tf-state-management-policy"
+ role = aws_iam_role.organizations_role.id
+
+ policy = jsonencode({
+ Version = "2012-10-17"
+ Statement = [
+ {
+ Sid = "StateBucketFullAccess"
+ Action = [
+ "s3:*"
+ ]
+ Effect = "Allow"
+ Resource = [
+ aws_s3_bucket.state_bucket.arn,
+ "${aws_s3_bucket.sate_bucket.arn}/*"
+ ]
+ },
+ {
+ Sid = "StateBucketDeleteDeny"
+ Action = [
+ "s3:DeleteBucket"
+ ]
+ Effect = "Deny"
+ Resource = [aws_s3_bucket.state_bucket.arn]
+ },
+ {
+ Sid = "AllowSecretRead"
+ Action = [
+ "secretsmanager:GetSecretValue",
+ "secretsmanager:DescribeSecret",
+ "secretsmanager:GetResourcePolicy"
+
+ ]
+ Effect = "Allow"
+ Resource = "*"
+ Condition = {
+ StringEquals = {
+ "secretsmanager:ResourceTag/Purpose" = local.rg_tags["Purpose"]
+ }
+ }
+ },
+ {
+ Sid = "AllowDynamoDBActionsOnLockTable"
+ Effect = "Allow",
+ Action = [
+ "dynamodb:DescribeTable",
+ "dynamodb:GetItem",
+ "dynamodb:PutItem",
+ "dynamodb:DeleteItem"
+ ],
+ Resource = [ aws_dynamodb_table.state_lock_table.arn ]
+ }
+ ]
+ })
+}
\ No newline at end of file
diff --git a/modules/github-aws-oidc/outputs.tf b/modules/github-aws-oidc/outputs.tf
new file mode 100644
index 0000000..2966bb2
--- /dev/null
+++ b/modules/github-aws-oidc/outputs.tf
@@ -0,0 +1,19 @@
+output "s3_bucket_name" {
+ description = "The name of the s3 bucket holding terraform state."
+ value = aws_s3_bucket.state_bucket.bucket
+}
+
+output "s3_bucket_region" {
+ description = "The region the s3 bucket holding terraform state was created in."
+ value = aws_s3_bucket.state_bucket.region
+}
+
+output "dynamodb_table_name" {
+ description = "The name of the dynamodb table that was created to store lock file ids."
+ value = aws_dynamodb_table.state_lock_table.name
+}
+
+output "organizations_runner_role" {
+ description = "The ARN of the role that the github action runner should assume for the organizations repo"
+ value = aws_iam_role.organizations_role.arn
+}
\ No newline at end of file
diff --git a/modules/github-aws-oidc/resource_group.tf b/modules/github-aws-oidc/resource_group.tf
new file mode 100644
index 0000000..358f775
--- /dev/null
+++ b/modules/github-aws-oidc/resource_group.tf
@@ -0,0 +1,21 @@
+locals {
+ rg_tags = {
+ Purpose = "Github Foundations"
+ }
+}
+
+resource "aws_resourcegroups_group" "github_foundations_rg" {
+ name = var.rg_name
+
+ resource_query {
+ query = jsonencode({
+ "ResourceTypeFilters" = [ "AWS::AllSupported" ]
+ "TagFilters" = [
+ {
+ "Key"="Purpose"
+ "Values"=[ local.rg_tags.Purpose ]
+ }
+ ]
+ })
+ }
+}
diff --git a/modules/github-aws-oidc/storage.tf b/modules/github-aws-oidc/storage.tf
new file mode 100644
index 0000000..c9e34e2
--- /dev/null
+++ b/modules/github-aws-oidc/storage.tf
@@ -0,0 +1,43 @@
+resource "aws_kms_key" "encryption_key" {
+ description = "This key is used to encrypt state bucket objects"
+ deletion_window_in_days = 10
+}
+
+resource "aws_s3_bucket" "state_bucket" {
+ bucket = var.bucket_name
+
+ tags = local.rg_tags
+}
+
+resource "aws_s3_bucket_versioning" "state_bucket_versioning" {
+ bucket = aws_s3_bucket.state_bucket.id
+ versioning_configuration {
+ status = "Enabled"
+ }
+}
+
+resource "aws_s3_bucket_server_side_encryption_configuration" "state_bucket_encryption" {
+ bucket = aws_s3_bucket.state_bucket.id
+
+ rule {
+ apply_server_side_encryption_by_default {
+ kms_master_key_id = aws_kms_key.encryption_key.arn
+ sse_algorithm = "aws:kms"
+ }
+ }
+}
+
+resource "aws_dynamodb_table" "state_lock_table" {
+ name = var.tflock_db_name
+ read_capacity = var.tflock_db_read_capacity
+ write_capacity = var.tflock_db_write_capacity
+ billing_mode = var.tflock_db_billing_mode
+ hash_key = "LockID"
+
+ attribute {
+ name = "LockID"
+ type = "S"
+ }
+
+ tags = local.rg_tags
+}
diff --git a/modules/github-aws-oidc/variables.tf b/modules/github-aws-oidc/variables.tf
new file mode 100644
index 0000000..085fa92
--- /dev/null
+++ b/modules/github-aws-oidc/variables.tf
@@ -0,0 +1,65 @@
+# Resource Group Variables
+variable "rg_name" {
+ type = string
+ description = "The name of the AWS resource group to create for github foundation resources."
+ default = "GithubFoundationResources"
+}
+
+# Bucket Variables
+variable "bucket_name" {
+ type = string
+ description = "The name of the s3 bucket that will store terraform state."
+ default = "GithubFoundationState"
+}
+
+# DynamoDB Variables
+variable "tflock_db_name" {
+ type = string
+ description = "The name of the dynamodb table that will store lock file ids."
+ default = "TFLockIds"
+}
+
+variable "tflock_db_read_capacity" {
+ type = number
+ description = "The read capacity to set for the dynamodb table storing lock file ids. Only required if billing mode is `PROVISIONED`. Defaults to 20."
+ default = 20
+}
+
+variable "tflock_db_write_capacity" {
+ type = number
+ description = "The write capacity to set for the dynamodb table storing lock file ids. Only required if billing mode is `PROVISIONED`. Defaults to 20."
+}
+
+variable "tflock_db_billing_mode" {
+ type = string
+ description = "The billing mode to use for the dynamodb table storing lock file ids. Defaults to `PROVISIONED`."
+ default = "PROVISIONED"
+}
+
+# IAM Variables
+
+variable "github_thumbprints" {
+ type = list(string)
+ description = "A list of top intermediate certifact authority thumbprints to use for setting up an openid connect provider with github. Info on how to obtain thumbprints here: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html"
+ validation {
+ error_message = "The list must be a minimum length of 1 and has a maximum length of 5"
+ condition = length(var.github_thumbprints) >=1 && length(var.github_thumbprints) <= 5
+ }
+}
+
+variable "organizations_role_name" {
+ type = string
+ description = "The name of the role that will be assummed by the github runner for the organizations repository."
+ default = "GhFoundationsOrganizationsAction"
+}
+
+variable "github_repo_owner" {
+ type = string
+ description = "The owner of the github foundations organizations repository. This value should be whatever github account you plan to make the repository under."
+}
+
+variable "organizations_repo_name" {
+ type = string
+ description = "The name of the github foundations organizations repository. Defaults to `organizations`"
+ default = "organizations"
+}
\ No newline at end of file
diff --git a/modules/github-aws-oidc/versions.tf b/modules/github-aws-oidc/versions.tf
new file mode 100644
index 0000000..1135ec5
--- /dev/null
+++ b/modules/github-aws-oidc/versions.tf
@@ -0,0 +1,13 @@
+terraform {
+ required_version = ">= 1.6"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = ">= 3.6" # tftest
+ }
+ }
+}
diff --git a/modules/github-azure-oidc/README.md b/modules/github-azure-oidc/README.md
index bc480f5..4dde149 100644
--- a/modules/github-azure-oidc/README.md
+++ b/modules/github-azure-oidc/README.md
@@ -4,7 +4,6 @@
|------|---------|
| [terraform](#requirement\_terraform) | >= 1.6 |
| [azurerm](#requirement\_azurerm) | >=3.0.0 |
-| [google-beta](#requirement\_google-beta) | >= 3.77 |
| [random](#requirement\_random) | >= 3.6 |
## Providers
diff --git a/modules/github-azure-oidc/versions.tf b/modules/github-azure-oidc/versions.tf
index d34e8d7..9a66b59 100644
--- a/modules/github-azure-oidc/versions.tf
+++ b/modules/github-azure-oidc/versions.tf
@@ -5,10 +5,6 @@ terraform {
source = "hashicorp/azurerm"
version = ">=3.0.0" #tftest
}
- google-beta = {
- source = "hashicorp/google-beta"
- version = ">= 3.77" # tftest
- }
random = {
source = "hashicorp/random"
version = ">= 3.6" # tftest