{
    "componentChunkName": "component---src-pages-blog-post-tsx",
    "path": "/blog/2021-01-11/gitops-developers-guide",
    "result": {"data":{"site":{"siteMetadata":{"siteUrl":"https://www.architect.io"}},"allMdx":{"edges":[{"node":{"body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"A Developer’s Guide to GitOps\",\n  \"description\": \"A guide to GitOps - a modern tactic for automating DevOps that dramatically improves stability while allowing developers to release quickly.\",\n  \"image\": \"/images/blog/a-developers-guide-to-gitops/gitops-for-developers.png\",\n  \"slug\": \"gitops-developers-guide\",\n  \"date\": \"2021-01-11T00:00:00.000Z\",\n  \"author\": \"David Thor\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"One of a modern DevOps team\\u2019s driving objectives is to help developers deploy\\nfeatures as quickly and safely as possible. This means creating tools and\\nprocesses that do everything from provisioning private developer environments to\\ndeploying and securing production workloads. This effort is a constant balance\\nbetween enabling developers to move quickly and ensuring that their haste\\ndoesn't lead to critical outages. Fortunately, both speed and stability improve\\ntremendously whenever automation, like GitOps, is introduced.\"), mdx(\"p\", null, \"As you might have guessed from that lead-up, GitOps is a tactic for automating\\nDevOps. More specifically, however, it's an automation tactic that hooks into a\\ncritical tool that already exists in developers\\u2019 everyday workflow, Git. Since\\ndevelopers are already committing code to a centralized Git repo (often hosted\\nby tools like GitHub, GitLab, or BitBucket), DevOps engineers can wire up any of\\ntheir operational scripts, like those used to build, test, or deploy\\napplications, to kick off every time developers commit code changes. This means\\ndevelopers get to work exclusively with Git, and everything that helps them get\\ntheir code to production will be automated behind the scenes.\"), mdx(\"h2\", {\n    \"id\": \"why-gitops\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Why GitOps?\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#why-gitops\",\n    \"aria-label\": \"why gitops permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"In years past, DevOps and CI/CD practices were a set of proprietary scripts and\\ntools that executed everyday tasks like running tests, provisioning\\ninfrastructure, or deploying an application. However, the availability of new\\ninfrastructure tools like Kubernetes combined with the proliferation of\\nmicroservice architectures have enabled and ultimately \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"demanded\"), \" that\\ndevelopers get more involved in CI/CD processes.\"), mdx(\"p\", null, \"This \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"shift left\"), \" exploded the problems seen with custom scripting and manual\\nexecution leading to confusing/inconsistent processes, duplication of efforts,\\nand a drastic reduction in development velocity. To take advantage of\\ncloud-native tools and architectures, teams need a consistent, automated\\napproach to CI/CD that would enable developers to:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Stop building and maintaining proprietary scripts and instead use a universal\\nprocess\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Create apps and services faster by using said universal deploy process\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Onboard more quickly by deploying every time they make code changes\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Deploy automatically to make releases faster, more frequent, and more reliable\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Rollback and pass compliance audits with declarative design patterns\")), mdx(\"h2\", {\n    \"id\": \"developers-love-gitops\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Developers love GitOps\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#developers-love-gitops\",\n    \"aria-label\": \"developers love gitops permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"For all the reasons cited above (and more), businesses need manageable and\\nautomatable approaches to CI/CD and DevOps to succeed in building and\\nmaintaining cloud-native applications. However, if automation is all that\\u2019s\\nneeded, why GitOps over other strategies (e.g., SlackOps, scheduled deployments,\\nor simple scripts)? The answer is simple: developers love GitOps.\"), mdx(\"h3\", {\n    \"id\": \"one-tool-to-rule-them-all-git\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"One tool to rule them all, Git\", mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#one-tool-to-rule-them-all-git\",\n    \"aria-label\": \"one tool to rule them all git permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"It's become apparent in the last few years that GitOps is among the most\\nhighly-rated strategies for automating DevOps by developers, and it's not hard\\nto see why. Developers \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"live\"), \" in Git. They save temporary changes to git,\\ncollaborate using git, peer-review code using git, and store a history and audit\\ntrail of all the changes everyone has ever made in git. The pipelining strategy\\ndescribed above was tailor-made for git. Since developers already rely on git so\\nheavily, these processes are, in turn, tailor-made for developers. Developers\\nrecognize this and are more than happy to reduce the tools and processes they\\nneed to use and follow to do their jobs.\"), mdx(\"h3\", {\n    \"id\": \"declared-alongside-code\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Declared alongside code\", mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#declared-alongside-code\",\n    \"aria-label\": \"declared alongside code permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"Beyond just the intuitive, git-backed execution flow, another part of modern CI\\ntools and GitOps that developers love is the declarative design. The previous\\ngeneration of CI tools had configurations that lived inside private instances of\\nthe tools. If you didn't have access to the tools, you didn't know what the\\npipelines did, if they were wrong or right, how or when they executed, or how to\\nchange them if needed. It was just a magic black box and hard for developers to\\ntrust as a result.\"), mdx(\"p\", null, \"In modern CI systems, like the ones most commonly used to power GitOps like\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://circleci.com/\"\n  }, \"CircleCI\"), \",\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.github.com/en/free-pro-team@latest/actions\"\n  }, \"Github Actions\"), \",\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/\"\n  }, \"Gitlab CI\"), \",\\netc., the configurations powering the pipelines live directly in the Git\\nrepository. Just like the source code for the application, these configurations\\nare version controlled and visible to every developer working on the project.\\nNot only can they see what the pipeline process is, but they can also quickly\\nand easily make changes to it as needed. This ease of access for developers is\\ncritical since developers write the tests for their applications and ensure it\\nis safe and stable.\"), mdx(\"h3\", {\n    \"id\": \"completely-self-service\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Completely self-service\", mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#completely-self-service\",\n    \"aria-label\": \"completely self service permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"New features or bug fixes aren't considered complete until they land in\\nproduction. This means that anything standing in the way of getting code changes\\nto production are eating up developer time and mental energy when the feature,\\nas far as the developer is concerned, \\\"works on my machine.\\u201D Suppose developers\\nhave to wait, even for a few minutes, for a different team or individual to do\\nsome task before they can close out their work. In that case, it creates both\\nfriction and animosity in the organization.\"), mdx(\"p\", null, \"Alleviating this back and forth between teams is one of the main benefits of\\nDevOps automation tactics like GitOps. Not only do developers get to work in a\\nfamiliar tool, but the ability to have their code make its way to production\\nwithout manual intervention means they are never waiting on someone else before\\nthey can complete their tasks.\"), mdx(\"h3\", {\n    \"id\": \"continuous-everything\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Continuous everything\", mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#continuous-everything\",\n    \"aria-label\": \"continuous everything permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"Yet another big perk of GitOps is that all the processes are continuously\\nrunning all the time! Every change we make triggers tests builds, and\\ndeployments without ANY manual steps required. Since developers would use git\\nwith or without GitOps, hooking into their existing workflow to trigger DevOps\\nprocesses is the perfect place to kick off automated events. Until developers\\nstop using Git, GitOps will remain the ideal way to instrument automated DevOps.\"), mdx(\"h2\", {\n    \"id\": \"gitops-in-practice\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"GitOps in practice\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#gitops-in-practice\",\n    \"aria-label\": \"gitops in practice permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"Naturally, the involvement of developers in the process has led teams to explore\\nthe use of developer-friendly tools like Git, but the use of Git as a source of\\ntruth for DevOps processes also creates a natural consistency to the shape of\\nCI/CD pipeline stages. There are only so many hooks available in a Git\\nrepository after all (e.g., commits, pull requests open/closed, merges, etc.),\\nso the look and feel of most GitOps implementations include a set of typical\\nstages:\"), mdx(\"p\", null, mdx(\"img\", {\n    parentName: \"p\",\n    \"src\": \"/images/blog/a-developers-guide-to-gitops/gitops-pipeline.png\",\n    \"alt\": \"GitOps\\nPipelines\"\n  })), mdx(\"h3\", {\n    \"id\": \"1-pull-requests-tests-and-preview-environments\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"1. Pull requests, tests, and preview environments\", mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#1-pull-requests-tests-and-preview-environments\",\n    \"aria-label\": \"1 pull requests tests and preview environments permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"After developers have spent time writing the code for their new feature, they\\ngenerally commit that code to a new Git branch and submit a\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/about-pull-requests\"\n  }, \"pull request\"), \"\\nor\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.gitlab.com/ee/user/project/merge_requests/getting_started.html\"\n  }, \"merge request\"), \"\\nback to the mainline branch of the repository. This is something developers\\nalready do daily to prompt engineering managers to review the code changes and\\napprove them to be merged into the main application code. Since developers\\nalready follow this kind of process for their daily collaboration efforts, it's\\na perfect opportunity for DevOps to wire up additional tasks.\"), mdx(\"p\", null, \"By hooking into the open/close events created by this pull request process using\\na continuous integration (CI) tool, DevOps teams can trigger the execution of\\nunit tests, creation of preview environments, and execution of integration tests\\nagainst that new preview environment. Instrumentation of these steps allows\\nengineering managers to establish trust in the code changes quickly and allows\\nproduct managers to see the code changes via the preview environment before\\nmerging. Faster trust development means faster merges, and earlier input from\\nproduct managers means easier changes without complicated and messy rollbacks.\\nThis GitOps hook is a key enabler for faster and healthier product and\\nengineering teams alike.\"), mdx(\"h3\", {\n    \"id\": \"2-merge-to-master-and-deploy-to-staging\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"2. Merge to master and deploy to staging\", mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#2-merge-to-master-and-deploy-to-staging\",\n    \"aria-label\": \"2 merge to master and deploy to staging permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"Once all parties have reviewed the changes, the code can be merged into the\\nmainline branch of the repository alongside changes from the rest of the\\nengineering team. This mainline branch is often used as a staging ground for\\ncode that is almost ready to go to production, and as such, it\\u2019s another ideal\\ntime for us to run some operational tasks like tests and deployment. While we\\ntested the code for each pull request before it was merged, we'll want to rerun\\ntests to ensure that code works with the other changes contributed by peer team\\nmembers. We'll also want to deploy all these changes to a shared environment\\n(aka \\\"staging\\\") that the entire team can use to view and test the latest changes\\nbefore they are released to customers.\"), mdx(\"h3\", {\n    \"id\": \"3-cut-releases-and-deploy-to-production\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"3. Cut releases and deploy to production\", mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#3-cut-releases-and-deploy-to-production\",\n    \"aria-label\": \"3 cut releases and deploy to production permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"Finally, after product and engineering have had time to review and test the\\nlatest changes to the mainline branch, teams are ready to cut a release and\\ndeploy to production! This is often a task performed by a release manager \\u2013 a\\ndedicated (or rotating) team member tasked with executing the deploy scripts and\\nmonitoring the release to ensure that nothing goes wrong in transit. Without\\nGitOps, this team member would have to know where the proper scripts are, in\\nwhat order to execute them, and would need to ensure their computer has all the\\ncorrect libraries and packages required to power the scripts.\"), mdx(\"p\", null, \"Thanks to GitOps, we can wire up this deployment to happen on another Git-based\\nevent \\u2013 creating a\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/about-releases\"\n  }, \"release\"), \"\\nor tag. All a release manager would have to do is create a new \\\"release,\\u201D often\\nusing semver for naming, and the tasks to build and deploy the code changes\\nwould be kicked off automatically. Like most tasks executed by a CI tool, these\\nwould be configured with the scripts\\u2019 location and order the libraries and\\npackages needed to execute them.\"), mdx(\"h2\", {\n    \"id\": \"gitops-tooling\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"GitOps tooling\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#gitops-tooling\",\n    \"aria-label\": \"gitops tooling permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"A solid and intuitive continuous integration tool isn't the only thing needed to\\ninstrument GitOps processes like those described in this article. The CI system\\ncan activate scripts based on git events, but you still need strong tools to\\npower those scripts and ensure they can be run and maintained easily and safely.\\nDeploying code changes (aka continuous delivery (CD)) is one of the most\\nchallenging steps to automate, so we've curated a few tooling categories that\\ncan help you through your GitOps journey:\"), mdx(\"h3\", {\n    \"id\": \"containerization-with-docker\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Containerization with Docker\", mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#containerization-with-docker\",\n    \"aria-label\": \"containerization with docker permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"Docker launched cloud development into an entirely new, distributed landscape\\nand helped developers begin to realistically consider microservice architectures\\nas a viable option. Part of what made Docker so powerful was how\\ndeveloper-friendly it is compared to the previous generation of virtualization\\nsolutions. Just like the declarative CI configurations that live inside our\\nrepositories, developers simply have to write and maintain a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dockerfile\"), \" in\\ntheir repository to enable automated container builds of deployable VMs.\\nContainerization is an enormously powerful tactic for cloud-native teams and\\nshould be a staple tool in your repertoire.\"), mdx(\"h3\", {\n    \"id\": \"infrastructure-as-code-iac\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Infrastructure-as-code (IaC)\", mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#infrastructure-as-code-iac\",\n    \"aria-label\": \"infrastructure as code iac permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"A lot goes into provisioning infrastructure and deploying applications that\\nisn't captured by a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dockerfile\"), \". For everything else, there's\\ninfrastructure-as-code (IaC) solutions like\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.terraform.io/\"\n  }, \"Terraform\"), \",\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://aws.amazon.com/cloudformation/\"\n  }, \"Cloudformation\"), \", and others. These\\nsolutions allow developers to describe the other bits of an application, like\\nKubernetes resources, load balancers, networking, security, and more, in a\\ndeclarative way. Just like the CI configs and Dockerfiles described earlier, IaC\\ntemplates can be version controlled and collaborated on by all the developers on\\nyour team.\"), mdx(\"h3\", {\n    \"id\": \"devops-automation-tools-like-architect\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"DevOps automation tools like Architect\", mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#devops-automation-tools-like-architect\",\n    \"aria-label\": \"devops automation tools like architect permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"I really can't talk about DevOps automation without talking about Architect. We\\nlove IaC and use it heavily as part of our product. We found that configuring\\ndeployments, networking, and network security, especially for microservice\\narchitectures, can be demanding on the developers who should be focused on new\\nproduct features instead of infrastructure.\"), mdx(\"p\", null, \"Instead of writing IaC templates and CI pipelines, which require developers to\\nlearn about Kubernetes, Cilium, API gateways, managed databases, or other\\ninfrastructure solutions, just have them write an \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"architect.yml\"), \" file. We'll\\nautomatically deploy dependent APIs/databases and securely broker connectivity\\nto them every time someone runs \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"architect deploy\"), \". Our process can\\nautomatically spin up private developer environments, automated preview\\nenvironments, and even production-grade cloud environments with just a single\\ncommand.\"), mdx(\"h2\", {\n    \"id\": \"learn-more-about-devops-gitops-and-architect\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Learn more about DevOps, GitOps, and Architect!\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#learn-more-about-devops-gitops-and-architect\",\n    \"aria-label\": \"learn more about devops gitops and architect permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"At Architect, our mission is to help ops and engineering teams simply and\\nefficiently collaborate and achieve deployment, networking, and security\\nautomation all at once. Ready to learn more? Check out these resources:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"/blog/creating-microservices-nestjs\"\n  }, \"Creating Microservices: Nest.js\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"/blog/the-importance-of-portability\"\n  }, \"The Importance of Portability in Technology\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"/docs\"\n  }, \"Our Product Docs!\"))), mdx(\"p\", null, \"Or \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://cloud.architect.io/signup\"\n  }, \"sign up\"), \" and try Architect yourself\\ntoday!\"));\n}\n;\nMDXContent.isMDXComponent = true;","excerpt":"One of a modern DevOps team’s driving objectives is to help developers deploy\nfeatures as quickly and safely as possible. This means creating tools and\nprocesses that do everything from provisioning…","tableOfContents":{"items":[{"url":"#why-gitops","title":"Why GitOps?"},{"url":"#developers-love-gitops","title":"Developers love GitOps","items":[{"url":"#one-tool-to-rule-them-all-git","title":"One tool to rule them all, Git"},{"url":"#declared-alongside-code","title":"Declared alongside code"},{"url":"#completely-self-service","title":"Completely self-service"},{"url":"#continuous-everything","title":"Continuous everything"}]},{"url":"#gitops-in-practice","title":"GitOps in practice","items":[{"url":"#1-pull-requests-tests-and-preview-environments","title":"1. Pull requests, tests, and preview environments"},{"url":"#2-merge-to-master-and-deploy-to-staging","title":"2. Merge to master and deploy to staging"},{"url":"#3-cut-releases-and-deploy-to-production","title":"3. Cut releases and deploy to production"}]},{"url":"#gitops-tooling","title":"GitOps tooling","items":[{"url":"#containerization-with-docker","title":"Containerization with Docker"},{"url":"#infrastructure-as-code-iac","title":"Infrastructure-as-code (IaC)"},{"url":"#devops-automation-tools-like-architect","title":"DevOps automation tools like Architect"}]},{"url":"#learn-more-about-devops-gitops-and-architect","title":"Learn more about DevOps, GitOps, and Architect!"}]},"frontmatter":{"title":"A Developer’s Guide to GitOps","description":"A guide to GitOps - a modern tactic for automating DevOps that dramatically improves stability while allowing developers to release quickly.","author":"David Thor","date":"2021-01-11","image":null}},"next":null,"previous":null}]}},"pageContext":{"slug":"gitops-developers-guide"}},
    "staticQueryHashes": ["764694655"]}