terraform-provider-github icon indicating copy to clipboard operation
terraform-provider-github copied to clipboard

[feature] Manage Organization IP Allow Lists

Open douglascayers opened this issue 3 years ago • 4 comments

Request

Hello, I would like to manage the IP allow list for my GitHub organizations via Terraform. On the web I can do this at https://github.com/organizations/<organization>/settings/security.

What I've checked so far

Desired Configuration

As an example, it would be nice to manage the IP allow lists for an organization something like the following.

locals {
  # For the example, I just grabbed some IPs from https://api.github.com/meta
  cidr_allow_set = [
    "192.30.252.0/22",
    "185.199.108.0/22",
    "140.82.112.0/20",
    "143.55.64.0/20",
  ] 
}

# Per current convention, this new resource infers the organization context from the `provider` configuration.
# This example is inspired by `heroku_space_inbound_ruleset` resource from heroku provider.
# https://registry.terraform.io/providers/heroku/heroku/4.9.0/docs/resources/space_inbound_ruleset
resource "github_organization_ip_allow_list" "default" {
  # For each IP range in the CIDR allow set,
  # creates a `entry { name, active, source }` block.
  dynamic "entry" {
    for_each = local.cidr_allow_set

    content {
      name = "An optional name for the IP allow list entry"
      active = true
      source = entry.value
    }
  }
}

Thank you!


Terraform v1.1.5
on darwin_amd64
+ provider registry.terraform.io/integrations/github v4.20.0

douglascayers avatar Feb 15 '22 02:02 douglascayers

Sid Palas suggested a workaround by using the sullivtr/graphql provider, which worked for me.

For anyone else wanting to do this, here's the setup I used:

terraform {
  required_version = "1.1.5"
  required_providers {
    github = {
      source  = "integrations/github"
      version = "4.20.0"
    }
    graphql = {
      source  = "sullivtr/graphql"
      version = "2.5.0"
    }
  }
  backend "pg" {
  }
}

variable "GITHUB_TOKEN" {
  description = "Your personal access token. Needs scopes: repo, admin:org, delete_repo"
  type        = string
  sensitive   = true
}

variable "GITHUB_OWNER" {
  description = "The target GitHub organization or individual user account to manage"
  type        = string
}

provider "github" {
  token = var.GITHUB_TOKEN
  owner = var.GITHUB_OWNER
}

provider "graphql" {
  url = "https://api.github.com/graphql"
  headers = {
    "Authorization" : "token ${var.GITHUB_TOKEN}"
  }
}

data "graphql_query" "organization" {
  query_variables = {
    login : var.GITHUB_OWNER
  }
  query = file("./graphql/organization_read.gql")
}

locals {
  # Map of CIDR IP range to graphql properties of the IpAllowListEntry
  cidr_allow_list = {
    "127.0.0.1/8": {
      name = "Description shown at https://github.com/organizations/{org}/settings/security"
      # you could also set isActive or ownerId
    }
  }
}

resource "graphql_mutation" "ip_allow_list" {
  for_each = local.cidr_allow_list

  mutation_variables = {
    name           = each.value.name
    allowListValue = each.key
    isActive       = true
    ownerId        = jsondecode(data.graphql_query.organization.query_response).data.organization.id
  }

  compute_from_create = true

  compute_mutation_keys = {
    ipAllowListEntryId = "data.createIpAllowListEntry.ipAllowListEntry.id"
  }

  create_mutation = file("./graphql/ip_allow_list_create.gql")
  update_mutation = file("./graphql/ip_allow_list_update.gql")
  delete_mutation = file("./graphql/ip_allow_list_delete.gql")
  read_query      = file("./graphql/ip_allow_list_read.gql")
}

And the files referenced above

./graphql/organization_read.gql

query Organization($login: String!) {
  organization(login: $login) {
    id
    name
    url
  }
}

./graphql/ip_allow_list_read.gql

query IpAllowListEntry($ipAllowListEntryId: ID!) {
  node(id: $ipAllowListEntryId) {
    ... on IpAllowListEntry {
      id
      name
      isActive
      allowListValue
      owner {
        ... on Organization {
          id
        }
      }
    }
  }
}

./graphql/ip_allow_list_create.gql

mutation CreateIpAllowListEntry(
  $name: String!,
  $isActive: Boolean!,
  $allowListValue: String!,
  $ownerId: ID!
) {
  createIpAllowListEntry(input: {
    name: $name,
    isActive: $isActive,
    allowListValue: $allowListValue,
    ownerId: $ownerId
  }) {
    ipAllowListEntry {
      id
      name
      isActive
      allowListValue
      owner {
        ... on Organization {
          id
        }
      }
    }
  }
}

./graphql/ip_allow_list_update.gql

mutation UpdateIpAllowListEntry(
  $ipAllowListEntryId: ID!,
  $name: String!,
  $isActive: Boolean!,
  $allowListValue: String!
) {
  updateIpAllowListEntry(input: {
    ipAllowListEntryId: $ipAllowListEntryId,
    name: $name,
    isActive: $isActive,
    allowListValue: $allowListValue,
  }) {
    ipAllowListEntry {
      id
      name
      isActive
      allowListValue
      owner {
        ... on Organization {
          id
        }
      }
    }
  }
}

./graphql/ip_allow_list_delete.gql

mutation DeleteIpAllowListEntry($ipAllowListEntryId: ID!) {
  deleteIpAllowListEntry(input: {
    ipAllowListEntryId: $ipAllowListEntryId
  }) {
    ipAllowListEntry {
      id
    }
  }
}

douglascayers avatar Feb 16 '22 02:02 douglascayers

Thanks for sharing this code snippet!

avgalani avatar Feb 18 '22 12:02 avgalani

👋 Hey Friends, this issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Please add the Status: Pinned label if you feel that this issue needs to remain open/active. Thank you for your contributions and help in keeping things tidy!

github-actions[bot] avatar Jun 01 '23 02:06 github-actions[bot]

Can we reopen this issue ?

XciD avatar Jun 14 '24 11:06 XciD