Closed sympmarc closed 3 months ago
Great approach, @sympmarc! Thank you for this. As we look for implementing a multi tenant scenario, there will be a setup to store configuration for multiple dedicated tenants. Let's discuss and go for a solution based on your idea. We should implement it as a YAML file.
So, what about creating a generic template (template.eps) that contains the outline of a tenant configuration -- and which is populated with tenant specific data during a setup flow ({tenantname}.yml)?
I will dig into later on...
So, what about creating a generic template (template.eps) that contains the outline of a tenant configuration -- and which is populated with tenant specific data during a setup flow ({tenantname}.yml)?
In my PR, I included .settings_template.json, intending that to be the "template" for the tenant settings.
I figure you'll want to change what's in my PR (if you reject it, I won't be offended) to fit your patterns, but by setting up a PSM1 file with the functions, we can expand the modularity of things, etc.
I really like your suggestions in #3! Let's start with your implementation and extend it afterwords (step by step):
I just converted from JSON to YAML in my PR.
What do you think about this: When we're going to refine the "modularization", shouldn't we go for this structure:
— src
— Private // contains all modules that are not shared "outside" the solution
HelperModule1.ps1
HelperModule2.ps1
....ps1
— Public // contains all modules that are accessible ("workflows")
Start-Validation.ps1
Invoke-Baselines.ps1
....ps1
Validators.psm1 // integrates all validation modules
Baselines.psm1 // integrates all baseline modules
— templates // the settings for tenant configs
tenant1.yml
tenant2.yml
tenant3.yml
Now you're getting fancy. :) You probably have thought further ahead than I have. I like where you're aiming, though.
Should the baselines be in a PSM1 file, though? Shouldn't they stand alone as YAML files so people can choose from the baseline they want to use?
Also, I'm not sure how you see the multi-tenant aspect of this working, but it seems like it would be good to optimize for a single tenant as a start.
Should the baselines be in a PSM1 file, though? Shouldn't they stand alone as YAML files so people can choose from the baseline they want to use?
Exactly. In my thoughts, Baselines.psm1
only imports the necessary modules for baseline management – as an example:
$Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue )
$Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue )
Foreach ($import in @($Public + $Private)) {
Try {
. $import.fullname
}
Catch {
Write-Error -Message "Failed to import function $( $import.fullname ): $_"
}
}
Export-ModuleMember -Function $Public.Basename
As you say, the baseline definition remains in its own yaml-file, e.g.baselines/M365.SPO-5.2.yml
The settings file (tenant.yml
) contains a reference to the baselines which are linked to the tenant:
Tenant: sympraxis # <-- I like it BTW 🤣
Baselines:
- M365.SPO
- M365.<Baseline1>
- M365.<Baseline2>
- M365.<Baseline...>
With this approach, you also can take the settings.yml
and put it in a repo – as you then have your customers' setup documented "for free"😃
BTW, I didn't intend for .settings.yml
to end up in the repo. I meant it to be excluded by .gitignore.
Yes, I know. I've understood your idea! We should then exclude the whole 'tenants' folder...
I've pushed a bunch of changes on an experimental
branch – containing a small architectural extension:
https://github.com/tmaestrini/easyGovernance/tree/experimental
What do you think about? If you agree with my extension, I would merge them into develop and main branch. See the example in the examples folder (or also on the bottom of the README) – running a validation becomes super easy! 😃
What you've done makes sense to me. It'll give us good modularity to move forward with additional approaches. Go for it!
Before you can run Engine-BaselineValidator-M365-SPO.ps1, you need to set the tenant name for
$AdminCenterURL
. Once you do that, you get into a tangle when doing a push/pull.This is something I used to do endlessly in my scripts. Now I have this scheme...
All I need to do is set the tenant in
settings.json
(below), and I'm off and running. Anywhere in my scripts I need a tenant URL, I can just use something like$dstSiteName = "https://$($tenant).sharepoint.com/sites/A"
.Would something like this make sense here? Happy to do a PR with the scaffolding if so. I expect you plan multiple validators and baselines, so this would help to make things "run ready". Since you're using YAML for the validators, we could use YAML rather than JSON for the settings file, of course.
settings.json
In Engine-BaselineValidator-M365-SPO.ps1
In UtilityFunctions.psm1