Transcript
            
            
              This transcript was autogenerated. To make changes, submit a PR.
            
            
            
            
              Hello everyone and welcome to my talk multiple terraform projects in
            
            
            
              a Monorepo and today we will try to answer a question, how to survive that
            
            
            
              mess. A couple words about
            
            
            
              me. I am a DevOps engineer and I used
            
            
            
              to be a software engineer.
            
            
            
              I try to automate things
            
            
            
              and I fan of clean
            
            
            
              code and open source and
            
            
            
              infrastructure as a code. Here you can find QR
            
            
            
              code and link to my profile on
            
            
            
              LinkedIn. So if you have questions about
            
            
            
              this terrap compose tool,
            
            
            
              or if you want to just talk with me
            
            
            
              about some DevOps topics or something else,
            
            
            
              you can reach me out there. So let's
            
            
            
              start when someone
            
            
            
              tell you that it has everything as
            
            
            
              an infrastructure, as a code, it might
            
            
            
              be something similar to that picture. So it
            
            
            
              probably not something that you are expecting out of these
            
            
            
              words, right? So you can
            
            
            
              see there as a code,
            
            
            
              but it may be copy pasted,
            
            
            
              or maybe not clean, or maybe not
            
            
            
              updated and so on. So it
            
            
            
              might be different expectations
            
            
            
              out of it. I was in this situation several
            
            
            
              times and today I will
            
            
            
              try to guide you through
            
            
            
              my experience out of managing
            
            
            
              such projects. And our agenda
            
            
            
              for today is first I will explain
            
            
            
              prerequisites that we have. Then we will
            
            
            
              have a problem deep dive. Then I
            
            
            
              will try to explore existing solutions.
            
            
            
              What we have there, I will introduce terracompose
            
            
            
              then and a short demo and a couple
            
            
            
              final words in the end. So let's
            
            
            
              start. We have as a prerequisite a set
            
            
            
              of projects in a monorepo. They have
            
            
            
              various workspaces, which is mostly equal to environments,
            
            
            
              various structures and terraform versions.
            
            
            
              And if we look into our
            
            
            
              projects, you might have similar
            
            
            
              situation that you have some projects
            
            
            
              in your folder, whatever name I
            
            
            
              select projects. And you
            
            
            
              might also have some common stuff like
            
            
            
              creating vpcs or something like that
            
            
            
              which is shared across these projects. And it might
            
            
            
              have a little bit different location here.
            
            
            
              In this example it's a common, you can see it on the left picture.
            
            
            
              Also you can have environments based
            
            
            
              approach of structures. Your projects,
            
            
            
              as you can see on the right picture with
            
            
            
              modules. When we talk about various
            
            
            
              workspaces,
            
            
            
              mostly we talk about different
            
            
            
              number of workspaces per project
            
            
            
              and different naming combinations. So some of
            
            
            
              the projects might have staging and production
            
            
            
              only, some might have life stage
            
            
            
              and so on. Also we have different
            
            
            
              structures here because some of
            
            
            
              the projects might have components which
            
            
            
              add additional level of the file structure.
            
            
            
              And in the end we might have different terraform versions
            
            
            
              across the projects and also different
            
            
            
              versions inside the project between different
            
            
            
              workspaces, because you might be in the process
            
            
            
              of upgrading terraform and you have on
            
            
            
              managing, for example, one version of terraform. And in production still you
            
            
            
              can have different version.
            
            
            
              Okay, so let's summarize
            
            
            
              our complaints.
            
            
            
              We have following pain points, different terraform versions,
            
            
            
              and it's a pain of switching
            
            
            
              terraform versions on local between different projects.
            
            
            
              Also you have there a risk of incompatibility of the snippets.
            
            
            
              And also here we
            
            
            
              have a problem that our workspaces
            
            
            
              not visible and not trackable by versions control
            
            
            
              system. And that's why
            
            
            
              you need to memorize everything.
            
            
            
              And it creates a problem
            
            
            
              when you involve someone for troubleshooting
            
            
            
              or onboard newcomers. Aren't there any solutions
            
            
            
              on the market? Let's see.
            
            
            
              So we have terraform cloud,
            
            
            
              which is famous SaaS solution.
            
            
            
              It's a native solution for terraform and
            
            
            
              it's really good, but it's a pricey
            
            
            
              solution and it's not solve everything
            
            
            
              that we need. So it still
            
            
            
              for us has a low
            
            
            
              visibility for workspaces.
            
            
            
              And you still need to memorize your structure
            
            
            
              and workspaces and
            
            
            
              the price for sure. If we take a
            
            
            
              look into other tools,
            
            
            
              terraground, terramate, terraspace, they are also
            
            
            
              really good and they
            
            
            
              cover some pain points,
            
            
            
              but not all of them. Instead they create
            
            
            
              also some pain points, because with
            
            
            
              introducing them, you need to
            
            
            
              maintain some files,
            
            
            
              they are required, or some file structures
            
            
            
              or so on. So they create some
            
            
            
              amount of overhead. Sometimes it
            
            
            
              does make sense to use it, sometimes not.
            
            
            
              But we are trying to talk
            
            
            
              about the lightweight solution. So we
            
            
            
              do not want to have overhead, almost nothing.
            
            
            
              And then three years ago
            
            
            
              I thought that. Okay, wait, I already
            
            
            
              saw it somewhere and I remember
            
            
            
              that we have Docker compose and
            
            
            
              docker and Docker compose have
            
            
            
              a configuration for the projects in yaml.
            
            
            
              It's a very clean approach
            
            
            
              with config as a code and it
            
            
            
              has high visibility and traceability.
            
            
            
              And the idea behind terracompose, exactly that.
            
            
            
              Why cannot we do something
            
            
            
              like that with the terraform projects?
            
            
            
              Okay, and let me show you
            
            
            
              this quick wrapper.
            
            
            
              So terracompose, use cases,
            
            
            
              use cases are actually here
            
            
            
              actions that we can run in terracompose,
            
            
            
              we can run plan, apply workspaces,
            
            
            
              run shell and help more
            
            
            
              often. For sure we using plan and
            
            
            
              apply. And under the hood these actions are
            
            
            
              having terraform commands and
            
            
            
              providing output of them. We also can
            
            
            
              run command inside the container
            
            
            
              with run action. We can list workspaces and
            
            
            
              we can run a shell inside
            
            
            
              the container and join
            
            
            
              it. If we take
            
            
            
              a look on collaboration diagram here,
            
            
            
              we can see that when we trigger terracompose
            
            
            
              action under the hood, Terracompose will
            
            
            
              read configuration which is written into the config file
            
            
            
              and based on that run terraform
            
            
            
              command inside the docker.
            
            
            
              Also it will run
            
            
            
              this action, wrap it into
            
            
            
              some different commands like change directory,
            
            
            
              terraform, init, select workspaces and so on.
            
            
            
              With this setup we solve our problem with terraform
            
            
            
              versions because we use Docker
            
            
            
              which allow us to have different terraform
            
            
            
              versions on the same machine.
            
            
            
              Also we solve problem with different structure
            
            
            
              and workspaces and memorizing them because we
            
            
            
              can customize our alias
            
            
            
              with different path, different workspace and
            
            
            
              we don't need to memorize them. Only one
            
            
            
              that we need to do is to actually create this config file.
            
            
            
              We also improve our validation
            
            
            
              approach because we chain terraform commands and
            
            
            
              we automatically run validation.
            
            
            
              We will not forget about it and
            
            
            
              it will also automate some cleanup
            
            
            
              things after running action.
            
            
            
              So it will also help us in this way when
            
            
            
              we will talk about capabilities. So here I would
            
            
            
              stress that we don't need to memorize
            
            
            
              it and it's
            
            
            
              a part of code base so it has same visibility.
            
            
            
              You can have merge requests
            
            
            
              and you can have a documentation
            
            
            
              just at your code base about workspaces.
            
            
            
              Also having terraform commands provide
            
            
            
              us a guaranteed validated plan and
            
            
            
              it will just speed up maintenance and development because
            
            
            
              it require less time for double check, for printing,
            
            
            
              repeated comments and in the end it
            
            
            
              means less validation failures on CI
            
            
            
              when you will push your code because it
            
            
            
              shift left validations and
            
            
            
              it require from you to do
            
            
            
              all checks locally. First in the configuration
            
            
            
              file you can see two
            
            
            
              main blocks. This is default
            
            
            
              which contains shared properties
            
            
            
              across the aliases and aliases which
            
            
            
              is actually our projects
            
            
            
              and environments. And here
            
            
            
              you can see that this terraform version
            
            
            
              that we define in default might
            
            
            
              be overwritten in alias.
            
            
            
              The required property is only one path
            
            
            
              only. This is distinguish aliases between
            
            
            
              each other and we
            
            
            
              have here also example of the hooks usage.
            
            
            
              Hooks will help us to customize our projects
            
            
            
              even more so we
            
            
            
              are able to run scripts or commands
            
            
            
              before some particular activities and
            
            
            
              or after. And this way we
            
            
            
              will be able to do some workarounds
            
            
            
              for some h cases. We will
            
            
            
              talk about it later. Here you can see
            
            
            
              the output of the help action.
            
            
            
              So it lists available actions and also
            
            
            
              it lists available aliases.
            
            
            
              And now it's time for demo.
            
            
            
              First of all I want to emphasize
            
            
            
              few points about demo. So first
            
            
            
              we will have it in AWS.
            
            
            
              Second demo project I
            
            
            
              prepare it and it contains for
            
            
            
              speed and for readability projects
            
            
            
              that creates only vpcs and security groups.
            
            
            
              And also we will keep terraform state locally
            
            
            
              for simplicity, but please never do it in production.
            
            
            
              Here I want to show
            
            
            
              how I connect to AWS. So it's
            
            
            
              just a simple AWS
            
            
            
              profile and I export also profile
            
            
            
              name with environment variable. I also created
            
            
            
              these commands, this aliases which is
            
            
            
              just help us to not print
            
            
            
              that long commands during the demo.
            
            
            
              So let's check that we have only default VPC and
            
            
            
              default security group. Okay,
            
            
            
              everything is prepared.
            
            
            
              Let's download the tool.
            
            
            
              So I'm downloading the terracompose
            
            
            
              tool and copied into
            
            
            
              the local bin. I also will clone
            
            
            
              the terracompose demo project which
            
            
            
              is available in GitHub.
            
            
            
              And let's start with the first
            
            
            
              demo project is a common so as I mentioned,
            
            
            
              it will create a vpcs for all our
            
            
            
              projects and we can use,
            
            
            
              and we can create resources in these
            
            
            
              vpcs. So here we have folder
            
            
            
              with terraform state. We have two environments,
            
            
            
              nonprod and production. And we
            
            
            
              have here tf varst files,
            
            
            
              one managing with workspace and another
            
            
            
              one does not match with
            
            
            
              his name with workspace name. So for
            
            
            
              this use case we for
            
            
            
              staging just define
            
            
            
              workspace property. And for production we
            
            
            
              define beside workspace property, we define also
            
            
            
              tfvars property. So this is a
            
            
            
              very simple example when we
            
            
            
              can omit some break in naming
            
            
            
              combinations and we can use
            
            
            
              a random name for tfwars. Just put
            
            
            
              this name into the alias
            
            
            
              config. Okay, let's build
            
            
            
              a plan. So this is just a simple command.
            
            
            
              As you can see this is plan and then alias
            
            
            
              name. Now you see the
            
            
            
              output that we are running,
            
            
            
              terraform init. We see the
            
            
            
              normal Tf init output.
            
            
            
              Also we can see that workspace Nonprod
            
            
            
              has been found in config and we will select it
            
            
            
              and we see the information about
            
            
            
              the main factors
            
            
            
              for our plan. This is workspace and this is tfwars
            
            
            
              name. Then after
            
            
            
              checking plan, you can see that this plan is
            
            
            
              actually saved in this file. So we can
            
            
            
              even manually check it if you want.
            
            
            
              Okay, then we can run workspaces alias.
            
            
            
              This is also just
            
            
            
              a short link to list the available alias workspaces.
            
            
            
              Sorry. And we see that we currently
            
            
            
              are in nonprod workspace.
            
            
            
              So let's apply. When we run apply,
            
            
            
              it's also easy. It's just apply and name workspace.
            
            
            
              You don't need to define all details about files and
            
            
            
              so on. So it's done already. Under the
            
            
            
              hood we see in which directory
            
            
            
              we are, we are running terraform in need standard
            
            
            
              output of it, selecting workspace.
            
            
            
              And now we see that, okay, we want to apply
            
            
            
              file with this name, are you sure about that?
            
            
            
              And also we can see how
            
            
            
              long time ago it was modified.
            
            
            
              So now you can decide, is that exactly file
            
            
            
              that you want to apply or not?
            
            
            
              So if we print, yes, we can proceed.
            
            
            
              And our sources were
            
            
            
              created. Now let's build a plan for production.
            
            
            
              And you remember that there we had an
            
            
            
              TfVars named differently
            
            
            
              from workspace, but terraform
            
            
            
              plan is there and file also
            
            
            
              pick it up correctly. Now let's apply.
            
            
            
              And now you see that, okay,
            
            
            
              I ran the command, but now it contains a suffix.
            
            
            
              So with the suffix debug you can enable debug
            
            
            
              mode which will run it
            
            
            
              without init, without format check
            
            
            
              and without validation. So it's very useful
            
            
            
              for development process and
            
            
            
              debugging process, because you don't need
            
            
            
              to wait until everything will be validated
            
            
            
              and in its process will finished and
            
            
            
              so on. So it's
            
            
            
              very useful for development, but I
            
            
            
              would not recommend doing that out
            
            
            
              of development. So you need to have a
            
            
            
              clear understanding for what you are doing
            
            
            
              that. Okay,
            
            
            
              so we want to apply our
            
            
            
              changes, they are applied.
            
            
            
              And also let's check how we can run
            
            
            
              other commands. So we can just
            
            
            
              trigger action, run alias and
            
            
            
              then we can put any commands
            
            
            
              that we want to run, they will be run in
            
            
            
              the container. So here you can see that
            
            
            
              we list our state and we see that our
            
            
            
              VPC is there. And also
            
            
            
              I want to show you that our vpcs
            
            
            
              were really created and they are
            
            
            
              in place. Okay, now let's check
            
            
            
              more complex example. Here we see
            
            
            
              project that have two compose,
            
            
            
              let's go with the app component.
            
            
            
              And here we see that
            
            
            
              we have beside our Tf
            
            
            
              state folder with two workspaces
            
            
            
              integration and live. We have also here
            
            
            
              some tf state for experiment.
            
            
            
              So for example you are doing some experiment in integration workspace
            
            
            
              and you have this TF
            
            
            
              state folder just for integration workspace
            
            
            
              and you want to apply that. So how can you do it for
            
            
            
              that you can use backend config property and
            
            
            
              define their workspace deer with
            
            
            
              another location for the terraform state.
            
            
            
              Or for example, if you are using remote
            
            
            
              backend, you can put here some key and
            
            
            
              use that. So that
            
            
            
              just allow you to run terraform
            
            
            
              in it with some custom backend config.
            
            
            
              And hooks. Help us here because
            
            
            
              when we will jump from one
            
            
            
              environment to another environment we
            
            
            
              will see error because we
            
            
            
              ran terraform init with different
            
            
            
              backend configs. So for
            
            
            
              work around that issue we can just
            
            
            
              run hooks which removing terraform
            
            
            
              folder on both of these environments
            
            
            
              and it will solve our problem.
            
            
            
              This is just an example, you might have different use case
            
            
            
              and let's see how it works. So I
            
            
            
              going to run a plan on integration.
            
            
            
              We see here that we trigger
            
            
            
              before df init hook and we
            
            
            
              run our terraform init using backend config.
            
            
            
              We see config sorry, init output and
            
            
            
              selecting workspace. And we
            
            
            
              can check that in the end we are in workspace
            
            
            
              integration with TFwars integration
            
            
            
              tFwars. Okay, we see the plan here,
            
            
            
              no errors. So I'm going to
            
            
            
              apply it now.
            
            
            
              After resource were created,
            
            
            
              we see that changes are actually were
            
            
            
              recorded into experiment TF
            
            
            
              state and TF state with origin was
            
            
            
              not modified. So you
            
            
            
              can see that this option
            
            
            
              really works. And our
            
            
            
              security group also in place,
            
            
            
              we can see it here. Okay, now let's try
            
            
            
              to run interactive shell into container.
            
            
            
              And for that we will use
            
            
            
              shell action. We also
            
            
            
              need to approve it because for the
            
            
            
              projects purposes and we are inside the container.
            
            
            
              Now let's check our workspace list.
            
            
            
              Okay, so now we just check in that we
            
            
            
              are in the backend
            
            
            
              configuration experimental one,
            
            
            
              and for live
            
            
            
              we can just run terra
            
            
            
              compose action plan. It will
            
            
            
              run before Tf init hook
            
            
            
              again, run normal Tfe
            
            
            
              init without experimental backend config.
            
            
            
              And you can see that here we
            
            
            
              have plan that has been built
            
            
            
              incorrect workspace with correct tfwars
            
            
            
              file. Let's apply.
            
            
            
              Okay, so the resource was created
            
            
            
              and here we also can see them.
            
            
            
              Good. I think it's enough
            
            
            
              for this demo. I hope
            
            
            
              that you saw that with this setup,
            
            
            
              terracompose tool is really helpful
            
            
            
              when we we can just
            
            
            
              run action name and alias and it
            
            
            
              will run it with the properties with the arguments
            
            
            
              that we defined in the config
            
            
            
              file and we don't have to remember
            
            
            
              them and double check
            
            
            
              validity and so on.
            
            
            
              Let's back now to
            
            
            
              our presentation. So with that said,
            
            
            
              all done now, what do you think?
            
            
            
              Let's check our points.
            
            
            
              So here we have almost
            
            
            
              everything solved switch and terraform versions.
            
            
            
              It's now only attribute in YaML thanks
            
            
            
              to the running it into Docker snippets
            
            
            
              and compatibility visualization.
            
            
            
              Workspace traceability of the
            
            
            
              workspace automate routines needs to
            
            
            
              remember all these were solved chain in
            
            
            
              commons still. Well, it's a
            
            
            
              solved, but it's hard coded. That's why I market it as
            
            
            
              partially solved, because in
            
            
            
              the future plans I want to make
            
            
            
              them customizable and also allow users
            
            
            
              to create a custom action or
            
            
            
              override default action
            
            
            
              to solve different problems,
            
            
            
              or maybe just because to
            
            
            
              fix something. And if
            
            
            
              we talk about complexity and price.
            
            
            
              It's an open source and it's a simple yaml that
            
            
            
              you can create for 1 hour. So I tried to
            
            
            
              implement it into different projects
            
            
            
              and I spent about 1 hour and
            
            
            
              the job was done.
            
            
            
              Now let's talk about the future. So since
            
            
            
              that was just a simple wrapper,
            
            
            
              a quick wrapper written three years ago.
            
            
            
              So I didn't thought about the proper
            
            
            
              interface design and this
            
            
            
              is something that I see needs to
            
            
            
              be improved. Also, I want
            
            
            
              to make actions customizable as I just mentioned.
            
            
            
              And who knows, maybe rewriting go how
            
            
            
              do you think? So I actually
            
            
            
              want to encourage you to contribute to this project.
            
            
            
              You can find links to this project in QR code
            
            
            
              and in my GitHub account.
            
            
            
              Please join. And with that I
            
            
            
              want to say thank you for your attention.