[Scott] Good morning,
and welcome to my session
on how to level up your Drupal
My name is Scott Weston.
I'm a principal Drupal
architect at Bounteous.
I've been doing Drupal since about 2007.
My biggest piece of housekeeping,
yes, the slides are available.
They're on the mid.camp site right now.
So feel free to download those
and use those as reference.
Like I said, I'm with Bounteous.
We're a company that builds
big picture digital solutions
for some big names.
Some of the logos I'm sure
you've recognized there.
Just a little bit about what
we're going to be talking
about today is really solving
a problem or answering
questions in one way.
And the problem is how
can you operate Drupal
environments such as dev, stage, and prod
for one site with different configurations
in each of those?
And at the same time maintain your sanity.
That's kinda the driving force for me
as I progress through
Drupal 8 from the early days
of Drupal 8, configuration
management out of the box
is kind of heavy-handed,
so I feel over time we've
developed a nice approach
to configuration management that solves
the majority of the
challenges that we have.
A little bit about what we're gonna do.
We're gonna talk through
a hypothetical scenario
that's gonna be very contrived.
It's not gonna be a real-world scenario.
Then we're gonna talk
about the tools that I use
in approaching the scenario.
And then we're gonna talk
about my favorite recipe,
The Config MISO.
Once we get through that,
then we'll actually, if
time allows, hopefully
we'll have some time to do a hands-on demo
because we know how awesome
those go during presentations.
So I have a lot to pack
in in the next 27 minutes,
so fasten your seatbelt
'cause we're gonna slam
on the accelerator here.
All right, so the scenario
that I wanna present to you
today is just a garden variety website.
We have dev, staging, and
production environments.
And we have some needs that we've put
into a spreadsheet here
about what we want different
between those as far
as configuration goes.
A couple things to point
out here would be like
for development, we want the
devel module devel generate,
we want Webprofiler
turned on in case we need
to do anything with that on
the development environment,
but in staging and production
we don't want those turned on.
Another example would be for Robots.txt.
Robots.txt we want to always
have it disallow everything
for search engine
crawlers on dev and stage
in case they get to it,
but we want to give the
content or site administrator
the ability to edit
Robots.txt as they need.
And then just for developer
sanity we want to have
some color indication of
what environment we're on,
so green for dev, yellow for
stage, red for production.
And then on this hypothetical site we used
blocks everywhere to augment content,
so we really don't want to manage those
with the default configuration management,
so we just want to basically tell
configuration management just
don't do anything with blocks.
Don't try to manage those blocks for us.
We'll just keep that
in active configuration
in the database.
My tip here is make a spreadsheet,
share it with the team,
make sure you have
conversations around it,
socialize it so that everybody
knows what the approach is
for configuration management
so that if you have
a developer making some changes,
what they change meets
these expectations as far as
when they push code to
a different environment
or they do a config
import to get our site.
Some of the tools that I
use in this may be familiar.
We have configuration ignore.
Spoiler, it helps you
ignore configuration.
There's also a configuration split,
and this is where a lot
of the magic happens
in having modules and
configuration different
per environment.
Both of those do require config filter,
which basically acts as a traffic cop
from the file system when you're
comporting configurations,
so it knows whether to actually
pass it into the system
for making it the active configuration.
Or if it just kinda
throws it out the window
and says don't worry about that.
There's also a tip that I have here
is the configuration split
module user interface
has a lot of select boxes on it.
So using something like chosen,
which will, if we get to the demo today,
I'll be able to show you,
it makes your life a lot
easier than scrolling
through hundreds of items in
a multi-select select box.
And then if you are heavy on web forms,
there is a web form config ignore.
I personally haven't used it.
I just am aware of it and
what it does is it will allow
for the import of new web forms,
so if you develop a new web form on dev,
and deploy that to production,
you can import that,
but then on subsequent changes to it,
it will not import it.
So it's like a one-time only import
into a specific environment.
One of the keys to
success in this approach
is to be able to reliably
determine what environment
that a particular site
is operating within.
Is it on the dev server or is
it on the production server?
If you use one of the
larger hosting companies,
two I've noted here are
Acquia and Pantheon,
they actually have an environment variable
that tells you what environment that site
is operating within.
Essentially what we're gonna
do is we're gonna leverage
this in our settings file
to be able to kind of do our
own coordination of what configuration
we are going to enable and
then go over and override.
So if you aren't hosting
on one of these two,
check it with your support docs.
If you're self-hosting,
come up with a scheme
that you can reliably follow to determine
what environments that you have operating.
So, now we get to the
cooking portion of the show.
The config miso.
It's just an acronym that
helps me keep in mind
what we're dealing with.
We're dealing with core
configuration management,
configuration ignore,
configuration splits,
and configuration overrides.
The configuration
management is just the core
Drupal configuration management,
so it's your drush config
export, config import.
It's just if it's something
that is going to be the
same on every environment,
let core manage that for you
'cause that's what it does
and it does that really really well.
Then we have configuration ignore,
and this is basically you can identify
configurations that
you don't want imported
into your site.
So in our example we have block instances
we don't want to import.
So if a content manager is adding blocks
to a production site,
when we run drush config import,
it's not going to blow
away those block instances.
It's not going to try to
make the block instances
that may exist in code part
of the production site.
And you can be very specific
with that configuration
that you ignore or you could also be very,
you could use wild cards to capture
a good chunk of configuration.
One thing to note,
and this one of those don't panic things,
if you have configuration ignore enabled,
and you do something in dev
like you create some blocks
just for testing or whatever
and you do a config export,
those blocks will still
get exported even though
they are ignored.
It's on the import where the
ignore actually takes place.
So you could do things
like some good ignore rules
or something like that if you wanna keep
the code base nice and clean.
A couple of tips with config ignore,
number one is don't ignore config ignore.
(laughter)
That is just asking for problems.
And also don't ignore core.extension.
That is what modules are on or off.
If you need to change
those per environment,
the next step is where
that comes into play.
So I think I kinda spoke
to these just a moment ago,
so block.block.star will get
rid of all your block instances
out of config import as well
as if you use robots text
module to manage the robots.txt file.
If you do robotstxt.settings,
those will be ignored for you as well.
You can get really,
really specific and say,
we want content admins to be
able to change the language
of the password reset email that goes out,
but we don't want to
manage that in config.
You can get very specific
with what you put
into that config ignore configuration.
So next we have configuration split.
This is a module that you would leverage
when you have configuration
in different environments
that you want to be different.
Basically what config split
does is it uses config filter
and it basically intercepts
on config export.
Config split export, the
configuration that you have
identified that you want to be different.
And I'll actually store that
in a different directory.
On the import side of things,
if a split is active,
the things in that folder
are going to get imported
into that environment.
If it's not active, it
will be disregarded.
In the case of a development environment
with the devel and
webprofiler modules enabled,
you'll want that split to be active
on just the dev environment
so that when you do
a config import, those
configurations for those modules
the modules would be enabled,
and then also that
configuration that you've set up
for those modules would be active,
and then if the split is inactive
on staging and production,
those modules don't even become enabled
and you don't have to worry about them.
Again this is where leveraging
the environment variable will help.
In general there are two kinds of splits.
Personally I don't like the
naming conventions for these,
but I'm okay with it.
The first one is a complete split,
and this is module is on or off
and all of the configuration
comes along for the ride
if it's turned on.
So you could have specific settings,
let's say for devel generate
or devel module enable,
in general and those
settings will be coming in
when you do the import.
Then there's also the
conditional config split,
and this is where you
can kind of fine tune
what configuration would be in play.
So example there, I think
we'll see it on the next slide,
is we want no caching turned on
in the system performance page for dev,
but we really wanna crank
it to 11 on production.
So you can have the
performance modules enabled
but have different settings
on those config forms
essentially in different environments.
Then we have configuration
overrides and these go
all the way back in Drupal history
to hard coding settings and
settings.php that you need.
Use these in cases where
you don't want a content
administrator to
inadvertently or intentionally
change one of those values.
If it's in the settings
file, it is basically
active configuration.
Some examples that I
have here would be using
the robots text module to always tell it
on dev and staging,
set engine crawling to
disallow everything.
If you have a google tag manager,
you could hard code that or some other
api key, you could hard
code those into settings.
Then it would literally
take a code deployment
to affect that change.
And then also a moment ago we were talking
about the config splits
being active or inactive,
in here is where I recommend
that you keep track
of if something is active or not.
There's a configuration split setting
that you can make something
active or inactive
in that environment.
I recommend just turning
them all off and only
relying on settings.php to turn them on
so that you can be sure
that it's not going
to inadvertently be
active on an environment
that you don't intend it to be.
My solution here.
So taking that spreadsheet from, I think,
the second slide we can look
at the different approaches
that we can take for
each of those line items.
For the develop module and
the webprofiler module,
we'll use conflig split.
For the robots.txt we're going to do,
kind of mix things up and say,
we're going to do config
ignore for dev and stage
and then we are, which
would be, sorry, override
for dev and stage.
Let me correct that.
Doing an override for dev and stage
and then doing an ignore for production.
And then for the environment indicators
green, yellow, red, we're
going to do overrides for that
in the settings file.
And then config ignore
across the board for ignoring
the block instances.
To get this going, and
to get it up and running,
kinda need to follow
through these steps here.
And this is my approach,
and this is my way
of approaching this problem in general.
So this is definitely one solution,
and I know that it works,
so I'm not saying you
have to do it this way,
but this is how I do it.
The first is to set up
the configuration ignores,
so enable the module,
configure those and then we'll
update the settings.php file
with the environment detection.
Then we'll go through and
create the directories
for the config split,
and then we will go in and
configure those splits,
get those exported,
and then create the specific overrides.
The config ignores, again,
just enable the module.
If you go to admin config
development configuration ignore,
in the configuration management section,
there's a new tab for ignore.
And you just put those patterns of things
that you want to ignore in there.
You can get some good
guidance about what strings
to put in there by
looking at the yaml files.
If you want to ignore an entire yaml file,
just drop the .yaml
off and put it in here.
If you want to ignore something
very specific in there,
just build the array.
Put the name of the yaml file in there
and then build that array
in the dot notation here
to get to the specific
setting you want to ignore.
Second step was enabling that dev,
the environment detection switch.
I have two code snippets
here on the screen.
The first one on the left
is basically grabbing
the environment variable.
In this case from Acquia
and if we don't find
that environment variable
I'm just setting it to dev.
That way my local, for example,
and dev are going to
be very closely aligned
if not exactly aligned when
it comes to configuration.
And then on the right I kinda
stubbed out just a case
statement to help determine
where to drop my config overrides here.
Next would be to create those directories,
so just a make directory or make directory
command will do that.
I recommend making them
easily identifiable
in their name
and the config split maintainers recommend
putting those as a
sibling directory to your
main config sync directory.
In this case I have it actually
outside of the dock root at the repo root,
so it's not (mumbles) the fault files area
and just have those
set up and ready to go.
Two things to note there,
config split module
will not make the directory.
It will kinda bark at
you if it doesn't find
the directory that you
tell it to export to.
And then when it does that first export,
it will create the ht
access file that blocks
random browsing into that directory.
I think we have time.
I'm going to hop into
the demonstration portion
of the cooking show.
And so what we're gonna
do is basically create one
of these config splits.
Already we've got the
settings.php updated,
we've got our config ignore in place,
and we've got the directories made,
so hopefully you guys can see this.
I've got the, over here I
have the directories made.
And here I have the configurations set up.
And like any good cooking
show, I've prepared some things
for you already since we can't
cook a turkey in 20 minutes.
Here I have the environment
detection and the switch here,
so I have the environment
indicator set up for dev,
and I have one for test
that I'm hiding here.
Down here we have production,
and so when we go over and
I'm going to need to open
my browser here at this moment.
There we are.
It's magic, it's right there.
So here I have just a
local setup running dev,
and we can tell it's dev
because I have the green banner
at the top since that's
what we're wanting to do.
So we're going to make a
new configurations split
for production.
So looking back at our steps,
I need to, in this case,
artificially set my local
to be production so I can
do the configuration changes
I want and get those exported to code
so that when that code
actually gets up to production
everything will be fine.
I am going to artificially
set this to prod,
and the key with making any
changes to the settings file
is to always do a drush cache rebuild,
so it will pick that up.
So when that runs and we hit refresh,
and that eventually
refreshes we'll see same page
but now we'll have the red
banner at the top of the page.
Live demos are awesome.
So we have that.
In this example let's say
that we want to make sure
that we have syslog turned on
and we'll turn that module on,
so getting back to that spreadsheet,
we wanted db logging turned
on for dev and stage.
And then syslog only for production.
So I've got syslog enabled now,
and make any other configuration
changes that you want
specific to your production
environment here,
so under configuration I'm
going to go to performance.
And I'm going to set the caching
all the way up and hit save.
So we have that done now,
so I now have my configuration
that I want to manage
for production set up
for our example here,
so I'm gonna hop over back
to the config split arena.
And I'm gonna make a
new configuration split,
and we're gonna make it,
we're gonna call it
production, cleverly enough.
And then in our folder we put in the path
that we set up for that.
Again, my recommendation, uncheck active
so that it's not turned on by accident.
And then in the complete split,
we want to do the syslog module.
And then in conditional split,
we wanted that performance setting,
so we did system.performance.
Pardon me.
Another setting that I
go against the default
is there is a checkbox here
for split only when different.
So basically it will
keep a setting in active
main config sync until you
make any changes to it.
Make changes to it and
then it will make those
splits for you.
I do it this way just so it's broken out,
it's clean, it's self-contained
in that environment.
And if you're going to
the care to create a split
for a specific setting,
the question I ask myself
is why would I not want
to just go ahead and
manage it wholly as a split
rather than having it the same in a couple
different environments potentially?
So I'm gonna hit save.
So now I have this configuration saved.
And then what I did here
in my settings at php file
as part of the pre-show,
I put in a config split basically saying
the production split to active
using this line of code here.
Now I'm ready to export it,
so right now we can see that
the prod directory over here
is empty and-
- [Audience Member]
Don't you want to scroll
down to case prod?
- [Scott] Oh, you are
correct. Sorry. Thank you.
Case prod config split config
split production is true,
so I do have that there.
Okay, great.
Thank you for that.
So now I'm going to do a
drush config sync export,
and the argument you
pass to it is the name,
the machine name of that split.
So we're gonna run that
and it's gonna confirm
that I want to do it.
And now when I look at my split directory,
I have two files in here.
One is the syslog settings,
and the other is the setting for that page
where I had that max age set.
If we were to get into
the weeds here and go down
to in the main config
directory after I do an export.
Drush cex c-e-x.
We'll see that there's a new, uh sorry,
getting ahead of myself here.
We'll see that there's
a new config split file
for production and it's
really not that interesting
of reading.
Of note here is an array
of the modules that you're
turning off and on in holds.
Down here what is called graylist,
which is that conditional split,
that's where that setting is,
so if you wanted some
fun nighttime reading,
that's the place to do that.
So now what I'm gonna
do to kinda prove out
that this works is in
my settings.php file,
I'm gonna set this back to dev
and then I'm going to clear cache.
And when we come back over here,
we should see two things happen.
The environment indicator
bar is gonna turn green
and then the status for the
development config split
will say active over written
because that's what I have
in settings php file for that.
So we have that, which is great,
so now if I just do a drush config import,
hopefully you can see this.
What will happen is the
things that were enabled
on production are gonna
be turned off here,
so it's reverting the
system.performance settings.
It's turning off the syslog module,
which is great.
But then again just to prove it all out,
if I go to production
and do the cache clear,
and then the config import,
we'll see those modules come
back on with those settings.
If I did everything correctly.
So yes, it looks like we
have some success here,
so we can see that it
installed syslog for us
and updated the system
performance variables for us.
So it does feel a little bit
like jumping through hoops
to get it set up,
but once you go through that once
and you get that pattern down,
life is so much easier
when you are doing ongoing
daily development for the site.
And again this just kinda
highlights the overrides.
A lot of this is here for reference,
so you can look at it later,
'cause I know I'm just like
slamming on the accelerator
through this presentation here.
A couple of quick tips that
I have for you is when you
make those changes to
settings, always clear cache.
You'll want to make sure
that that setting is
on your target environment before you make
the configuration changes
and you keep that active,
do the config export, and
then you can change it back.
Otherwise if you do a config
import or a config export,
targeting the wrong
environment you're gonna get
that extra configuration
spit out to the main config
as well and then you have
not happy developer days.
That's that.
We have four minutes if
there are any questions.
- [Audience Member] I was
wondering how this plays out
(mumbles) I noticed your config split was
set to gray or whatever.
How does this system work
with different versions?
- [Scott] It works perfectly with the-
The question was how do
the config splits work
with version control?
It works well.
These are separate files that get exported
and so they're just managed with-
so in the example of the graylist,
like you mentioned,
so here for production the graylist is,
we have that system.performance,
so it grabs all the config
settings from that page.
But then when we go up here in, sorry,
I'm gonna go one place first,
so we have system.performance
in the main config directory.
We can see that caching is
not turned on right now.
But then if we were to go up
to the config split
directory for production,
and look at that system.performance,
we can see that caching is turned off.
So all these will get committed and then
when you do the drush config import,
like on production,
it's gonna have that
environment switch to know
that it needs to bring this one in.
So it's managed just like any other files
from that respect.
I think we had a question here first.
- [Audience Member] So can
you play out a scenario
where you have let's say a gethub token
in your configuration file.
Some kind of API key with split,
how would you manage that 'cause typically
what we end up doing is
including an override
settings file out of code
repository completely.
So would that play nicely
with splitting and ignoring?
- [Scott] Yeah, I think it would.
- [Audience Member] Could
you repeat the question?
- [Scott] The question
is how could you handle
something like a gethub
token in a directory
that's outside of code management?
Is that the right rephrasing
outside of version control?
- [Audience Member] Yeah.
- [Scott] So you could
definitely have a home directory
or a user directory on the
server for each environment
and do include that file.
It plays nice in that
database config is first
and then it would do,
depending on how you sequence
it in your settings file,
it'll either do your home
directory settings file override,
your environment settings file override,
or the main settings.php.
I think it would be more
work how you sequence those
because the config split
isn't read every time.
It's only on config import.
Does that make sense?
- [Audience Member] Absolutely.
- [Scott] Okay, great.
Question here.
- [Audience Member] So
assuming you're copying
your config sync into an install profile,
but you don't have splits set up,
what do you need to do to
accommodate splits if you're
trying to generate (mumbles)?
- [Scott] The question is how
do you manage config splits
via a install profile,
and I am going to be very
honest and say I don't know.
I haven't had to come
across that scenario,
so I don't know.
I could hypothesize, but I don't-
- [Audience Member] Is
there a better alternative
to install profiles which
you've been looking at or?
- [Scott] I don't think so.
I think install profiles are a good thing.
Yeah. Okay.
I think we have time for
one more question here.
- [Audience Member] Is
there any way to turn off
the module in one split,
or do you just have to enable
it in all the other splits?
- [Scott] You want kind of
the negate the scenario.
That I don't know that I have an answer
for you as well of being
able to turn off a module
in all but one environment.
I think the split for the develop module,
you have that on in one environment
and off in the other two,
but that converse-
I don't know if you
would be able to do that
unless you added that module
to those two other splits.
Okay, I see that we are at time.
I'm gonna just kinda hang out back there
if you guys have any
questions or anything.
Please if you have a moment,
go to mid.camp/250.
That's my node for the presentation,
provide some feedback,
and yeah,
Saturday is contribution day,
so if you're so inclined to hang out here,
thank you.
Captions made possible by ClarityPartners.com
Chicago area Drupal consultants
(applause)
Captions made possible by ClarityPartners.com. Chicago area Drupal consultants