commit
fc6265b766
|
@ -32,3 +32,5 @@ cloud_sql_proxy
|
|||
examples/cloud-operations/binauthz/tenant-setup.yaml
|
||||
examples/cloud-operations/binauthz/app/app.yaml
|
||||
env/
|
||||
examples/cloud-operations/adfs/ansible/vars/vars.yaml
|
||||
examples/cloud-operations/adfs/ansible/gssh.sh
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
# AD FS
|
||||
|
||||
This 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>"10.0.0.0/24"</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>"pd-ssd"</code> |
|
||||
| [image](variables.tf#L66) | Image. | <code>string</code> | | <code>"projects/windows-cloud/global/images/family/windows-2022"</code> |
|
||||
| [instance_type](variables.tf#L72) | Instance type. | <code>string</code> | | <code>"n1-standard-2"</code> |
|
||||
| [network_config](variables.tf#L35) | Network configuration | <code title="object({ network = string subnet = string })">object({…})</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({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L78) | Region. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [subnet_ip_cidr_block](variables.tf#L96) | Subnet IP CIDR block. | <code>string</code> | | <code>"10.0.1.0/28"</code> |
|
||||
| [zone](variables.tf#L84) | Zone. | <code>string</code> | | <code>"europe-west1-c"</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| [ip_address](outputs.tf#L15) | IP address. | |
|
||||
|
||||
<!-- END TFDOC -->
|
|
@ -0,0 +1,8 @@
|
|||
[defaults]
|
||||
inventory = inventory/hosts.ini
|
||||
|
||||
[ssh_connection]
|
||||
pipelining = True
|
||||
ssh_executable = ./gssh.sh
|
||||
transfer_method = piped
|
||||
|
|
@ -0,0 +1 @@
|
|||
adfs ansible_connection=ssh ansible_shell_type=powershell
|
|
@ -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 }}"
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"gcp-billing-admins",
|
||||
"gcp-devops",
|
||||
"gcp-network-admins",
|
||||
"gcp-organization-admins",
|
||||
"gcp-security-admins",
|
||||
"gcp-support"
|
||||
]
|
|
@ -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"
|
||||
}
|
||||
]
|
|
@ -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"
|
||||
}
|
||||
]
|
|
@ -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,0 +1,104 @@
|
|||
# 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: Create server certificate
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$Certificate = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN={{ adfs_dns_domain_name }}"}
|
||||
if(-not $Certificate) {
|
||||
$Certificate = New-SelfSignedCertificate `
|
||||
-Subject {{ adfs_dns_domain_name }} `
|
||||
-KeyAlgorithm RSA `
|
||||
-KeyLength 2048 `
|
||||
-KeyExportPolicy NonExportable `
|
||||
-KeyUsage DigitalSignature, KeyEncipherment `
|
||||
-Provider 'Microsoft Platform Crypto Provider' `
|
||||
-NotAfter (Get-Date).AddDays(365) `
|
||||
-Type SSLServerAuthentication `
|
||||
-CertStoreLocation 'Cert:\LocalMachine\My' `
|
||||
-DnsName {{ adfs_dns_domain_name }}
|
||||
}
|
||||
$Certificate.Thumbprint
|
||||
register: server_cert
|
||||
|
||||
- name: Create token signing certificate
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$Certificate = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=ADFS Signing"}
|
||||
if(-not $Certificate) {
|
||||
$Certificate = New-SelfSignedCertificate `
|
||||
-Subject "ADFS Signing" `
|
||||
-KeyAlgorithm RSA `
|
||||
-KeyLength 2048 `
|
||||
-KeyExportPolicy NonExportable `
|
||||
-KeyUsage DigitalSignature, KeyEncipherment `
|
||||
-Provider 'Microsoft RSA SChannel Cryptographic Provider' `
|
||||
-NotAfter (Get-Date).AddDays(365) `
|
||||
-DnsName {{ adfs_dns_domain_name }} `
|
||||
-CertStoreLocation 'Cert:\LocalMachine\My'
|
||||
}
|
||||
$Certificate.Thumbprint
|
||||
register: token_signing_cert
|
||||
|
||||
- name: Create AD FS DKM container
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$DkmContainer = Get-ADObject -LDAPFilter "(Objectclass=container)" -SearchBase "CN=ADFS Data,{{ cloud_path }}" -SearchScope 1
|
||||
if(-not $DkmContainer) {
|
||||
$DkmContainer.DistinguishedName
|
||||
$Name = (New-Guid).Guid
|
||||
$DkmContainer = New-ADObject `
|
||||
-Name $Name `
|
||||
-Type Container `
|
||||
-Path "CN=ADFS Data,{{ cloud_path }}" `
|
||||
-PassThru
|
||||
}
|
||||
$DkmContainer.DistinguishedName
|
||||
register: adfs_dkm_container
|
||||
|
||||
- name: Install ADFS
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
try {
|
||||
$AdfsFarm = Get-AdfsFarmInformation
|
||||
} catch [System.ServiceModel.EndpointNotFoundException] {
|
||||
$AdfsCredential = New-Object `
|
||||
-TypeName System.Management.Automation.PSCredential `
|
||||
-ArgumentList "$env:userdomain\adfssvc", (ConvertTo-SecureString {{ adfssvc_password }} -AsPlainText -Force)
|
||||
Install-ADFSFarm `
|
||||
-CertificateThumbprint {{ server_cert.output[0] }} `
|
||||
-SigningCertificateThumbprint {{ token_signing_cert.output[0] }} `
|
||||
-DecryptionCertificateThumbprint {{ token_signing_cert.output[0] }}`
|
||||
-FederationServiceName {{ adfs_dns_domain_name }} `
|
||||
-ServiceAccountCredential $AdfsCredential `
|
||||
-OverwriteConfiguration `
|
||||
-AdminConfiguration @{"DKMContainerDn"="{{ adfs_dkm_container.output[0] }}"}
|
||||
}
|
||||
no_log: yes
|
||||
|
||||
- name: Configure TLS
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
netsh http show sslcert ipport=0.0.0.0:443
|
||||
if($LastExitCode -gt 0) {
|
||||
netsh http add sslcert ipport=0.0.0.0:443 certhash={{ server_cert.output[0] }} appid="{5d89a20c-beab-4389-9447-324788eb944a}" certstorename=MY
|
||||
}
|
||||
|
||||
- name: Restart computer
|
||||
ansible.windows.win_reboot:
|
||||
|
||||
- name: Enable the Idp-Initiated Sign on page
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
Set-AdfsProperties -EnableIdpInitiatedSignonPage $true
|
|
@ -0,0 +1,45 @@
|
|||
# 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: Create AD FS service user
|
||||
community.windows.win_domain_user:
|
||||
name: "adfssvc"
|
||||
password: "{{ adfssvc_password }}"
|
||||
spn: "http/{{ adfs_dns_domain_name }}"
|
||||
path: "OU=Users,{{ cloud_path }}"
|
||||
state: present
|
||||
|
||||
- name: Add AD FS service user to local Administrators group
|
||||
ansible.windows.win_group_membership:
|
||||
name: Administrators
|
||||
members:
|
||||
- "adfssvc@{{ ad_dns_domain_name }}"
|
||||
state: present
|
||||
|
||||
- name: Create AD FS Data container
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
try {
|
||||
Get-ADObject -Identity "CN=ADFS Data,{{ cloud_path }}"
|
||||
} catch [Microsoft.ActiveDirectory.Management.ADIdentityResolutionException] {
|
||||
New-ADObject `
|
||||
-Name "ADFS Data" `
|
||||
-Type Container `
|
||||
-Path "{{ cloud_path }}"
|
||||
}
|
||||
|
||||
- name: Grant the AD FS user full control on the container
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
dsacls.exe "CN=ADFS Data,{{ cloud_path }}" /G $env:userdomain\adfssvc:GA /I:T
|
|
@ -0,0 +1,67 @@
|
|||
# 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.
|
||||
|
||||
$ApplicationGroup = Get-AdfsApplicationGroup -Name Anthos
|
||||
|
||||
$ApplicationGroupName = "Anthos"
|
||||
$ApplicationGroupIdentifier = (New-Guid).Guid
|
||||
New-AdfsApplicationGroup -Name $ApplicationGroupName `
|
||||
-ApplicationGroupIdentifier $ApplicationGroupIdentifier
|
||||
|
||||
$ServerApplicationName = "$ApplicationGroupName Server App"
|
||||
$ServerApplicationIdentifier = (New-Guid).Guid
|
||||
$RelyingPartyTrustName = "Anthos"
|
||||
$RelyingPartyTrustIdentifier = (New-Guid).Guid
|
||||
$RedirectURI1 = "http://localhost:1025/callback"
|
||||
$RedirectURI2 = "https://console.cloud.google.com/kubernetes/oidc"
|
||||
|
||||
$ADFSApp = Add-AdfsServerApplication -Name $ServerApplicationName `
|
||||
-ApplicationGroupIdentifier $ApplicationGroupIdentifier `
|
||||
-RedirectUri $RedirectURI1,$RedirectURI2 `
|
||||
-Identifier $ServerApplicationIdentifier `
|
||||
-GenerateClientSecret
|
||||
|
||||
$IssuanceTransformRules = @'
|
||||
@RuleTemplate = "LdapClaims"
|
||||
@RuleName = "groups"
|
||||
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
|
||||
=> issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/claims/Group"), query = ";tokenGroups(domainQualifiedName);{0}", param = c.Value);
|
||||
'@
|
||||
|
||||
Add-AdfsRelyingPartyTrust -Name $RelyingPartyTrustName `
|
||||
-Identifier $RelyingPartyTrustIdentifier `
|
||||
-AccessControlPolicyName "Permit everyone" `
|
||||
-IssuanceTransformRules "$IssuanceTransformRules"
|
||||
|
||||
Grant-ADFSApplicationPermission -ClientRoleIdentifier $ServerApplicationIdentifier `
|
||||
-ServerRoleIdentifier $RelyingPartyTrustIdentifier `
|
||||
-ScopeName "allatclaims", "openid"
|
||||
|
||||
$ClientId = $ADFSApp.Identifier
|
||||
$ClientSecret = $ADFSApp.ClientSecret
|
||||
|
||||
@"
|
||||
authentication:
|
||||
oidc:
|
||||
clientID: $ADFSApp.Identifier
|
||||
clientSecret: $ADFSApp.ClientSecret
|
||||
extraParams: resource=$RelyingPartyTrustIdentifier
|
||||
group: groups
|
||||
groupPrefix: ""
|
||||
issuerURI: https://{{ adfs_dns_domain_name }}/adfs
|
||||
kubectlRedirectURL: $RedirectURI1
|
||||
scopes: openid
|
||||
username: upn
|
||||
usernamePrefix: ""
|
||||
"@
|
|
@ -0,0 +1,86 @@
|
|||
# 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: Install Windows features
|
||||
ansible.windows.win_feature:
|
||||
name: "{{ item.feature }}"
|
||||
include_mamangement_tools: "{{ item.include_management_tools }}"
|
||||
state: present
|
||||
with_items:
|
||||
- { "feature": "RSAT-AD-Tools", "include_management_tools": false }
|
||||
- { "feature": "GPMC", "include_management_tools": false }
|
||||
- { "feature": "RSAT-DNS-Server", "include_management_tools": false }
|
||||
- { "feature": "ADFS-Federation", "include_management_tools": true }
|
||||
- { "feature": "RSAT-AD-PowerShell", "include_management_tools": false }
|
||||
- { "feature": "RSAT-ADDS-Tools", "include_management_tools": false }
|
||||
|
||||
- name: Check if SetupAdmin password has already been reset
|
||||
stat:
|
||||
path: ~/.setupadmin-password.txt
|
||||
register: setupadmin_password_file_check
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Set AD SetupAdmin password fact
|
||||
set_fact:
|
||||
setupadmin_password: "{{ lookup('file', '~/.setupadmin-password.txt') }}"
|
||||
no_log: true
|
||||
when: setupadmin_password_file_check.stat.exists
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Reset AD deletegated admin password
|
||||
shell: >
|
||||
gcloud active-directory domains reset-admin-password {{ ad_dns_domain_name }}
|
||||
--project={{ project_id }}
|
||||
--quiet
|
||||
--format "value(password)"
|
||||
register: setupadmin_password_reset
|
||||
no_log: yes
|
||||
when: not setupadmin_password_file_check.stat.exists
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Set AD SetupAdmin password fact
|
||||
set_fact:
|
||||
setupadmin_password: "{{ setupadmin_password_reset.stdout }}"
|
||||
no_log: yes
|
||||
when: not setupadmin_password_file_check.stat.exists
|
||||
|
||||
- name: Creating a file setupadmin password
|
||||
copy:
|
||||
dest: ~/.setupadmin-password.txt
|
||||
content: "{{ setupadmin_password }}"
|
||||
when: not setupadmin_password_file_check.stat.exists
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Add computer to domain
|
||||
ansible.windows.win_domain_membership:
|
||||
dns_domain_name: "{{ ad_dns_domain_name }}"
|
||||
domain_admin_user: "SetupAdmin@{{ ad_dns_domain_name }}"
|
||||
domain_admin_password: "{{ setupadmin_password }}"
|
||||
state: domain
|
||||
register: domain_state
|
||||
|
||||
- name: Restart computer
|
||||
ansible.windows.win_reboot:
|
||||
when: domain_state.reboot_required
|
||||
|
||||
- name: Get Domain info
|
||||
community.windows.win_domain_object_info:
|
||||
filter: ObjectClass -eq 'domain'
|
||||
domain_username: "SetupAdmin@{{ ad_dns_domain_name }}"
|
||||
domain_password: "{{ setupadmin_password }}"
|
||||
register: ad_domain
|
||||
|
||||
- name: Set facts
|
||||
set_fact:
|
||||
cloud_path: "OU=Cloud,{{ ad_domain.objects[0].DistinguishedName }}"
|
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
|
@ -0,0 +1,191 @@
|
|||
# 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.
|
||||
|
||||
locals {
|
||||
prefix = (var.prefix == null || var.prefix == "") ? "" : "${var.prefix}-"
|
||||
}
|
||||
|
||||
module "project" {
|
||||
source = "../../../modules/project"
|
||||
billing_account = (
|
||||
var.project_create != null
|
||||
? var.project_create.billing_account_id
|
||||
: null
|
||||
)
|
||||
parent = (
|
||||
var.project_create != null
|
||||
? var.project_create.parent
|
||||
: null
|
||||
)
|
||||
prefix = var.project_create == null ? null : var.prefix
|
||||
name = var.project_id
|
||||
services = [
|
||||
"compute.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
"managedidentities.googleapis.com"
|
||||
]
|
||||
}
|
||||
|
||||
module "vpc" {
|
||||
count = var.network_config == null ? 1 : 0
|
||||
source = "../../../modules/net-vpc"
|
||||
project_id = module.project.project_id
|
||||
name = "${local.prefix}vpc"
|
||||
subnets = [
|
||||
{
|
||||
ip_cidr_range = var.subnet_ip_cidr_block
|
||||
name = "subnet"
|
||||
region = var.region
|
||||
secondary_ip_range = null
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
resource "google_active_directory_domain" "ad_domain" {
|
||||
project = module.project.project_id
|
||||
domain_name = var.ad_dns_domain_name
|
||||
locations = [var.region]
|
||||
authorized_networks = [module.vpc[0].network.id]
|
||||
reserved_ip_range = var.ad_ip_cidr_block
|
||||
}
|
||||
|
||||
module "server" {
|
||||
source = "../../../modules/compute-vm"
|
||||
project_id = module.project.project_id
|
||||
zone = var.zone
|
||||
name = "adfs"
|
||||
instance_type = var.instance_type
|
||||
network_interfaces = [{
|
||||
network = var.network_config == null ? module.vpc[0].self_link : var.network_config.network
|
||||
subnetwork = var.network_config == null ? module.vpc[0].subnet_self_links["${var.region}/subnet"] : var.network_config.subnet
|
||||
nat = false
|
||||
addresses = null
|
||||
}]
|
||||
metadata = {
|
||||
# Enables OpenSSH in the Windows instance
|
||||
sysprep-specialize-script-cmd = "googet -noconfirm=true update && googet -noconfirm=true install google-compute-engine-ssh"
|
||||
enable-windows-ssh = "TRUE"
|
||||
# Set the default OpenSSH shell to Powershell
|
||||
windows-startup-script-ps1 = <<EOT
|
||||
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" `
|
||||
-Name DefaultShell `
|
||||
-Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" `
|
||||
-PropertyType String `
|
||||
-Force
|
||||
EOT
|
||||
}
|
||||
service_account_create = true
|
||||
boot_disk = {
|
||||
image = var.image
|
||||
type = var.disk_type
|
||||
size = var.disk_size
|
||||
}
|
||||
group = {
|
||||
named_ports = {
|
||||
http = 443
|
||||
}
|
||||
}
|
||||
tags = ["https-server"]
|
||||
}
|
||||
|
||||
module "glb" {
|
||||
source = "../../../modules/net-glb"
|
||||
name = "${local.prefix}glb"
|
||||
project_id = module.project.project_id
|
||||
|
||||
https = true
|
||||
reserve_ip_address = true
|
||||
|
||||
ssl_certificates_config = {
|
||||
adfs-domain = {
|
||||
domains = [
|
||||
"${var.adfs_dns_domain_name}"
|
||||
],
|
||||
unmanaged_config = null
|
||||
}
|
||||
}
|
||||
|
||||
target_proxy_https_config = {
|
||||
ssl_certificates = [
|
||||
"adfs-domain"
|
||||
]
|
||||
}
|
||||
|
||||
backend_services_config = {
|
||||
adfs-group-backend = {
|
||||
bucket_config = null
|
||||
enable_cdn = false
|
||||
cdn_config = null
|
||||
group_config = {
|
||||
backends = [
|
||||
{
|
||||
group = module.server.group.id
|
||||
options = null
|
||||
}
|
||||
],
|
||||
health_checks = ["hc"]
|
||||
log_config = {
|
||||
enable = true
|
||||
sample_rate = 1
|
||||
}
|
||||
options = {
|
||||
affinity_cookie_ttl_sec = null
|
||||
custom_request_headers = null
|
||||
custom_response_headers = null
|
||||
connection_draining_timeout_sec = null
|
||||
load_balancing_scheme = null
|
||||
locality_lb_policy = null
|
||||
port_name = null
|
||||
security_policy = null
|
||||
session_affinity = null
|
||||
timeout_sec = null
|
||||
circuits_breakers = null
|
||||
consistent_hash = null
|
||||
iap = null
|
||||
protocol = "HTTPS"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
health_checks_config = {
|
||||
hc = {
|
||||
type = "tcp"
|
||||
logging = true
|
||||
options = null
|
||||
check = {
|
||||
port_name = "http"
|
||||
port_specification = "USE_NAMED_PORT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "local_file" "vars_file" {
|
||||
content = templatefile("${path.module}/templates/vars.yaml.tpl", {
|
||||
project_id = var.project_id
|
||||
ad_dns_domain_name = var.ad_dns_domain_name
|
||||
adfs_dns_domain_name = var.adfs_dns_domain_name
|
||||
})
|
||||
filename = "${path.module}/ansible/vars/vars.yaml"
|
||||
file_permission = "0666"
|
||||
}
|
||||
|
||||
resource "local_file" "gssh_file" {
|
||||
content = templatefile("${path.module}/templates/gssh.sh.tpl", {
|
||||
zone = var.zone
|
||||
project_id = var.project_id
|
||||
})
|
||||
filename = "${path.module}/ansible/gssh.sh"
|
||||
file_permission = "0777"
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
# 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.
|
||||
|
||||
output "ip_address" {
|
||||
description = "IP address."
|
||||
value = module.glb.ip_address
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
# 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.
|
||||
|
||||
from textwrap import indent
|
||||
import click
|
||||
import json
|
||||
import random
|
||||
from faker import Faker
|
||||
|
||||
ENCODING = 'UTF8'
|
||||
|
||||
FIELD_USER_FIRST_NAME = 'first_name'
|
||||
FIELD_USER_LAST_NAME = 'last_name'
|
||||
FIELD_USER_USERNAME = 'username'
|
||||
FIELD_USER_PASSWORD = 'password'
|
||||
|
||||
FIELD_MEMBERSHIP_GROUP = 'group'
|
||||
FIELD_MEMBERSHIP_MEMBER = 'member'
|
||||
|
||||
fake = Faker()
|
||||
|
||||
@ click.group()
|
||||
def cli():
|
||||
pass
|
||||
|
||||
@ cli.command()
|
||||
@ click.option(
|
||||
"--num-users",
|
||||
help="Number of users to create",
|
||||
default=10,
|
||||
)
|
||||
@click.option(
|
||||
"--output-file",
|
||||
help="Output file",
|
||||
default="users.json",
|
||||
)
|
||||
def create_users(num_users, output_file):
|
||||
rows = []
|
||||
for i in range(1, num_users):
|
||||
row = {}
|
||||
row[FIELD_USER_FIRST_NAME] = fake.first_name()
|
||||
row[FIELD_USER_LAST_NAME] = fake.last_name()
|
||||
row[FIELD_USER_USERNAME] = row[FIELD_USER_FIRST_NAME].lower() + "." + \
|
||||
row[FIELD_USER_LAST_NAME].lower()
|
||||
row[FIELD_USER_PASSWORD] = fake.password()
|
||||
rows.append(row)
|
||||
write_json(output_file, rows)
|
||||
|
||||
@cli.command()
|
||||
@click.option(
|
||||
"--users-file",
|
||||
help="Users file",
|
||||
default="users.json",
|
||||
)
|
||||
@click.option(
|
||||
"--groups-file",
|
||||
help="Groups file",
|
||||
default="groups.json",
|
||||
)
|
||||
@click.option(
|
||||
"--output-file",
|
||||
help="Output file",
|
||||
default="memberships.json",
|
||||
)
|
||||
def create_memberships(users_file, groups_file, output_file):
|
||||
users = read_json(users_file)
|
||||
groups = read_json(groups_file)
|
||||
rows = []
|
||||
for group in groups:
|
||||
members = random.sample(users, random.randint(0, len(users) - 1))
|
||||
for member in members:
|
||||
row = {}
|
||||
row[FIELD_MEMBERSHIP_GROUP] = group
|
||||
row[FIELD_MEMBERSHIP_MEMBER] = member[FIELD_USER_USERNAME]
|
||||
rows.append(row)
|
||||
write_json(output_file, rows)
|
||||
|
||||
def write_json(file, rows):
|
||||
with open(file, 'w') as f:
|
||||
json.dump(rows, f, indent=2)
|
||||
|
||||
def read_json(file):
|
||||
with open(file, 'r', encoding='UTF8') as f:
|
||||
return json.load(f)
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
|
@ -0,0 +1,3 @@
|
|||
argparse==1.4.0
|
||||
Faker==13.3.2
|
||||
click==8.0.4
|
|
@ -0,0 +1,66 @@
|
|||
# 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.
|
||||
|
||||
param($DnsName)
|
||||
|
||||
$ApplicationGroup = Get-AdfsApplicationGroup -Name Anthos
|
||||
|
||||
$ApplicationGroupName = "Anthos"
|
||||
$ApplicationGroupIdentifier = (New-Guid).Guid
|
||||
New-AdfsApplicationGroup -Name $ApplicationGroupName `
|
||||
-ApplicationGroupIdentifier $ApplicationGroupIdentifier
|
||||
|
||||
$ServerApplicationName = "$ApplicationGroupName Server App"
|
||||
$ServerApplicationIdentifier = (New-Guid).Guid
|
||||
$RelyingPartyTrustName = "Anthos"
|
||||
$RelyingPartyTrustIdentifier = (New-Guid).Guid
|
||||
$RedirectURI1 = "http://localhost:1025/callback"
|
||||
$RedirectURI2 = "https://console.cloud.google.com/kubernetes/oidc"
|
||||
|
||||
$ADFSApp = Add-AdfsServerApplication -Name $ServerApplicationName `
|
||||
-ApplicationGroupIdentifier $ApplicationGroupIdentifier `
|
||||
-RedirectUri $RedirectURI1,$RedirectURI2 `
|
||||
-Identifier $ServerApplicationIdentifier `
|
||||
-GenerateClientSecret
|
||||
|
||||
$IssuanceTransformRules = @'
|
||||
@RuleTemplate = "LdapClaims"
|
||||
@RuleName = "groups"
|
||||
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
|
||||
=> issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/claims/Group"), query = ";tokenGroups(domainQualifiedName);{0}", param = c.Value);
|
||||
'@
|
||||
|
||||
Add-AdfsRelyingPartyTrust -Name $RelyingPartyTrustName `
|
||||
-Identifier $RelyingPartyTrustIdentifier `
|
||||
-AccessControlPolicyName "Permit everyone" `
|
||||
-IssuanceTransformRules "$IssuanceTransformRules"
|
||||
|
||||
Grant-ADFSApplicationPermission -ClientRoleIdentifier $ServerApplicationIdentifier `
|
||||
-ServerRoleIdentifier $RelyingPartyTrustIdentifier `
|
||||
-ScopeName "allatclaims", "openid"
|
||||
|
||||
@"
|
||||
authentication:
|
||||
oidc:
|
||||
clientID: $($ADFSApp.Identifier)
|
||||
clientSecret: $($ADFSApp.ClientSecret)
|
||||
extraParams: resource=$RelyingPartyTrustIdentifier
|
||||
group: groups
|
||||
groupPrefix: ""
|
||||
issuerURI: https://$DnsName/adfs
|
||||
kubectlRedirectURL: $RedirectURI1
|
||||
scopes: openid
|
||||
username: upn
|
||||
usernamePrefix: ""
|
||||
"@
|
|
@ -0,0 +1,30 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# 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.
|
||||
|
||||
host="$${@: -2: 1}"
|
||||
cmd="$${@: -1: 1}"
|
||||
|
||||
gcloud_args="
|
||||
--tunnel-through-iap
|
||||
--zone=${zone}
|
||||
--project=${project_id}
|
||||
--quiet
|
||||
--no-user-output-enabled
|
||||
--
|
||||
-C
|
||||
"
|
||||
|
||||
exec gcloud compute ssh "$host" $gcloud_args "$cmd"
|
|
@ -0,0 +1,17 @@
|
|||
# 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.
|
||||
|
||||
project_id: ${project_id}
|
||||
ad_dns_domain_name: ${ad_dns_domain_name}
|
||||
adfs_dns_domain_name: ${adfs_dns_domain_name}
|
|
@ -0,0 +1,100 @@
|
|||
# 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.
|
||||
|
||||
variable "project_create" {
|
||||
description = "Parameters for the creation of the new project."
|
||||
type = object({
|
||||
billing_account_id = string
|
||||
parent = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Host project ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix for the resources created."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "network_config" {
|
||||
description = "Network configuration"
|
||||
type = object({
|
||||
network = string
|
||||
subnet = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "ad_dns_domain_name" {
|
||||
description = "AD DNS domain name."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "adfs_dns_domain_name" {
|
||||
description = "ADFS DNS domain name."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "disk_size" {
|
||||
description = "Disk size."
|
||||
type = number
|
||||
default = 50
|
||||
}
|
||||
|
||||
variable "disk_type" {
|
||||
description = "Disk type."
|
||||
type = string
|
||||
default = "pd-ssd"
|
||||
}
|
||||
|
||||
variable "image" {
|
||||
description = "Image."
|
||||
type = string
|
||||
default = "projects/windows-cloud/global/images/family/windows-2022"
|
||||
}
|
||||
|
||||
variable "instance_type" {
|
||||
description = "Instance type."
|
||||
type = string
|
||||
default = "n1-standard-2"
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region."
|
||||
type = string
|
||||
default = "europe-west1"
|
||||
}
|
||||
|
||||
variable "zone" {
|
||||
description = "Zone."
|
||||
type = string
|
||||
default = "europe-west1-c"
|
||||
}
|
||||
|
||||
variable "ad_ip_cidr_block" {
|
||||
description = "Managed AD IP CIDR block."
|
||||
type = string
|
||||
default = "10.0.0.0/24"
|
||||
}
|
||||
|
||||
variable "subnet_ip_cidr_block" {
|
||||
description = "Subnet IP CIDR block."
|
||||
type = string
|
||||
default = "10.0.1.0/28"
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
# 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.
|
||||
|
||||
terraform {
|
||||
required_version = ">= 1.1.0"
|
||||
required_providers {
|
||||
local = {
|
||||
version = ">= 2.2.3"
|
||||
}
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 4.17.0"
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 4.17.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# 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
|
||||
#
|
||||
# http://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.
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
module "test" {
|
||||
source = "../../../../../examples/cloud-operations/adfs"
|
||||
project_create = var.project_create
|
||||
project_id = var.project_id
|
||||
ad_dns_domain_name = var.ad_dns_domain_name
|
||||
adfs_dns_domain_name = var.adfs_dns_domain_name
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
# 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.
|
||||
|
||||
# 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.
|
||||
|
||||
variable "project_create" {
|
||||
type = object({
|
||||
billing_account_id = string
|
||||
parent = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
type = string
|
||||
default = "my-project"
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "network_config" {
|
||||
type = object({
|
||||
network = string
|
||||
subnet = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "ad_dns_domain_name" {
|
||||
type = string
|
||||
default = "example.com"
|
||||
}
|
||||
|
||||
variable "adfs_dns_domain_name" {
|
||||
type = string
|
||||
default = "adfs.example.com"
|
||||
}
|
||||
|
||||
variable "disk_size" {
|
||||
type = number
|
||||
default = 50
|
||||
}
|
||||
|
||||
variable "disk_type" {
|
||||
type = string
|
||||
default = "pd-ssd"
|
||||
}
|
||||
|
||||
variable "image" {
|
||||
type = string
|
||||
default = "projects/windows-cloud/global/images/family/windows-2022"
|
||||
}
|
||||
|
||||
variable "instance_type" {
|
||||
type = string
|
||||
default = "n1-standard-2"
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
type = string
|
||||
default = "europe-west1"
|
||||
}
|
||||
|
||||
variable "zone" {
|
||||
type = string
|
||||
default = "europe-west1-c"
|
||||
}
|
||||
|
||||
variable "ad_ip_cidr_block" {
|
||||
type = string
|
||||
default = "10.0.0.0/24"
|
||||
}
|
||||
|
||||
variable "subnet_ip_cidr_block" {
|
||||
type = string
|
||||
default = "10.0.1.0/28"
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
# 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
|
||||
#
|
||||
# http://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.
|
||||
|
||||
def test_resources(e2e_plan_runner):
|
||||
"Test that plan works and the numbers of resources is as expected."
|
||||
modules, resources = e2e_plan_runner()
|
||||
assert len(modules) == 4
|
||||
assert len(resources) == 16
|
Loading…
Reference in New Issue