Skip to content

Commit

Permalink
AD FS example
Browse files Browse the repository at this point in the history
  • Loading branch information
apichick committed Jul 4, 2022
1 parent 9336ac6 commit 6674e06
Show file tree
Hide file tree
Showing 27 changed files with 1,388 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ fast/stages/**/globals.auto.tfvars.json
cloud_sql_proxy
examples/cloud-operations/binauthz/tenant-setup.yaml
examples/cloud-operations/binauthz/app/app.yaml
examples/cloud-operations/adfs/ansible/vars/vars.yaml
examples/cloud-operations/adfs/ansible/gssh.sh
78 changes: 78 additions & 0 deletions examples/cloud-operations/adfs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# AD FS

The folowing example does the following:

Terraform:

- (Optional) Creates a project.
- (Optional) Creates a VPC.
- Sets up managed AD
- Creates a server where AD FS will be installed. This machine will also act as admin workstation for AD.
- Exposes AD FS using GLB.

Ansible:

- Installs the required Windows features and joins the computer to the AD domain.
- Provisions some tests users, groups and group memberships in AD. The data to provision is in the ifles directory of the ad-provisioning ansible role. There is script available in the scripts/ad-provisioning folder that you can use to generate an alternative users or memberships file.
- Installs AD FS

In addition to this, we also include a Powershell script that facilitates the configuration required for Anthos when authenticating users with AD FS as IdP.

The diagram below depicts the architecture of the example:

![Architecture](architecture.png)

## Running the example

