Skip to content

Commit 30fa1ff

Browse files
authored
Preserve custom roles when vendoring in updates (#697)
1 parent 675f40b commit 30fa1ff

File tree

6 files changed

+87
-6
lines changed

6 files changed

+87
-6
lines changed

modules/aws-team-roles/README.md

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,57 @@
33
This component is responsible for provisioning user and system IAM roles outside the `identity` account.
44
It sets them up to be assumed from the "team" roles defined in the `identity` account by
55
[the `aws-teams` component](../aws-teams) and/or the AWS SSO permission sets
6-
defined in [the `aws-sso` component](../aws-sso).
6+
defined in [the `aws-sso` component](../aws-sso), and/or be directly accessible via SAML logins.
7+
8+
9+
### Privileges are Granted to Users via IAM Policies
10+
11+
Each role is granted permissions by attaching a list of IAM policies to the IAM role
12+
via its `role_policy_arns` list. You can configure AWS managed policies by entering the ARNs of the policies
13+
directly into the list, or you can create a custom policy as follows:
14+
15+
1. Give the policy a name, e.g. `eks-admin`. We will use `NAME` as a placeholder for the name in the instructions below.
16+
2. Create a file in the `aws-teams` directory with the name `policy-NAME.tf`.
17+
3. In that file, create a policy as follows:
18+
19+
```hcl
20+
data "aws_iam_policy_document" "NAME" {
21+
# Define the policy here
22+
}
23+
24+
resource "aws_iam_policy" "NAME" {
25+
name = format("%s-NAME", module.this.id)
26+
policy = data.aws_iam_policy_document.NAME.json
27+
28+
tags = module.this.tags
29+
}
30+
```
31+
32+
4. Create a file named `additional-policy-map_override.tf` in the `aws-team-roles` directory (if it does not already exist).
33+
This is a [terraform override file](https://developer.hashicorp.com/terraform/language/files/override), meaning its
34+
contents will be merged with the main terraform file, and any locals defined in it will override locals defined in other files.
35+
Having your code in this separate override file makes it possible for the component to provide a placeholder local variable
36+
so that it works without customization, while allowing you to customize the component and still update it without losing your customizations.
37+
5. In that file, redefine the local variable `overridable_additional_custom_policy_map` map as follows:
38+
39+
```hcl
40+
locals {
41+
overridable_additional_custom_policy_map = {
42+
NAME = aws_iam_policy.NAME.arn
43+
}
44+
}
45+
```
46+
47+
If you have multiple custom policies, add each one to the map in the form `NAME = aws_iam_policy.NAME.arn`.
48+
6. With that done, you can now attach that policy by adding the name to the `role_policy_arns` list. For example:
49+
50+
```yaml
51+
role_policy_arns:
52+
- "arn:aws:iam::aws:policy/job-function/ViewOnlyAccess"
53+
- "NAME"
54+
```
55+
56+
757
858
## Usage
959
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
locals {
2+
# If you have custom policies, override this declaration by creating
3+
# a file called `additional-policy-map_override.tf`.
4+
# Then add the custom policies to the additional_custom_policy_map in that file.
5+
# See the README for more details.
6+
overridable_additional_custom_policy_map = {
7+
# Example:
8+
# eks_viewer = aws_iam_policy.eks_viewer.arn
9+
}
10+
}

modules/aws-team-roles/main.tf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ locals {
1010
# If you want to create custom policies to add to multiple roles by name, create the policy
1111
# using an aws_iam_policy resource and then map it to the name you want to use in the
1212
# YAML configuration by adding an entry in `custom_policy_map`.
13-
custom_policy_map = {
13+
supplied_custom_policy_map = {
1414
billing_read_only = try(aws_iam_policy.billing_read_only[0].arn, null)
1515
billing_admin = try(aws_iam_policy.billing_admin[0].arn, null)
1616
support = try(aws_iam_policy.support[0].arn, null)
1717
eks_viewer = try(aws_iam_policy.eks_viewer[0].arn, null)
1818
}
19+
custom_policy_map = merge(local.supplied_custom_policy_map, local.overridable_additional_custom_policy_map)
1920

2021
configured_policies = flatten([for k, v in local.roles_config : v.role_policy_arns])
2122

modules/aws-teams/README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
# Component: `aws-teams`
22

3-
This component is responsible for provisioning all primary user and system roles into the centralized identity account.
4-
This is expected to be use alongside [the `aws-team-roles` component](../aws-team-roles) to provide
5-
fine grained role delegation across the account hierarchy.
3+
## Purpose
4+
5+
This component implements the hub of a hub-and-spoke account access hierarchy, where the hub is the `identity` account.
6+
This allows you to assign each user to a single "team" (implemented as an IAM role) in the `identity` account, which they access
7+
via a single authentication (login), which then allows them to access a set of roles in a set of accounts.
8+
9+
This component is responsible for provisioning team roles in the centralized identity account.
10+
This is expected to be used alongside [the `aws-team-roles` component](../aws-team-roles)
11+
which provisions the roles in the spoke accounts and configures their privileges and which teams can access them.
612

713
### Teams Function Like Groups and are Implemented as Roles
814
The "teams" created in the `identity` account by this module can be thought of as access control "groups":
915
a user who is allowed access one of these teams gets access to a set of roles (and corresponding permissions)
1016
across a set of accounts. Generally, there is nothing else provisioned in the `identity` account,
1117
so the teams have limited access to resources in the `identity` account by design.
1218

19+
Privileges for the users within the identity account itself are generally limited, and are configured
20+
via the `role_policy_arns` variable, just as with `aws-team-roles`. See the `aws-team-roles` README for more details.
21+
1322
Teams are implemented as IAM Roles in each account. Access to the "teams" in the `identity`
1423
account is controlled by the `aws-saml` and `aws-sso` components. Access to the roles in all the
1524
other accounts is controlled by the "assume role" policies of those roles, which allow the "team"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
locals {
2+
# If you have custom policies, override this declaration by creating
3+
# a file called `additional-policy-map_override.tf`.
4+
# Then add the custom policies to the additional_custom_policy_map in that file.
5+
# See the README in `aws-team-roles` for more details.
6+
overridable_additional_custom_policy_map = {
7+
# Example:
8+
# eks_viewer = aws_iam_policy.eks_viewer.arn
9+
}
10+
}

modules/aws-teams/main.tf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ locals {
66
# If you want to create custom policies to add to multiple roles by name, create the policy
77
# using an aws_iam_policy resource and then map it to the name you want to use in the
88
# YAML configuration by adding an entry in `custom_policy_map`.
9-
custom_policy_map = {
9+
supplied_custom_policy_map = {
1010
team_role_access = aws_iam_policy.team_role_access.arn
1111
support = try(aws_iam_policy.support[0].arn, null)
1212
}
13+
custom_policy_map = merge(local.supplied_custom_policy_map, local.overridable_additional_custom_policy_map)
1314

1415
configured_policies = flatten([for k, v in local.roles_config : v.role_policy_arns])
1516

0 commit comments

Comments
 (0)