1"use strict";(globalThis.webpackChunkmission_control=globalThis.webpackChunkmission_control||[]).push([[3263],{81854(e,n,s){s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>p,frontMatter:()=>t,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"guide/playbooks/index","title":"Playbooks","description":"Playbooks","source":"@site/docs/guide/playbooks/index.mdx","sourceDirName":"guide/playbooks","slug":"/guide/playbooks","permalink":"/docs/guide/playbooks","draft":false,"unlisted":false,"editUrl":"https://github.com/flanksource/docs/tree/main/docs/guide/playbooks/index.mdx","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"slug":"/guide/playbooks","title":"Playbooks","sidebar_position":1,"hide_title":true,"pagination_prev":"guide/config-db/index","pagination_next":"guide/notifications/index","sidebar_custom_props":{"icon":"playbook"}},"sidebar":"guide","previous":{"title":"Catalog","permalink":"/docs/guide/config-db"},"next":{"title":"Notifications","permalink":"/docs/guide/notifications/"}}');var o=s(74848),r=s(28453);const t={slug:"/guide/playbooks",title:"Playbooks",sidebar_position:1,hide_title:!0,pagination_prev:"guide/config-db/index",pagination_next:"guide/notifications/index",sidebar_custom_props:{icon:"playbook"}},l=void 0,a={},c=[{value:"Playbooks",id:"playbooks",level:2},{value:"Use cases",id:"use-cases",level:2},{value:"Provisioning",id:"provisioning",level:3},{value:"Day 2 Operations",id:"day-2-operations",level:3},{value:"Just In Time Access",id:"just-in-time-access",level:3},{value:"AIOps",id:"aiops",level:3},{value:"Actions",id:"actions",level:2},{value:"Templating",id:"templating",level:3},{value:"Approval",id:"approval",level:2},{value:"Permissions",id:"permissions",level:2},{value:"Required Permissions",id:"required-permissions",level:3},{value:"Permission Types",id:"permission-types",level:3},{value:"Permission Inheritance",id:"permission-inheritance",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components},{Screenshot:i}=n;return i||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Screenshot",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h2,{id:"playbooks",children:"Playbooks"}),"\n",(0,o.jsx)(n.p,{children:"Playbooks automate common workflows and processes by defining reusable templates of actions that can be triggered on-demand by users, when specific events happen or through webhooks."}),"\n",(0,o.jsx)(i,{img:"/img/playbooks.svg",shadow:!1,size:"600px"}),"\n",(0,o.jsx)(n.p,{children:"Some key benefits include:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Accelerated GitOps Adoption"})," - Use ",(0,o.jsx)(n.em,{children:'"ClickOps"'})," to make changes to resources but have them being applied as Git pull requests in the background, enabling non-technical teams to leverage GitOps workflows."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Consistency"})," - Provide easy to discover and reusable templates for common tasks, preventing the complexity of doing the same thing multiple ways."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Self-Service"})," - Enable developers/operators to provision and manage their own resources without involving a central DevOps/Platform team."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Compliance"})," - Improve compliance and security by limiting the need for elevated privileges."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Cost Efficiency"})," - Optimize costs with on-demand environments that spin down after a fixed duration."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Portability"})," - A consistent interface for performing operations irrespective of the underlying infrastructure and/or environment"]}),"\n"]}),"\n",(0,o.jsx)("hr",{}),"\n",(0,o.jsx)(n.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,o.jsx)(n.h3,{id:"provisioning",children:"Provisioning"}),"\n",(0,o.jsx)(n.h3,{id:"day-2-operations",children:"Day 2 Operations"}),"\n",(0,o.jsxs)(n.p,{children:["Day 2 operations can be added onto existing resources (",(0,o.jsx)(n.code,{children:"configs"}),", ",(0,o.jsx)(n.code,{children:"components"})," or health ",(0,o.jsx)(n.code,{children:"checks"}),") using ",(0,o.jsx)(n.a,{href:"/docs/reference/resource-selector",children:"resource selectors"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["For example scaling a Kubernetes Deployment is only applicable to config items of type: ",(0,o.jsx)(n.code,{children:"Kubernetes::Deployment"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:"title='scale-deployment.yaml' file=<rootDir>/modules/mission-control/fixtures/playbooks/scale-deployment.yaml",children:"apiVersion: mission-control.flanksource.com/v1\nkind: Playbook\nmetadata:\n name: scale-deployment\nspec:\n description: Scale Deployment\n configs:\n - types:\n - Kubernetes::Deployment\n parameters:\n - name: replicas\n label: The new desired number of replicas.\n actions:\n - name: kubectl scale\n exec:\n script: |\n kubectl scale --replicas={{.params.replicas}} \\\n --namespace={{.config.tags.namespace}} \\\n deployment {{.config.name}}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Before running a playbook, users can provide input using ",(0,o.jsx)(n.a,{href:"/docs/reference/playbooks/parameters",children:(0,o.jsx)(n.code,{children:"parameters"})}),".\nIn the playbook above, the user can decide the new number of replicas before running the playbook."]}),"\n",(0,o.jsx)(n.h3,{id:"just-in-time-access",children:"Just In Time Access"}),"\n",(0,o.jsx)(n.h3,{id:"aiops",children:"AIOps"}),"\n",(0,o.jsx)(n.h2,{id:"actions",children:"Actions"}),"\n",(0,o.jsxs)(n.p,{children:["Playbooks execute a sequence of actions (steps), these actions can update git repositories, invoke pipelines or run command line tools like ",(0,o.jsx)(n.code,{children:"kubectl"})," and ",(0,o.jsx)(n.code,{children:"aws"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"templating",children:"Templating"}),"\n",(0,o.jsxs)(n.p,{children:["The actions values can be templated using ",(0,o.jsx)(n.a,{href:"/docs/reference/scripting/gotemplate",children:"Go Templates"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="restart-deployment.yaml"',children:"#...\nkind: Playbook\nspec:\n configs:\n - types:\n - Kubernetes::Deployment\n actions:\n - name: 'Restart kubernetes deployment'\n exec:\n //highlight-next-line\n script: kubectl rollout restart deployment {{.config.name}} -n {{.config.tags.namespace}}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The parameters to the playbooks are available in the ",(0,o.jsx)(n.a,{href:"/docs/reference/playbooks/context",children:"Context"})]}
1),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{alt:"Playbook Action Logs",src:s(45051).A+"",width:"1263",height:"507"})}),"\n",(0,o.jsx)(n.h2,{id:"approval",children:"Approval"}),"\n",(0,o.jsxs)(n.p,{children:["Playbooks can require approval before execution by configuring an ",(0,o.jsx)(n.code,{children:"approval"})," block:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="approve-kubernetes-scaling.yaml"',children:"#...\nkind: Playbook\nspec:\n #...\n approval:\n type: any\n approvers:\n people:\n - admin@local\n teams:\n - DevOps\n"})}),"\n",(0,o.jsxs)(n.table,{children:[(0,o.jsx)(n.thead,{children:(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.th,{children:"Field"}),(0,o.jsx)(n.th,{children:"Description"}),(0,o.jsx)(n.th,{children:"Scheme"}),(0,o.jsx)(n.th,{children:"Required"})]})}),(0,o.jsxs)(n.tbody,{children:[(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.code,{children:"type"})}),(0,o.jsxs)(n.td,{children:["How many approvals required. Defaults to ",(0,o.jsx)(n.code,{children:"all"})]}),(0,o.jsxs)(n.td,{children:[(0,o.jsx)(n.code,{children:"any"})," or ",(0,o.jsx)(n.code,{children:"all"})]}),(0,o.jsx)(n.td,{children:(0,o.jsx)(n.code,{children:"false"})})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.code,{children:"approvers.[]people"})}),(0,o.jsx)(n.td,{children:"Login or id of a person"}),(0,o.jsx)(n.td,{children:(0,o.jsx)(n.code,{children:"People"})}),(0,o.jsx)(n.td,{children:(0,o.jsx)(n.code,{children:"false"})})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.code,{children:"approvers.[]teams"})}),(0,o.jsx)(n.td,{children:"Name or id of a team"}),(0,o.jsx)(n.td,{children:(0,o.jsx)(n.code,{children:"Team"})}),(0,o.jsx)(n.td,{children:(0,o.jsx)(n.code,{children:"false"})})]})]})]}),"\n",(0,o.jsx)(n.h2,{id:"permissions",children:"Permissions"}),"\n",(0,o.jsx)(n.p,{children:"Playbook permissions control who can perform various actions on playbooks."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml"})}),"\n",(0,o.jsx)(n.h3,{id:"required-permissions",children:"Required Permissions"}),"\n",(0,o.jsx)(n.p,{children:"To run a playbook, a principal (user, team, or service account) needs:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.code,{children:"playbook:run"})," permission on the playbook"]}),"\n",(0,o.jsxs)(n.li,{children:["A ",(0,o.jsx)(n.code,{children:"read"})," permission on the resource the playbook targets"]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"For example, to run a playbook that scales a Kubernetes deployment, the principal needs:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"playbook:run"})," permission on the scaling playbook"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"read"})," permission on the target Kubernetes deployment resource"]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"permission-types",children:"Permission Types"}),"\n",(0,o.jsxs)(n.table,{children:[(0,o.jsx)(n.thead,{children:(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.th,{children:"Permission"}),(0,o.jsx)(n.th,{children:"Description"})]})}),(0,o.jsxs)(n.tbody,{children:[(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.code,{children:"playbook:run"})}),(0,o.jsx)(n.td,{children:"Run a playbook"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.code,{children:"playbook:approve"})}),(0,o.jsx)(n.td,{children:"Approve a playbook run"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.code,{children:"playbook:cancel"})}),(0,o.jsx)(n.td,{children:"Cancel a running playbook"})]})]})]}),"\n",(0,o.jsx)(n.h3,{id:"permission-inheritance",children:"Permission Inheritance"}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsx)(n.p,{children:"When a playbook triggers another playbook, the permissions are evaluated using the playbook's identity, not the original user who initiated the first playbook.\nThis means the triggering playbook must have permission to run the target playbook and to read the resources."})})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},45051(e,n,s){const i=s.p+"assets/images/playbook-action-logs-8cd27fdc9887063a28dddef8b0c633c1.png";s.d(n,["A",0,i])},28453(e,n,s){s.d(n,{R:()=>t,x:()=>l});var i=s(96540);const o={},r=i.createContext(o);function t(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.