Clone this repository or [open it in cloud shell](https://ssh.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fcloud-foundation-fabric&cloudshell_print=cloud-shell-readme.txt&cloudshell_working_dir=examples%2Fcloud-operations%2Fadfs), then go through the following steps to create resources:

* `terraform init`
* `terraform apply -var project_id=my-project-id -var ad_dns_domain_name=my-domain.org -var adfs_dns_domain_name=adfs.my-domain.org`

Once the resources have been created, do the following:

1. Create an A record to point the AD FS DNS domain name to the public IP address returned after the terraform configuration was applied.

2. Run the ansible playbook

ansible-playbook playbook.yaml

# Testing the example

1. In your browser open the following URL:

https://adfs.my-domain.org/adfs/ls/IdpInitiatedSignOn.aspx

2. Enter the username and password of one of the users provisioned. The username has to be in the format: username@my-domain.org

3. Verify that you have successfuly signed in.

Once done testing, you can clean up resources by running `terraform destroy`.
<!-- BEGIN TFDOC -->

## Variables

| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [ad_dns_domain_name](variables.tf#L44) | AD DNS domain name. | <code>string</code> || |
| [adfs_dns_domain_name](variables.tf#L49) | ADFS DNS domain name. | <code>string</code> || |
| [project_id](variables.tf#L24) | Host project ID. | <code>string</code> || |
| [ad_ip_cidr_block](variables.tf#L90) | Managed AD IP CIDR block. | <code>string</code> | | <code>&#34;10.0.0.0&#47;24&#34;</code> |
| [disk_size](variables.tf#L54) | Disk size. | <code>number</code> | | <code>50</code> |
| [disk_type](variables.tf#L60) | Disk type. | <code>string</code> | | <code>&#34;pd-ssd&#34;</code> |
| [image](variables.tf#L66) | Image. | <code>string</code> | | <code>&#34;projects&#47;windows-cloud&#47;global&#47;images&#47;family&#47;windows-2022&#34;</code> |
| [instance_type](variables.tf#L72) | Instance type. | <code>string</code> | | <code>&#34;n1-standard-2&#34;</code> |
| [network_config](variables.tf#L35) | Network configuration | <code title="object&#40;&#123;&#10; network &#61; string&#10; subnet &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [prefix](variables.tf#L29) | Prefix for the resources created. | <code>string</code> | | <code>null</code> |
| [project_create](variables.tf#L15) | Parameters for the creation of the new project. | <code title="object&#40;&#123;&#10; billing_account_id &#61; string&#10; parent &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [region](variables.tf#L78) | Region. | <code>string</code> | | <code>&#34;europe-west1&#34;</code> |
| [subnet_ip_cidr_block](variables.tf#L96) | Subnet IP CIDR block. | <code>string</code> | | <code>&#34;10.0.1.0&#47;28&#34;</code> |
| [zone](variables.tf#L84) | Zone. | <code>string</code> | | <code>&#34;europe-west1-c&#34;</code> |

## Outputs

| name | description | sensitive |
|---|---|:---:|
| [ip_address](outputs.tf#L15) | IP address. | |

<!-- END TFDOC -->
8 changes: 8 additions & 0 deletions examples/cloud-operations/adfs/ansible/ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[defaults]
inventory = inventory/hosts.ini

[ssh_connection]
pipelining = True
ssh_executable = ./gssh.sh
transfer_method = piped

1 change: 1 addition & 0 deletions examples/cloud-operations/adfs/ansible/inventory/hosts.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
adfs ansible_connection=ssh ansible_shell_type=powershell
53 changes: 53 additions & 0 deletions examples/cloud-operations/adfs/ansible/playbook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright 2022 Google LLC

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# https://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

- name: Prepare
hosts: adfs
gather_facts: yes
vars_files:
- vars/vars.yaml
roles:
- role: server-setup

- name: Provision organizational units users, groups and memberships
hosts: adfs
gather_facts: no
vars_files:
- vars/vars.yaml
vars:
ansible_become: yes
ansible_become_method: runas
ansible_become_user: "SetupAdmin@{{ ad_dns_domain_name }}"
ansible_become_password: "{{ setupadmin_password }}"
roles:
- role: ad-provisioning

- name: Install AD FS
hosts: adfs
gather_facts: no
vars_files:
- vars/vars.yaml
vars:
ansible_become: yes
ansible_become_method: runas
adfssvc_password: "{{ lookup('ansible.builtin.password', '~/.adfssvc-password.txt chars=ascii_letters,digits') }}"
roles:
- role: adfs-prerequisites
vars:
ansible_become_user: "SetupAdmin@{{ ad_dns_domain_name }}"
ansible_become_password: "{{ setupadmin_password }}"
- role: adfs-installation
vars:
ansible_become_user: "adfssvc@{{ ad_dns_domain_name }}"
ansible_become_password: "{{ adfssvc_password }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
"gcp-billing-admins",
"gcp-devops",
"gcp-network-admins",
"gcp-organization-admins",
"gcp-security-admins",
"gcp-support"
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
[
{
"group": "gcp-devops",
"member": "pamela.reed"
},
{
"group": "gcp-devops",
"member": "joshua.banks"
},
{
"group": "gcp-devops",
"member": "clayton.espinoza"
},
{
"group": "gcp-devops",
"member": "maureen.morgan"
},
{
"group": "gcp-network-admins",
"member": "pamela.reed"
},
{
"group": "gcp-network-admins",
"member": "william.bowen"
},
{
"group": "gcp-network-admins",
"member": "clayton.espinoza"
},
{
"group": "gcp-network-admins",
"member": "stacy.holland"
},
{
"group": "gcp-network-admins",
"member": "joshua.banks"
},
{
"group": "gcp-network-admins",
"member": "charlene.mckenzie"
},
{
"group": "gcp-network-admins",
"member": "lisa.harris"
},
{
"group": "gcp-organization-admins",
"member": "maureen.morgan"
},
{
"group": "gcp-organization-admins",
"member": "pamela.reed"
},
{
"group": "gcp-support",
"member": "maureen.morgan"
},
{
"group": "gcp-support",
"member": "pamela.reed"
},
{
"group": "gcp-support",
"member": "lisa.harris"
},
{
"group": "gcp-support",
"member": "tina.ferguson"
},
{
"group": "gcp-support",
"member": "stacy.holland"
},
{
"group": "gcp-support",
"member": "william.bowen"
},
{
"group": "gcp-support",
"member": "clayton.espinoza"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
[
{
"first_name": "Pamela",
"last_name": "Reed",
"username": "pamela.reed",
"password": "Ig_17BbZVu"
},
{
"first_name": "Charlene",
"last_name": "Mckenzie",
"username": "charlene.mckenzie",
"password": "$y0IsMLPy5"
},
{
"first_name": "William",
"last_name": "Bowen",
"username": "william.bowen",
"password": "y882QxMHE@"
},
{
"first_name": "Joshua",
"last_name": "Banks",
"username": "joshua.banks",
"password": ")00+LN!r0$"
},
{
"first_name": "Clayton",
"last_name": "Espinoza",
"username": "clayton.espinoza",
"password": "gIf@52FqUY"
},
{
"first_name": "Stacy",
"last_name": "Holland",
"username": "stacy.holland",
"password": "da4PLSQDb^"
},
{
"first_name": "Maureen",
"last_name": "Morgan",
"username": "maureen.morgan",
"password": "V)c2Vfc%i#"
},
{
"first_name": "Lisa",
"last_name": "Harris",
"username": "lisa.harris",
"password": "0@1Oid71co"
},
{
"first_name": "Tina",
"last_name": "Ferguson",
"username": "tina.ferguson",
"password": "+f#0C#_oi6"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

- name: Read files
set_fact:
ad_users: "{{ lookup('file','users.json') | from_json }}"
ad_groups: "{{ lookup('file','groups.json') | from_json }}"
ad_memberships: "{{ lookup('file','memberships.json') | from_json }}"

- name: Create organizational units
community.windows.win_domain_ou:
name: "{{ item }}"
path: "{{ cloud_path }}"
state: present
protected: true
with_items:
- "Users"
- "Groups"

- name: Create users
community.windows.win_domain_user:
name: "{{ item.username }}"
firstname: "{{ item.first_name }}"
surname: "{{ item.last_name }}"
email: "{{ item.username }}@{{ ad_dns_domain_name }}"
sam_account_name: "{{ item.username }}"
upn: "{{ item.username }}@{{ ad_dns_domain_name }}"
password: "{{ item.password }}"
path: "OU=Users,{{ cloud_path }}"
state: present
with_items: "{{ ad_users }}"

- name: Create groups
community.windows.win_domain_group:
name: "{{ item }}"
path: "OU=Groups,{{ cloud_path }}"
scope: global
state: present
with_items: "{{ ad_groups }}"

- name: Create memberships
community.windows.win_domain_group_membership:
name: "{{ item.group }}"
members:
- "{{ item.member }}"
state: present
with_items: "{{ ad_memberships }}"

0 comments on commit 6674e06

Please sign in to comment.