Things you didn't know you can use in your Salesforce
Applying Roles and Profiles method to compliance code
1. Applying the Roles & Profiles
Method to Compliance Code
Heston Snodgrass,
Sr. Services Delivery Engineer
March 25, 2021
2. 2
Agenda
• Writing Compliance Code is Hard
• Overview of Roles & Profiles and the Facade
Pattern
• Adapting These Patterns to Compliance Code
• Unique Hiera Interfaces
• Handling Boilerplate
• Q&A
3. 3
Writing Compliance Code is
Hard
• Code touches many parts of the node
• Can lead to a sprawling, tightly-coupled code base
• Auditing and maintaining this code can be difficult
• A lot of overlap between compliance frameworks
• Dreaded “spaghetti code”
Image: Yeh Xintong, unsplash.com
4. Design patterns are problem-solving templates for your code
• The roles & profiles method is a design pattern
• It takes inspiration from the facade pattern detailed in the “Gang of Four” book¹
• a facade is an object that serves as a front-facing interface masking more complex underlying or
structural code²
• Roles are the simple “front-end” facades, or interfaces, and profiles are the complex, “back-end”
implementations
4
Not just for software engineering interviews
Software Design Patterns
1. Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard
Helm, Ralph Johnson, and John Vlissides
2. https://en.wikipedia.org/wiki/Facade_pattern
5. 5
A Picture is Worth a Thousand Roles & Profiles
https://puppet.com/docs/pe/2019.8/osp/the_roles_and_profiles_method.html
6. Adapting
Roles &
Profiles to
Modules
There are two fundamental concepts for
adapting roles & profiles to a module:
• Interfaces - Simple Puppet classes that are interacted with
• Implementations - More complex Puppet classes / defined types
that are either declared or included by interfaces
Interfaces and implementations should be kept separate
Finally, remember to document all of your code thoroughly
6
7. 7
I’m the Interface, so That’s
What You Call Me
• Interfaces are simple and homogenized
• Interfaces names relate directly to a compliance
framework
• Interfaces only declare or include implementations
• Interfaces pass all needed parameters
Image: Pierre Chatel, unsplash.com
8. 8
That Implementation Really
Tied the Room Together
• Implementations are single-purpose and
self-contained
• Implementations DO NOT have framework-specific
data
• Exceptions can be made for default values
• Implementations are as complex as necessary
• Implementations are reusable
Image: Ant Rozetsky, unsplash.com
10. 10
This is our Compliance
Module
Simple, straight-forward, and WE know what it does.
However, I have a few questions:
• What CIS controls does this module enforce?
• Does this module enforce the CIS control “Ensure
mounting of UDF filesystem is disabled”?
• Not all nodes that need to be CIS compliant need
SSH and rsyslog configuration, is this possible?
This overly simplistic and incomplete CIS compliance
module still has fundamental issues with it. So what can
we do about all this?
11. • To adapt the roles & profiles method to our module we’ll need to refactor it
• First, we create two subdirectories in our manifests directory:
• manifests/interfaces
• manifests/implementations
• Next, we split up the implementation code into separate, self-contained classes / defined types
• Implementations are created in manifests/implementations
11
Refactoring, It’s What’s for Dinner
12. • Now, we need to create the interfaces for this code
• Interfaces are created in manifests/interfaces
• We will use the CIS control names as the interface class names
12
Let There be Interfaces
13. • Now we create an init.pp for our module. I like to refer to init.pp as the module interface
• The simplest way to do this is to just include all of our interfaces
• Standard Hiera configuration
• No scope issues from resource-like class declarations
• We could also treat init.pp just like our other interface classes and parameterize it
• This simplifies our Hiera config
• We can configure our compliance module entirely from the classifier
• Use what works best for you. Experiment and focus on configuration, maintainability, and auditability.
• Keep it as simple as feasibly possible for what you want to accomplish
13
The Module Interface
15. A New
Compliance
Framework
has Appeared!
By using our adapted roles & profiles pattern,
change is easy
• Quickly adapt to compliance framework changes
– New compliance framework, new interfaces
– Framework control names change, update interfaces
• Refactoring and maintaining the code is easier
– Backend changes don’t necessarily impact the front end
• Configuring the code now aligns directly with the controls we are
enforcing
– Makes life easier for auditors
• Onboarding new team members is easier
– Code is in small, digestible pieces
– Maps directly to the compliance framework
15
16. 16
Whole Lotta Boilerplate
One downside with this pattern is that there is a good
amount of boilerplate code. Fortunately, there’s some
tooling that can help:
• Custom PDK templates
– Uses a familiar tool
– Documented well
– Can be complex to implement generation of custom classes
• https://github.com/hsnodgrass/abide_dev_utils
– Used by the Puppet SSE team
– Works from ERB templates stored directly in your module
– I like a bit of self-promotion
17. Thank you.
And now time for our Q&A!
My contact info:
- Email: heston.snodgrass@puppet.com
- Community Slack: @Heston Snodgrass