dbt Mesh¶
Group 2 - Part 2
You've seen how access levels gate what mediapulse_analytics can already reach into in mediapulse_base. This part goes into the other half of dbt's governance model - groups - and asks you to think about mesh boundaries as a design decision, not just a config setting.
Exercise¶
Step 1 - Understand groups¶
- Step complete
Research how model groups work in dbt: what a group is, how a model gets assigned to one, and how many groups a single model can belong to.
Hint: One owner per model
Every model belongs to at most one group, and groups are typically used to represent a team or domain's ownership boundary. See About model governance.
Step 2 - Understand how groups and access interact¶
- Step complete
One access level is defined entirely in terms of groups. Find out which one, and what it means in practice for a model that has it.
Hint: The tightest access level
private access restricts a model to being referenced only by other models in the same group - it's a stricter boundary than "same project." See Model access.
Step 3 - Design a group structure for mediapulse_base¶
- Step complete
Looking at mediapulse_base's folder layout (ads/, news/, podcasts/, streaming/, plus the shared dim_dates), propose a set of groups that would reflect real ownership boundaries. For each group, decide which of its models should stay private, which should be protected (usable elsewhere in the project), and which should be public (usable by mediapulse_analytics or any other consuming project).
Step 4 - Actually define one group and assign it¶
- Step complete
Pick the ads domain from your proposal. Add a real group definition for it (a groups: block - this can live in any existing model YAML file in that folder, or a new file) with a name and an owner, then assign dim_campaigns and fct_ad_impressions to it. Run dbt parse (or dbt list) afterwards to confirm the project still parses cleanly with the group in place.
Hint: Where groups get defined vs. assigned
A group's definition (name, owner) is declared once under a top-level groups: key. Assigning a model to that group is a separate step, done via that model's own config. See Groups for both the definition shape and the three different places you can assign a model to one.
Step 5 - Justify the outliers¶
- Step complete
dim_dates is a calendar spine explicitly documented as meant for both projects to join to - where does it belong in your group structure, and does it need public access to make that documented intent actually true today? (Check whether it currently has that access.)
Deliverable: A proposed group-and-access map for mediapulse_base's current models, the real group definition and assignment you added for ads in step 4, and a one-line justification for any model whose access level you'd change from what it is today.
Extension¶
This is the harder, open-ended part - there's no single correct answer, and part of the exercise is noticing that.
Step 1 - Look for a mesh opportunity that doesn't exist yet¶
- Step complete
mediapulse_analytics's CRM domain (mediapulse_analytics/models/marts/crm/) has its own dim_advertisers, built entirely from local CRM seeds. mediapulse_base's dim_campaigns also carries an advertiser_id column. Neither model currently references the other, and there's no dbt Mesh dependency in that direction at all. Read both models' full column lists.
Step 2 - Argue both sides¶
- Step complete
Write a short case FOR wiring these together across the mesh boundary (what would a unified advertiser view give you that neither model gives alone?) and a short case AGAINST it (what coupling, ownership, or stability risk would you be taking on by doing so?).
Step 3 - Make a call, and defend the access implications¶
- Step complete
If you decided it's worth doing: which project should own the resulting model, what access level would the models it depends on need, and would you use private, protected, or public for the new model itself given who else might eventually want it? If you decided against it: what would need to change (in scale, in stability, in actual demand) before you'd revisit that decision?
Step 4 - Write the config you'd actually ship¶
- Step complete
Regardless of which way you argued in step 3, write out the real group: and access configuration you'd add - to dim_campaigns, to dim_advertisers, and to any new model - to make your decision concrete. If you decided the connection is worth building, also add the model-level group: config to dim_advertisers now, in mediapulse_analytics/models/marts/crm/_marts__crm__models.yml, as if your recommendation had been accepted.
Hint: Public is a commitment, not just a switch
Making a model public is treated in dbt's own governance guidance as signing up to keep its interface stable for consumers you may not control. Read the framing in About model governance before you argue for flipping access levels lightly.
Deliverable: A short design memo (a few paragraphs) making and defending your call on whether mediapulse_base's dim_campaigns and mediapulse_analytics's dim_advertisers domains should be connected via dbt Mesh, plus the real config change from step 4.
Done?
You've defined a real group structure and made a defensible call on a genuine mesh design question, backed by an actual config change rather than just an opinion.
Now head to Dynamic data masking to see where Snowflake and dbt's responsibilities split.