Skip to content

Commit

Permalink
feat: terraform-google-artifact-registry-repository-iam
Browse files Browse the repository at this point in the history
  • Loading branch information
samen93 committed Oct 19, 2021
1 parent 726f7fe commit 854e52c
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 72 deletions.
156 changes: 84 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,40 +34,12 @@ secure, and production-grade cloud infrastructure.

## Module Features

<!-- info: please adjust the following text -->

This module implements the following terraform resources

- `google_resource`
- `google_something_else`

and supports additional features of the following modules:

<!-- markdown-link-check-disable -->
- [mineiros-io/something/google](https://github.com/mineiros-io/terraform-google-something)
<!-- markdown-link-check-enable -->

<!--
These are some of our custom features:
- **Default Security Settings**:
secure by default by setting security to `true`, additional security can be added by setting some feature to `enabled`
- **Standard Module Features**:
Cool Feature of the main resource, tags
- **Extended Module Features**:
Awesome Extended Feature of an additional related resource,
and another Cool Feature
- **Additional Features**:
a Cool Feature that is not actually a resource but a cool set up from us
- _Features not yet implemented_:
Standard Features missing,
Extended Features planned,
Additional Features planned
-->
- `google_artifact_registry_repository_iam_binding`
- `google_artifact_registry_repository_iam_member`
- `google_artifact_registry_repository_iam_policy`
- `google_iam_policy`

## Getting Started

Expand All @@ -76,6 +48,11 @@ Most basic usage just setting required arguments:
```hcl
module "terraform-google-artifact-registry-repository-iam" {
source = "github.com/mineiros-io/terraform-google-artifact-registry-repository-iam?ref=v0.1.0"
repository = "my-repository"
location = "us-central1"
role = "roles/viewer"
members = ["user:member@example.com"]
}
```

Expand Down Expand Up @@ -107,58 +84,91 @@ See [variables.tf] and [examples/] for details and use-cases.

#### Main Resource Configuration

<!-- Example of a required variable:
- **`repository`**: **_(Required `string`)_**

Used to find the parent resource to bind the IAM policy to.

- **`name`**: **_(Required `string`)_**
- **`location`**: **_(Required `string`)_**

The name of the resource.
The name of the location this repository is located in. Used to find the parent resource to bind the IAM policy to.

Default is `"name"`.
- **`members`**: **_(Optional `string`)_

-->
Identities that will be granted the privilege in role. Each entry can have one of the following values:
- `allUsers`: A special identifier that represents anyone who is on the internet; with or without a Google account.
- `allAuthenticatedUsers`: A special identifier that represents anyone who is authenticated with a Google account or a service account.
- `user:{emailid}`: An email address that represents a specific Google account. For example, alice@gmail.com or joe@example.com.
- `serviceAccount:{emailid}`: An email address that represents a service account. For example, my-other-app@appspot.gserviceaccount.com.
- `group:{emailid}`: An email address that represents a Google group. For example, admins@example.com.
- `domain:{domain}`: A G Suite domain (primary, instead of alias) name that represents all the users of that domain. For example, google.com or example.com.

<!-- Example of an optional variable:
Default is `[]`.

- **`name`**: _(Optional `string`)_
- **`role`**: _(Optional `string`)_

The name of the resource.
The role that should be applied. Note that custom roles must be of the format `[projects|organizations]/{parent-name}/roles/{role-name}`.

Default is `"name"`.
- **`project`**: _(Optional `string`)_

-->
The resource name of the project the policy is attached to. Its format is `projects/{project_id}`.

<!-- Example of an object:
- We use inline documentation to describe complex objects or lists/maps of complex objects.
- Please indent each level with 2 spaces so the documentation is rendered in a readable way.
- **`authoritative`**: _(Optional `bool`)_

- **`user`**: _(Optional `object(user)`)_
Whether to exclusively set (authoritative mode) or add (non-authoritative/additive mode) members to the role.

A user object.
Default is `true`.

- **`policy_bindings`**: _(Optional `list(policy_bindings)`)_

A list of IAM policy bindings.

Example

```hcl
user = {
name = "marius"
description = "The guy from Berlin."
}
policy_bindings = [{
role = "roles/viewer"
members = ["user:member@example.com"]
}]
```

Default is `{}`.
Each `policy_bindings` object accepts the following fields:

- **`role`**: **_(Required `string`)_**

The role that should be applied.

A/Each `user` object can have the following fields:
- **`members`**: **_(Required `string`)_**

- **`name`**: **_(Required `string`)_**
Identities that will be granted the privilege in `role`.

The Name of the user.
Default is `var.members`.

- **`description`**: _(Optional `decription`)_
- **`condition`**: _(Optional `object(condition)`)_

A description describing the user in more detail.
An IAM Condition for a given binding.

Example

```hcl
condition = {
expression = "request.time < timestamp(\"2022-01-01T00:00:00Z\")"
title = "expires_after_2021_12_31"
}
```

Default is `""`.
A `condition` object accepts the following fields:

-->
- **`expression`**: **_(Required `string`)_**

Textual representation of an expression in Common Expression Language syntax.

- **`title`**: **_(Required `string`)_**

A title for the expression, i.e. a short string describing its purpose.

- **`description`**: _(Optional `string`)_

An optional description of the expression. This is a longer text which describes the expression, e.g. when hovered over it in a UI.

#### Extended Resource Configuration

Expand All @@ -170,18 +180,20 @@ The following attributes are exported in the outputs of the module:

Whether this module is enabled.

<!-- all outputs in outputs.tf-->
- **`iam`**

All attributes of the created `iam_binding` or `iam_member` or `iam_policy` resource according to the mode.

## External Documentation

### Google Documentation
<!-- markdown-link-check-disable -->

- https://link-to-docs
- https://cloud.google.com/artifact-registry

### Terraform Google Provider Documentation:

- https://www.terraform.io/docs/providers/google/r/something.html
- https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/artifact_registry_repository_iam
<!-- markdown-link-check-disable -->

## Module Versioning
Expand Down Expand Up @@ -241,7 +253,7 @@ Copyright &copy; 2020-2021 [Mineiros GmbH][homepage]

<!-- markdown-link-check-disable -->

[badge-build]: https://github.com/mineiros-io/terraform-google-premium-modules/workflows/Tests/badge.svg
[badge-build]: https://github.com/mineiros-io/terraform-google-artifact-registry-repository-iam/workflows/Tests/badge.svg

<!-- markdown-link-check-enable -->

Expand All @@ -252,8 +264,8 @@ Copyright &copy; 2020-2021 [Mineiros GmbH][homepage]

<!-- markdown-link-check-disable -->

[build-status]: https://github.com/mineiros-io/terraform-google-premium-modules/modules/terraform-google-artifact-registry-repository-iam/actions
[releases-github]: https://github.com/mineiros-io/terraform-google-premium-modules/modules/terraform-google-artifact-registry-repository-iam/releases
[build-status]: https://github.com/mineiros-io/terraform-google-artifact-registry-repository-iam/actions
[releases-github]: https://github.com/mineiros-io/terraform-google-artifact-registry-repository-iam/releases

<!-- markdown-link-check-enable -->

Expand All @@ -268,12 +280,12 @@ Copyright &copy; 2020-2021 [Mineiros GmbH][homepage]

<!-- markdown-link-check-disable -->

[variables.tf]: https://github.com/mineiros-io/terraform-google-premium-modules/blob/modules/terraform-google-artifact-registry-repository-iam/main/variables.tf
[examples/]: https://github.com/mineiros-io/terraform-google-premium-modules/blob/modules/terraform-google-artifact-registry-repository-iam/main/examples
[issues]: https://github.com/mineiros-io/terraform-google-premium-modules/issues
[license]: https://github.com/mineiros-io/terraform-google-premium-modules/blob/main/LICENSE
[makefile]: https://github.com/mineiros-io/terraform-google-premium-modules/blob/main/Makefile
[pull requests]: https://github.com/mineiros-io/terraform-google-premium-modules/pulls
[contribution guidelines]: https://github.com/mineiros-io/terraform-google-premium-modules/blob/main/CONTRIBUTING.md
[variables.tf]: https://github.com/mineiros-io/terraform-google-artifact-registry-repository-iam/main/variables.tf
[examples/]: https://github.com/mineiros-io/terraform-google-artifact-registry-repository-iam/main/examples
[issues]: https://github.com/mineiros-io/terraform-google-artifact-registry-repository-iam/issues
[license]: https://github.com/mineiros-io/terraform-google-artifact-registry-repository-iam/blob/main/LICENSE
[makefile]: https://github.com/mineiros-io/terraform-google-artifact-registry-repository-iam/blob/main/Makefile
[pull requests]: https://github.com/mineiros-io/terraform-google-artifact-registry-repository-iam/pulls
[contribution guidelines]: https://github.com/mineiros-io/terraform-google-artifact-registry-repository-iam/blob/main/CONTRIBUTING.md

<!-- markdown-link-check-enable -->
60 changes: 60 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
resource "google_artifact_registry_repository_iam_binding" "binding" {
provider = google-beta
count = var.module_enabled && var.policy_bindings == null && var.authoritative ? 1 : 0

repository = var.repository
location = var.location
role = var.role
members = var.members
project = var.project

depends_on = [var.module_depends_on]
}

resource "google_artifact_registry_repository_iam_member" "member" {
provider = google-beta
for_each = var.module_enabled && var.policy_bindings == null && var.authoritative == false ? var.members : []

repository = var.repository
location = var.location
role = var.role
member = each.value
project = var.project

depends_on = [var.module_depends_on]
}

resource "google_artifact_registry_repository_iam_policy" "policy" {
provider = google-beta
count = var.module_enabled && var.policy_bindings != null ? 1 : 0

repository = var.repository
location = var.location
policy_data = data.google_iam_policy.policy[0].policy_data
project = var.project

depends_on = [var.module_depends_on]
}

data "google_iam_policy" "policy" {
count = var.module_enabled && var.policy_bindings != null ? 1 : 0

dynamic "binding" {
for_each = var.policy_bindings

content {
role = binding.value.role
members = try(binding.value.members, var.members)

dynamic "condition" {
for_each = try([binding.value.condition], [])

content {
expression = condition.value.expression
title = condition.value.title
description = try(condition.value.description, null)
}
}
}
}
}
14 changes: 14 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
locals {
binding = try(google_artifact_registry_repository_iam_binding.binding[0], null)
member = try(google_artifact_registry_repository_iam_member.member, null)
policy = try(google_artifact_registry_repository_iam_policy.policy[0], null)

iam_output = [local.binding, local.member, local.policy]

iam_output_index = var.policy_bindings != null ? 2 : var.authoritative ? 0 : 1
}

output "iam" {
description = "All attributes of the created 'iam_binding' or 'iam_member' or 'iam_policy' resource according to the mode."
value = local.iam_output[local.iam_output_index]
}
66 changes: 66 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# ---------------------------------------------------------------------------------------------------------------------
# REQUIRED VARIABLES
# These variables must be set when using this module.
# ---------------------------------------------------------------------------------------------------------------------

variable "repository" {
description = "(Required) Used to find the parent resource to bind the IAM policy to."
type = string
}

variable "location" {
description = "(Required) The name of the location this repository is located in. Used to find the parent resource to bind the IAM policy to."
type = string
}

# ---------------------------------------------------------------------------------------------------------------------
# OPTIONAL VARIABLES
# These variables have defaults, but may be overridden.
# ---------------------------------------------------------------------------------------------------------------------

variable "members" {
type = set(string)
description = "(Optional) Identities that will be granted the privilege in role. Each entry can have one of the following values: 'allUsers', 'allAuthenticatedUsers', 'user:{emailid}', 'serviceAccount:{emailid}', 'group:{emailid}', 'domain:{domain}', 'projectOwner:projectid', 'projectEditor:projectid', 'projectViewer:projectid'."
default = []
}

variable "role" {
description = "(Optional) The role that should be applied. Only one 'iam_binding' can be used per role. Note that custom roles must be of the format '[projects|organizations]/{parent-name}/roles/{role-name}'."
type = string
default = null
}

variable "authoritative" {
description = "(Optional) Whether to exclusively set (authoritative mode) or add (non-authoritative/additive mode) members to the role."
type = bool
default = true
}

variable "policy_bindings" {
description = "(Optional) A list of IAM policy bindings."
type = any
default = null
}

variable "project" {
description = "(Optional) The ID of the project in which the resource belongs. If it is not provided, the provider project is used."
type = string
default = null
}

# ------------------------------------------------------------------------------
# MODULE CONFIGURATION PARAMETERS
# These variables are used to configure the module.
# ------------------------------------------------------------------------------

variable "module_enabled" {
type = bool
description = "(Optional) Whether to create resources within the module or not. Default is 'true'."
default = true
}

variable "module_depends_on" {
type = any
description = "(Optional) A list of external resources the module depends_on. Default is '[]'."
default = []
}
7 changes: 7 additions & 0 deletions versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
terraform {
required_version = ">= 0.14, < 2.0"

required_providers {
google-beta = "~> 3.75"
}
}

0 comments on commit 854e52c

Please sign in to comment.