68 lines
195 KiB
HTML
68 lines
195 KiB
HTML
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1,maximum-scale=1"/><style data-precedence="high" data-href="lite-color-scheme-tokens">:root{color-scheme:light;--invert-in-dark-mode: 0;--blend-in-dark-mode: normal;--color-bg-neutral-primary: #ffffff;--color-bg-neutral-secondary: #f2f2f2;--color-bg-neutral-tertiary: #f9f9f9;--color-bg-neutral-quaternary: #242424;--color-bg-brand-primary: #191919;--color-bg-brand-primary-hover: #080808;--color-bg-accent-secondary: #bbdbba;--color-bg-accent-secondary-hover: #9fcc9e;--color-bg-accent-tertiary: #d2e7d1;--color-bg-accent-quaternary: #e8f3e8;--color-bg-error-primary: #c94a4a;--color-bg-error-primary-hover: #b63636;--color-bg-utility-yellow-primary: #fffae1;--color-bg-utility-blue-primary: #e5f2ff;--color-bg-verified-book-author-intro: #e5f2ff;--color-border-verified-book-author-intro: transparent;--verified-book-author-intro-illustration-scale: 1;--color-fg-neutral-primary: #242424;--color-fg-neutral-primary-hover: #000000;--color-fg-neutral-secondary: #6b6b6b;--color-fg-neutral-secondary-hover: #3f3f3f;--color-fg-neutral-tertiary: #ffffff;--color-fg-accent-primary: #1a8917;--color-fg-accent-primary-hover: #156d12;--color-fg-error-primary: #c94a4a;--color-fg-error-primary-hover: #b63636;--color-fg-utility-blue-primary: #437aff;--color-border-neutral-primary: #f2f2f2;--color-border-neutral-primary-hover: #e5e5e5;--color-border-neutral-secondary: #242424;--color-border-neutral-secondary-hover: #000000;--color-border-neutral-tertiary: #e5e5e5;--color-border-neutral-tertiary-hover: #d2d2d2;--color-border-brand-primary: #191919;--color-border-accent-primary: #1a8917;--color-border-accent-primary-hover: #156d12;--color-border-error-primary: #c94a4a;--color-border-error-primary-hover: #b63636;--color-chart-accent-primary: #1a8917;--color-chart-accent-secondary: #9fcc9e;--color-chart-accent-tertiary: #bbdbba;--color-chart-accent-quaternary: #e8f3e8;--color-chart-utility-yellow-primary: #fea010;--color-chart-utility-yellow-secondary: #ffc017;--color-chart-utility-yellow-tertiary: #fffae1;--color-chart-neutral-primary: #b3b3b3;--color-chart-neutral-secondary: #b3b3b3;--color-chart-neutral-tertiary: #e5e5e5;--color-status-in-review-background: #e5f2ff;--color-status-in-review-text: #437aff;--color-status-edits-requested-background: #fffae1;--color-status-edits-requested-text: #be5b04;--color-story-footer-bg-subtle: #f7f4ed;--color-story-footer-bg-contrast: #242424;--color-story-footer-fg-subtle: #242424;--color-story-footer-fg-contrast: #ffffff;--color-story-footer-placeholder-light-grey: #d2d2d2;--color-story-footer-placeholder-dark-grey: #6b6b6b}</style><script src="https://www.google.com/recaptcha/enterprise.js?render=6Le-uGgpAAAAAPprRaokM8AKthQ9KNGdoxaGUvVp" async=""></script><link rel="icon" href="https://miro.medium.com/v2/5d8de952517e8160e40ef9841c781cdc14a5db313057fa3c3de41c6f5b494b19"/><title>Medium</title><meta name="theme-color" content="#000000"/><meta name="twitter:app:name:iphone" content="Medium"/><meta name="twitter:app:id:iphone" content="828256236"/><meta property="al:ios:app_name" content="Medium"/><meta property="al:ios:app_store_id" content="828256236"/><meta property="al:android:package" content="com.medium.reader"/><meta property="al:android:app_name" content="Medium"/><meta property="fb:app_id" content="542599432471018"/><meta property="og:site_name" content="Medium"/><meta name="apple-itunes-app" content="app-id=828256236, app-argument=/mixpaneleng/automate-rotating-credentials-using-terraform-b0e7dab4d793, affiliate-data=pt=698524&ct=smart_app_banner&mt=8"/><link rel="search" type="application/opensearchdescription+xml" title="Medium" href="/osd.xml"/><link rel="apple-touch-icon" sizes="152x152" href="https://miro.medium.com/v2/resize:fill:304:304/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link rel="apple-touch-icon" sizes="120x120" href="https://miro.medium.com/v2/resize:fill:240:240/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link rel="apple-touch-icon" sizes="76x76" href="https://miro.medium.com/v2/resize:fill:152:152/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link rel="apple-touch-icon" sizes="60x60" href="https://miro.medium.com/v2/resize:fill:120:120/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link rel="mask-icon" href="https://miro.medium.com/v2/resize:fill:1000:1000/7*GAOKVe--MXbEJmV9230oOQ.png" color="#171717"/><link rel="preconnect" href="https://glyph.medium.com" crossorigin=""/><link rel="manifest" href="/manifest.json"/><link rel="preconnect" href="https://www.google.com"/><link rel="preconnect" href="https://www.gstatic.com" crossorigin=""/><link id="glyph_preload_link" rel="preload" as="style" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><title>Automate Rotating Credentials using Terraform | by Andy Leap | Mixpanel Engineering | Medium</title><meta property="og:type" content="article"/><meta property="article:published_time" content="2025-05-14T20:18:39.423Z"/><meta name="title" content="Automate Rotating Credentials using Terraform | by Andy Leap | Mixpanel Engineering | Medium"/><meta property="og:title" content="Automate Rotating Credentials using Terraform"/><meta property="al:android:url" content="medium://p/b0e7dab4d793"/><meta property="al:ios:url" content="medium://p/b0e7dab4d793"/><meta property="al:android:app_name" content="Medium"/><meta name="description" content="Automate Rotating Credentials using Terraform At Mixpanel, keeping your data secure is of the utmost importance. We strictly adhere to security best practices, including rotating credentials often …"/><meta property="og:description" content="At Mixpanel, keeping your data secure is of the utmost importance. We strictly adhere to security best practices, including rotating…"/><meta property="og:url" content="https://medium.com/mixpaneleng/automate-rotating-credentials-using-terraform-b0e7dab4d793"/><meta property="al:web:url" content="https://medium.com/mixpaneleng/automate-rotating-credentials-using-terraform-b0e7dab4d793"/><meta property="og:image" content="https://miro.medium.com/v2/da:true/bc1f8416df0cad099e43cda2872716e5864f18a73bda2a7547ea082aca9b5632"/><meta property="og:image:alt" content="Medium"/><meta property="article:author" content="https://medium.com/@andyleap"/><meta name="author" content="Andy Leap"/><meta name="robots" content="index,follow,max-image-preview:large"/><meta name="referrer" content="unsafe-url"/><meta property="twitter:title" content="Automate Rotating Credentials using Terraform"/><meta name="twitter:site" content="@mixpanel"/><meta name="twitter:app:url:iphone" content="medium://p/b0e7dab4d793"/><meta property="twitter:description" content="At Mixpanel, keeping your data secure is of the utmost importance. We strictly adhere to security best practices, including rotating…"/><meta name="twitter:image:src" content="https://miro.medium.com/v2/da:true/bc1f8416df0cad099e43cda2872716e5864f18a73bda2a7547ea082aca9b5632"/><meta name="twitter:image:alt" content="Medium"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:label1" content="Reading time"/><meta name="twitter:data1" content="8 min read"/><link rel="author" href="https://medium.com/@andyleap"/><link rel="canonical" href="https://medium.com/mixpaneleng/automate-rotating-credentials-using-terraform-b0e7dab4d793"/><link rel="alternate" href="android-app://com.medium.reader/https/medium.com/p/b0e7dab4d793"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/static/manifest-3cf8583e.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/entry-C9P2t20qJW.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-D0WnhmqRYc.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-C11jW0FiNe.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CrjQH3m-gW.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BZidLkaas_.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/entry-CwxkgI60OV.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DXScYH4iYt.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DpwhkAmq4W.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/entry-fBNTF2ig9x.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CXnHTW_oeV.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DnPkHBw3I_.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CYdEVPzgBO.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CQtFW-cnCb.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-Ccx4bzDBz8.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CD5QG4Nr4u.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DdonUN-_p_.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-C0nqQaN4zj.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-Dyqv3_ywby.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DlxwlCRnKY.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-x3yMr9Hj2M.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-D6hKjcUA3T.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-6-s_y3aqFJ.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BQYOJ-mO15.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DP3_7SVASi.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CjgOIT_e7P.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CzYDeZxwQf.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BHu-NPXwPu.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-HvNxSL9udh.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-ByFaBDnwQT.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk---sLyFDcIU.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-Cwg9icNWml.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-I8cQABJjKJ.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-EPww8yA76c.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BW6VYw0uzE.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CZabPPB8tI.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CPynNJqWgE.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-6BSpMonAeB.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DuJ3wvjuqM.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BDd81HQSRF.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CH0gmOPEMW.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DxkCkufq5c.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CUCbM7l4Dj.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-cNcrfj78jd.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DTqgPoTD1a.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-Bne5AQ4h-5.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CGhflpm2Hm.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CNPxQmRnXf.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BX3UAvcF5y.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CRPL1qQoWW.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BfU8uMdn42.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-Bn3GEJ9G7e.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-4m7R-C0Uxl.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CeP5820RVI.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-Q5o9bjyr7s.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-E3gD0vz4qE.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-C839jH4HYq.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-Bn4kth2VY1.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-Cgs_EYwel6.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-zgIIvDkvAP.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-Cl_V_h5b8P.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-wS9mSISbp0.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BJsxkluEP9.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CvnM9G2Pye.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BSxQZl1sLA.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-KzP5Y5LLQP.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DfTA5uCdpU.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CmwWkCGGjS.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DTGFyXOJOa.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DuxEVP_C5g.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CBXapKR9BK.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/entry-DJjt4aY773.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-qI8VCxaJvk.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DCC7-BJDuV.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BWWdZr0USU.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-Ba_Uf5H8ZL.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DSy2ZEdAjr.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CbMw0xIIxH.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-B4miwgxpFB.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BJ72pzEf0s.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-D9y1tiYsrF.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-Cy2g0X2OZx.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-48RYi7P5w4.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CJ9k-wmTwA.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-C5Yqs-oE3u.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DTomAmq_pV.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-vH1AZzDYbp.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BvfKfi9j2g.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-B9W5mp7Pc-.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CL-ZvphHYY.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DvptD6K6cu.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-D5ciu3l8Qw.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CbFLM138qE.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CMTIR1k2Vp.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DetynJx9PY.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-1s_R4bonAJ.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DsHhLSyYeg.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-Z6E5M310NG.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-CIAVaunxWo.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BxOL7DBeLv.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DdbWhtMyTh.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BaolDDrFXO.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DJdM89KVgu.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BBEAsIkFV6.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-LSHJIEs1W4.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-StD-hACT-A.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-BL0RVjf1MM.js"/><link rel="modulepreload" href="https://cdn-client.medium.com/lite/assets/chunk-DYqHmMoGMW.js"/><style type="text/css" data-fela-rehydration="623" data-fela-type="STATIC">html{box-sizing:border-box;-webkit-text-size-adjust:100%}*, *:before, *:after{box-sizing:inherit}body{margin:0;padding:0;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color:var(--color-fg-neutral-primary);position:relative;min-height:100vh}h1, h2, h3, h4, h5, h6, dl, dd, ol, ul, menu, figure, blockquote, p, pre, form{margin:0}menu, ol, ul{padding:0;list-style:none;list-style-image:none}main{display:block}a{color:inherit;text-decoration:none}a, button, input{-webkit-tap-highlight-color:transparent}img, svg{vertical-align:middle}button{background:transparent;overflow:visible}button, input, optgroup, select, textarea{margin:0}:root{--reach-tabs:1;--reach-menu-button:1}#speechify-root{font-family:Sohne, sans-serif}div[data-popper-reference-hidden="true"]{visibility:hidden;pointer-events:none}.grecaptcha-badge{visibility:hidden}
|
||
:root {--color-syntax-keyword: #cf222e;--color-syntax-keyword: light-dark(#cf222e, #ff7b72);--color-syntax-entity: #8250df;--color-syntax-entity: light-dark(#8250df, #d2a8ff);--color-syntax-constant: #0550ae;--color-syntax-constant: light-dark(#0550ae, #79c0ff);--color-syntax-string: #0a3069;--color-syntax-string: light-dark(#0a3069, #a5d6ff);--color-syntax-variable: #953800;--color-syntax-variable: light-dark(#953800, #ffa657);--color-syntax-comment: #656d76;--color-syntax-comment: light-dark(#656d76, #8b949e);--color-syntax-tag: #116329;--color-syntax-tag: light-dark(#116329, #7ee787);--color-syntax-subst: #24292f;--color-syntax-subst: light-dark(#24292f, #c9d1d9);--color-syntax-heading: #0550ae;--color-syntax-heading: light-dark(#0550ae, #58a6ff);--color-syntax-bullet: #3b2300;--color-syntax-bullet: light-dark(#3b2300, #f2cc60);--color-syntax-inserted: #116329;--color-syntax-inserted: light-dark(#116329, #aff5b4);--color-syntax-inserted-bg: #dafbe1;--color-syntax-inserted-bg: light-dark(#dafbe1, #033a16);--color-syntax-deleted: #82071e;--color-syntax-deleted: light-dark(#82071e, #ffdcd7);--color-syntax-deleted-bg: #ffebe9;--color-syntax-deleted-bg: light-dark(#ffebe9, #67060c);
|
||
}.hljs-doctag,
|
||
.hljs-keyword,
|
||
.hljs-meta .hljs-keyword,
|
||
.hljs-template-tag,
|
||
.hljs-template-variable,
|
||
.hljs-type,
|
||
.hljs-variable.language_ {color: var(--color-syntax-keyword);
|
||
}.hljs-title,
|
||
.hljs-title.class_,
|
||
.hljs-title.class_.inherited__,
|
||
.hljs-title.function_ {color: var(--color-syntax-entity);
|
||
}.hljs-attr,
|
||
.hljs-attribute,
|
||
.hljs-literal,
|
||
.hljs-meta,
|
||
.hljs-number,
|
||
.hljs-operator,
|
||
.hljs-variable,
|
||
.hljs-selector-attr,
|
||
.hljs-selector-class,
|
||
.hljs-selector-id {color: var(--color-syntax-constant);
|
||
}.hljs-regexp,
|
||
.hljs-string,
|
||
.hljs-meta .hljs-string {color: var(--color-syntax-string);
|
||
}.hljs-built_in,
|
||
.hljs-symbol {color: var(--color-syntax-variable);
|
||
}.hljs-code,
|
||
.hljs-comment,
|
||
.hljs-formula {color: var(--color-syntax-comment);
|
||
}.hljs-name,
|
||
.hljs-quote,
|
||
.hljs-selector-tag,
|
||
.hljs-selector-pseudo {color: var(--color-syntax-tag);
|
||
}.hljs-subst {color: var(--color-syntax-subst);
|
||
}.hljs-section {color: var(--color-syntax-heading);font-weight: bold;
|
||
}.hljs-bullet {color: var(--color-syntax-bullet);
|
||
}.hljs-addition {color: var(--color-syntax-inserted);background-color: var(--color-syntax-inserted-bg);
|
||
}.hljs-deletion {color: var(--color-syntax-deleted);background-color: var(--color-syntax-deleted-bg);
|
||
}.hljs-doctag,
|
||
.hljs-strong {font-weight: bold;
|
||
}.hljs-emphasis,
|
||
.hljs-formula {font-style: italic;
|
||
}
|
||
</style><style type="text/css" data-fela-rehydration="623" data-fela-type="KEYFRAME">@-webkit-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@-moz-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE">.a{font-family:medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif}.b{font-weight:400}.c{background-color:var(--color-bg-neutral-primary)}.d{display:none}.e{display:block}.f{position:sticky}.g{top:0}.h{z-index:500}.i{padding:0 24px}.j{align-items:center}.k{border-bottom:solid 1px var(--color-border-neutral-primary)}.t{height:41px}.u{line-height:20px}.v{margin-left:8px}.w{color:var(--color-fg-neutral-secondary)}.x{fill:inherit}.y{font-size:13px}.z{font-family:sohne, "Helvetica Neue", Helvetica, Arial, sans-serif}.ab{letter-spacing:inherit}.ac{padding:0}.ae{margin:0}.af{cursor:pointer}.ag:disabled{cursor:not-allowed}.ah:disabled{color:var(--color-fg-neutral-secondary)}.ai:disabled{fill:var(--color-fg-neutral-secondary)}.al{height:100%}.am{display:flex}.be{color:#FFFFFF}.bf{fill:#FFFFFF}.bg{background:#1A8917}.bh{border-color:var(--color-border-accent-primary)}.bl:disabled{cursor:inherit !important}.bm:disabled{opacity:0.3}.bn:disabled:hover{background:#1A8917}.bo:disabled:hover{border-color:var(--color-border-accent-primary)}.bp{border-radius:99em}.bq{border-width:1px}.br{border-style:solid}.bs{box-sizing:border-box}.bt{display:inline-block}.bu{text-decoration:none}.bv{text-align:center}.bw{margin-left:16px}.bx{color:inherit}.by{font-size:inherit}.bz{border:inherit}.ca{font-family:inherit}.cb{font-weight:inherit}.cc{gap:24px}.cd{height:57px}.ce{flex:1 0 auto}.cf{border:none}.cg{width:auto}.ch path{fill:var(--color-fg-neutral-primary)}.ci{height:25px}.cj{margin-left:24px}.cl{border-radius:20px}.cm{width:240px}.cn{background:var(--color-bg-neutral-tertiary)}.co path{fill:var(--color-fg-neutral-secondary)}.cq{outline:none}.cr{font-size:14px}.cs{width:100%}.ct{padding:10px 20px 10px 0}.cu{background-color:transparent}.cv{color:var(--color-fg-neutral-primary)}.cw::placeholder{color:var(--color-fg-neutral-secondary)}.cx{margin-left:12px}.cy{margin-right:12px}.db{gap:4px}.dc{padding:6px 12px}.dd{white-space:nowrap}.de{background-color:var(--color-bg-neutral-quaternary)}.df{width:24px}.dg{height:24px}.dh{flex-shrink:0}.di path{fill:var(--color-fg-neutral-tertiary)}.dj{color:var(--color-fg-neutral-tertiary)}.dm{position:relative}.dn{fill:var(--color-fg-neutral-secondary)}.do{gap:8px}.dr{position:absolute}.ds{width:1px}.dt{height:1px}.du{margin:-1px}.dv{overflow:hidden}.dw{clip:rect(0, 0, 0, 0)}.dx{border-width:0}.dy{margin-right:32px}.dz{background:transparent}.ea svg{margin-left:4px}.eb svg{fill:var(--color-fg-neutral-secondary)}.ed{box-shadow:inset 0 0 0 1px rgba(0, 0, 0, 0.05)}.ee{border-radius:50%}.ef{height:32px}.eg{width:32px}.ei{background-color:var(--color-bg-neutral-secondary)}.ej{flex:0 0 auto}.el{flex:1 1 auto}.er{max-width:100%}.es{text-overflow:ellipsis}.et{padding-top:3px}.eu{border-bottom:1px solid var(--color-border-neutral-primary)}.ev{justify-content:center}.fb{max-width:1192px}.fc{min-width:0}.fi{font-weight:500}.fw{margin:0 8px}.fx{display:inline}.fy{font-size:16px}.fz{line-height:24px}.gb{position:fixed}.gc{top:50%}.gd{right:16px}.ge{transform:translateY(-50%)}.gf{z-index:499}.gh{flex-direction:column}.gi{align-items:flex-end}.gj{padding:12px 4px}.gk{border-radius:999px}.gl{background-color:color-mix(in srgb, var(--color-bg-neutral-primary) 38%, transparent)}.gm{backdrop-filter:blur(10px)}.gn{-webkit-backdrop-filter:blur(10px)}.go{opacity:1}.gp{pointer-events:auto}.gq{transition:opacity 0.18s ease, visibility 0.18s ease}.gs{width:16px}.gt{height:2px}.gu{border-radius:1px}.gv{background-color:var(--color-fg-neutral-primary)}.gw{transition:opacity 0.15s ease, background-color 0.15s ease}.gx{opacity:0.15}.gy{max-width:300px}.gz{max-height:70vh}.ha{border-radius:8px}.hb{box-shadow:0px 0px 4px 0px color-mix(in srgb, var(--color-bg-neutral-quaternary) 5%, transparent), 0px 2px 8px 0px color-mix(in srgb, var(--color-bg-neutral-quaternary) 15%, transparent)}.hc{opacity:0}.hd{visibility:hidden}.he{pointer-events:none}.hf{overflow-y:auto}.hg{overscroll-behavior:contain}.hh{min-height:0}.hi{padding:12px 40px 12px 16px}.hj{list-style-type:none}.hk{padding:2px 0}.hl{width:4px}.hm{height:4px}.hn{background-color:var(--color-fg-accent-primary)}.ho{flex:1}.hp{max-height:20px}.hq{display:-webkit-box}.hr{-webkit-line-clamp:1}.hs{-webkit-box-orient:vertical}.ht{word-break:break-all}.hv{color:var(--color-fg-accent-primary)}.hw{will-change:opacity, transform}.hx{width:calc(100% - 0px)}.ia{transform:translateY(89px)}.ib::before{content:""}.ic::before{position:absolute}.id::before{inset:-12px}.ie::before{z-index:-1}.if::before{border-radius:12px}.ig::before{pointer-events:none}.ih::before{background-color:color-mix(in srgb, var(--color-bg-neutral-primary) 90%, transparent)}.ii::before{backdrop-filter:blur(10px)}.ij::before{-webkit-backdrop-filter:blur(10px)}.ik{width:160px}.il{align-items:flex-start}.im{gap:16px}.in{border-radius:2px}.io{height:38px}.ip{width:38px}.ir{text-decoration:underline}.is{word-wrap:break-word}.it{word-break:break-word}.iz{margin:0 24px}.jd{background:var(--color-bg-neutral-primary)}.je{border:1px solid var(--color-border-neutral-primary)}.jf{border-radius:4px}.jg{box-shadow:0 1px 4px var(--color-border-neutral-primary)}.jh{max-height:100vh}.ji{left:0}.jj{top:calc(100vh + 100px)}.jk{bottom:calc(100vh + 100px)}.jl{width:10px}.jm{margin-bottom:12px}.jn{margin-top:32px}.jo{flex-wrap:wrap}.jp{display:inline-flex}.jq{align-items:stretch}.jr{box-shadow:inset 0 0 0 1px var(--color-border-neutral-primary)}.js{display:contents}.jt{padding:4px 8px 4px 12px}.ju{border-radius:99em 0 0 99em}.jw{padding:4px 8px}.jx{border-radius:0 99em 99em 0}.jy{border-left:1px solid var(--color-border-neutral-primary)}.ka:after{display:block}.kb:after{content:""}.kc:after{clear:both}.kd{line-height:1.23}.ke{letter-spacing:0}.kf{font-style:normal}.kg{font-weight:700}.lb{margin-top:0px}.lc{justify-content:space-between}.ln{gap:12px}.lo{align-items:baseline}.lp{width:36px}.lq{height:36px}.lr{border:2px solid var(--color-bg-neutral-primary)}.ls{z-index:0}.lt{box-shadow:none}.lu{border:1px solid rgba(0, 0, 0, 0.05)}.lv{margin-bottom:2px}.lw{flex-wrap:nowrap}.ly{width:12px}.lz{padding-left:8px}.ma{padding-right:8px}.nb> *{flex-shrink:0}.nc{overflow-x:scroll}.nd::-webkit-scrollbar{display:none}.ne{scrollbar-width:none}.nf{-ms-overflow-style:none}.ng{max-width:74px}.nh{flex-direction:row}.ni{z-index:2}.nj{margin-right:4px}.nm{-webkit-user-select:none}.nn{border:0}.nq{outline:0}.nr{user-select:none}.ns> svg{pointer-events:none}.ob{cursor:progress}.oc{margin-left:32px}.od{margin-left:4px}.oe{padding:4px 0}.oo{padding:8px 2px}.op svg{color:var(--color-fg-neutral-secondary)}.ph{line-height:1.58}.pi{letter-spacing:-0.004em}.pj{font-family:source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif}.qb{margin-bottom:-0.46em}.qc{line-height:1.12}.qd{letter-spacing:-0.022em}.qe{font-weight:600}.qx{margin-bottom:-0.28em}.ri{overflow-x:auto}.rj{font-family:source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace}.rk{padding:32px}.rl{border:1px solid var(--color-border-neutral-tertiary)}.rm{line-height:1.4}.rn{margin-top:-0.2em}.ro{margin-bottom:-0.2em}.rp{white-space:pre}.rq{min-width:fit-content}.rr{padding:2px 4px}.rs{font-size:75%}.rt> strong{font-family:inherit}.ru{margin-bottom:26px}.rv{margin-top:6px}.rw{padding:8px 12px 8px 16px}.rx{padding:8px 12px}.ry{border-top:none}.rz{margin-bottom:50px}.sa{height:52px}.sb{max-height:52px}.sc{box-sizing:content-box}.sd{position:static}.se{z-index:1}.sf{max-width:155px}.sn{margin:0 32px}.so{margin-right:20px}.sp{margin-bottom:64px}.sq{gap:48px}.sr{white-space:pre-wrap}.tj{height:48px}.tk{width:48px}.tl{height:64px}.tm{width:64px}.tn{align-self:flex-end}.tz{margin-top:8px}.ua{margin-top:16px}.ub{animation:k1 1.2s ease-in-out infinite}.uc{padding:32px 0}.ud{border-radius:100%}.ue{margin-top:4px}.uf{margin-bottom:8px}.ug{height:8px}.uh{width:120px}.ui{width:80px}.uj{margin-top:12px}.uk{height:10px}.ul{width:90%}.ur{height:0px}.uu{height:20px}.uv{width:220px}.uw{width:180px}.ux{margin:24px 0}.uy{height:148px}.uz{margin-bottom:32px}.wm{flex-grow:0}.wn{height:200px}.wo{margin-bottom:16px}.wp{width:158px}.wq{height:16px}.wr{width:288px}.ws{width:296px}.wt{margin-bottom:56px}.wu{width:224px}.wv{border-bottom:solid 1px var(--color-border-neutral-tertiary)}.ww{margin-top:72px}.wx{padding:24px 0}.wy{margin-bottom:0px}.wz{margin-right:16px}.aj:hover:not(:disabled){color:var(--color-fg-neutral-primary)}.ak:hover:not(:disabled){fill:var(--color-fg-neutral-primary)}.bi:hover{background:#156D12}.bj:hover{border-color:var(--color-border-accent-primary-hover)}.bk:hover{cursor:pointer}.dp:hover{color:var(--color-fg-neutral-primary)}.dq:hover{fill:var(--color-fg-neutral-primary)}.ec:hover svg{fill:var(--color-fg-neutral-primary)}.eh:hover{background-color:rgba(0, 0, 0, 0.1)}.iq:hover{background-color:none}.jv:hover{background-color:var(--color-bg-neutral-secondary)}.jz:hover{border-left-color:transparent}.lx:hover{text-decoration:underline}.np:hover{fill:var(--color-fg-neutral-secondary-hover)}.of:hover p{color:var(--color-fg-neutral-secondary-hover)}.og:hover{color:var(--color-fg-neutral-secondary-hover)}.oh:hover path{stroke:var(--color-fg-neutral-secondary-hover) !important}.oi:hover{color:var(--color-fg-neutral-primary-hover)}.oq:hover svg{color:var(--color-fg-neutral-primary-hover)}.or:hover p{color:var(--color-fg-neutral-primary-hover)}.cp:focus-within path{fill:var(--color-fg-neutral-primary)}.no:focus-visible{fill:var(--color-fg-neutral-secondary-hover)}.os:focus svg{color:var(--color-fg-neutral-primary-hover)}.nt:active{border-style:none}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="all and (min-width: 1080px)">.s{display:none}.av{font-size:14px}.aw{line-height:20px}.bc{font-size:13px}.bd{padding:5px 12px}.dl{display:flex}.ek{display:block}.fa{margin:0 64px}.fh{max-width:250px}.ft{font-size:20px}.fu{line-height:24px}.fv{letter-spacing:0}.iy{margin-bottom:50px}.jc{max-width:680px}.kx{font-size:42px}.ky{margin-bottom:32px}.kz{line-height:52px}.la{letter-spacing:-0.011em}.ll{align-items:center}.lm{flex-direction:row}.mn{border-top:solid 1px var(--color-bg-neutral-secondary)}.mo{border-bottom:solid 1px var(--color-bg-neutral-secondary)}.mp{margin:32px 0 0}.mq{padding:3px 8px}.mz> *{margin-right:24px}.na> :last-child{margin-right:0}.oa{margin-top:0px}.on{margin:0}.py{margin-top:2.14em}.pz{line-height:32px}.qa{letter-spacing:-0.003em}.qt{font-size:24px}.qu{margin-top:1.95em}.qv{line-height:30px}.qw{letter-spacing:-0.016em}.rc{margin-top:0.94em}.rh{margin-top:56px}.sm{display:inline-block}.ss{gap:8px}.sz{margin-bottom:0}.ta{margin-right:20px}.to{max-width:500px}.uq{margin-bottom:52px}.ve{padding-top:72px}.vr{width:calc(100% + 32px)}.vs{margin-left:-16px}.vt{margin-right:-16px}.wi{padding-left:16px}.wj{padding-right:16px}.wk{flex-basis:50%}.wl{max-width:50%}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="all and (max-width: 1079.98px)">.nz{margin-top:0px}.sj{display:none}.sl{display:inline-block}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="all and (max-width: 903.98px)">.ga{display:none}.ny{margin-top:0px}.si{display:inline-block}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="all and (max-width: 727.98px)">.nw{margin-top:0px}.nx{margin-right:0px}.sh{display:inline-block}.sk{display:none}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="all and (max-width: 551.98px)">.l{display:flex}.m{justify-content:space-between}.an{font-size:13px}.ao{line-height:20px}.ax{padding:0px 8px 1px}.ck{display:none}.em{min-width:100%}.ew{margin:0 24px}.fd{max-width:150px}.fj{font-size:16px}.fk{letter-spacing:0}.iu{margin-bottom:2px}.kh{font-size:32px}.ki{margin-bottom:24px}.kj{line-height:38px}.kk{letter-spacing:-0.014em}.ld{align-items:flex-start}.le{flex-direction:column-reverse}.mb{margin:24px -24px 0}.mc{padding:0}.mr> *{margin-right:8px}.ms> :last-child{margin-right:24px}.nk{margin-left:0px}.nu{margin-top:0px}.nv{margin-right:0px}.oj{margin:0}.ot{border:1px solid var(--color-border-neutral-primary)}.ou{border-radius:99em}.ov{padding:0px 16px 0px 12px}.ow{height:38px}.ox{align-items:center}.oz svg{margin-right:8px}.pk{font-size:18px}.pl{margin-top:1.56em}.pm{line-height:28px}.pn{letter-spacing:-0.003em}.qf{font-size:20px}.qg{margin-top:1.2em}.qh{line-height:24px}.qy{margin-top:0.67em}.rd{margin-top:40px}.sg{display:inline-block}.sx{flex-direction:column}.sy{gap:0}.th{margin-bottom:20px}.ti{margin-right:0}.ts{max-width:100%}.tt{font-size:24px}.tu{line-height:30px}.tv{letter-spacing:-0.016em}.um{margin-bottom:40px}.us{margin-bottom:30px}.va{padding-top:48px}.vf{width:calc(100% + 24px)}.vg{margin-left:-12px}.vh{margin-right:-12px}.vu{padding-left:12px}.vv{padding-right:12px}.vw{flex-basis:100%}.oy:hover{border-color:var(--color-border-neutral-tertiary)}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="all and (min-width: 904px) and (max-width: 1079.98px)">.r{display:none}.at{font-size:14px}.au{line-height:20px}.ba{font-size:13px}.bb{padding:5px 12px}.dk{display:flex}.eq{min-width:100%}.ez{margin:0 64px}.fg{max-width:250px}.fq{font-size:20px}.fr{line-height:24px}.fs{letter-spacing:0}.ix{margin-bottom:50px}.jb{max-width:680px}.kt{font-size:42px}.ku{margin-bottom:32px}.kv{line-height:52px}.kw{letter-spacing:-0.011em}.lj{align-items:center}.lk{flex-direction:row}.mj{border-top:solid 1px var(--color-bg-neutral-secondary)}.mk{border-bottom:solid 1px var(--color-bg-neutral-secondary)}.ml{margin:32px 0 0}.mm{padding:3px 8px}.mx> *{margin-right:24px}.my> :last-child{margin-right:0}.om{margin:0}.pv{margin-top:2.14em}.pw{line-height:32px}.px{letter-spacing:-0.003em}.qp{font-size:24px}.qq{margin-top:1.95em}.qr{line-height:30px}.qs{letter-spacing:-0.016em}.rb{margin-top:0.94em}.rg{margin-top:56px}.st{gap:8px}.tb{margin-bottom:0}.tc{margin-right:20px}.tp{max-width:500px}.up{margin-bottom:52px}.vd{padding-top:72px}.vo{width:calc(100% + 32px)}.vp{margin-left:-16px}.vq{margin-right:-16px}.we{padding-left:16px}.wf{padding-right:16px}.wg{flex-basis:50%}.wh{max-width:50%}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="all and (min-width: 728px) and (max-width: 903.98px)">.p{display:flex}.q{justify-content:space-between}.ar{font-size:13px}.as{line-height:20px}.az{padding:0px 8px 1px}.da{display:none}.ep{min-width:100%}.ey{margin:0 48px}.ff{max-width:250px}.fn{font-size:20px}.fo{line-height:24px}.fp{letter-spacing:0}.iw{margin-bottom:50px}.ja{max-width:680px}.kp{font-size:42px}.kq{margin-bottom:32px}.kr{line-height:52px}.ks{letter-spacing:-0.011em}.lh{align-items:center}.li{flex-direction:row}.mf{border-top:solid 1px var(--color-bg-neutral-secondary)}.mg{border-bottom:solid 1px var(--color-bg-neutral-secondary)}.mh{margin:32px 0 0}.mi{padding:3px 8px}.mv> *{margin-right:24px}.mw> :last-child{margin-right:0}.ol{margin:0}.ps{margin-top:2.14em}.pt{line-height:32px}.pu{letter-spacing:-0.003em}.ql{font-size:24px}.qm{margin-top:1.95em}.qn{line-height:30px}.qo{letter-spacing:-0.016em}.ra{margin-top:0.94em}.rf{margin-top:56px}.su{gap:8px}.td{margin-bottom:0}.te{margin-right:20px}.tq{max-width:500px}.uo{margin-bottom:52px}.vc{padding-top:72px}.vl{width:calc(100% + 28px)}.vm{margin-left:-14px}.vn{margin-right:-14px}.wa{padding-left:14px}.wb{padding-right:14px}.wc{flex-basis:50%}.wd{max-width:50%}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="all and (min-width: 552px) and (max-width: 727.98px)">.n{display:flex}.o{justify-content:space-between}.ap{font-size:13px}.aq{line-height:20px}.ay{padding:0px 8px 1px}.cz{display:none}.eo{min-width:100%}.ex{margin:0 24px}.fe{max-width:150px}.fl{font-size:16px}.fm{letter-spacing:0}.iv{margin-bottom:2px}.kl{font-size:32px}.km{margin-bottom:24px}.kn{line-height:38px}.ko{letter-spacing:-0.014em}.lf{align-items:flex-start}.lg{flex-direction:column-reverse}.md{margin:24px 0 0}.me{padding:0}.mt> *{margin-right:8px}.mu> :last-child{margin-right:8px}.nl{margin-left:0px}.ok{margin:0}.pa{border:1px solid var(--color-border-neutral-primary)}.pb{border-radius:99em}.pc{padding:0px 16px 0px 12px}.pd{height:38px}.pe{align-items:center}.pg svg{margin-right:8px}.po{font-size:18px}.pp{margin-top:1.56em}.pq{line-height:28px}.pr{letter-spacing:-0.003em}.qi{font-size:20px}.qj{margin-top:1.2em}.qk{line-height:24px}.qz{margin-top:0.67em}.re{margin-top:40px}.sv{flex-direction:column}.sw{gap:0}.tf{margin-bottom:20px}.tg{margin-right:0}.tr{max-width:100%}.tw{font-size:24px}.tx{line-height:30px}.ty{letter-spacing:-0.016em}.un{margin-bottom:40px}.ut{margin-bottom:30px}.vb{padding-top:48px}.vi{width:calc(100% + 24px)}.vj{margin-left:-12px}.vk{margin-right:-12px}.vx{padding-left:12px}.vy{padding-right:12px}.vz{flex-basis:100%}.pf:hover{border-color:var(--color-border-neutral-tertiary)}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="print">.gg{display:none}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="(prefers-reduced-motion: reduce)">.gr{transition:none}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="(orientation: landscape) and (max-width: 903.98px)">.hu{max-height:none}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="(prefers-reduced-motion: no-preference)">.hy{transition:opacity 200ms}</style><style type="text/css" data-fela-rehydration="623" data-fela-type="RULE" media="all and (max-width: 1256px)">.hz{display:none}</style></head><body><!--$--><!--/$--><div class="a b c"><a href="/sitemap/sitemap.xml" class="d">Sitemap</a><link id="glyph_link" rel="stylesheet" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><script>document.domain = document.domain;</script><div class="e f g h c"><div class="i j k l m n o p q r s t u"><a class="w x y z ab b ac ae af ag ah ai aj ak l n p r s j al u" href="https://play.google.com/store/apps/details?id=com.medium.reader&referrer=utm_source%3DmobileNavBar&source=---top_nav_layout_nav-------------------------------------------" rel="noopener follow">Open in app<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg" class="v"><path d="M0.984835 8.48484C0.838388 8.63128 0.838388 8.86872 0.984835 9.01516C1.13128 9.16161 1.36872 9.16161 1.51517 9.01516L0.984835 8.48484ZM8.75 1.25H9.125C9.125 1.04289 8.95711 0.875 8.75 0.875V1.25ZM8.375 6.5C8.375 6.70711 8.54289 6.875 8.75 6.875C8.95711 6.875 9.125 6.70711 9.125 6.5H8.375ZM3.5 0.875C3.29289 0.875 3.125 1.04289 3.125 1.25C3.125 1.45711 3.29289 1.625 3.5 1.625V0.875ZM1.51517 9.01516L9.01516 1.51517L8.48484 0.984835L0.984835 8.48484L1.51517 9.01516ZM8.375 1.25V6.5H9.125V1.25H8.375ZM3.5 1.625H8.75V0.875H3.5V1.625Z" fill="currentColor"></path></svg></a><div class="am j"><p class="z b an ao ap aq ar as at au av aw w"><span data-dd-action-name="Susi presentation tracker global_nav"><button class="z b an ao ax ap aq ay ar as az ba au bb bc aw bd be bf bg bh bi bj bk bl bm bn bo bp bq br bs bt bu bv" data-testid="headerSignUpButton">Sign up</button></span></p><div class="bw e"><p class="z b an ao ap aq ar as at au av aw w"><span data-dd-action-name="Susi presentation tracker global_nav"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" data-testid="headerSignInButton" rel="noopener follow" href="/m/signin?operation=login&redirect=https%3A%2F%2Fmedium.com%2Fmixpaneleng%2Fautomate-rotating-credentials-using-terraform-b0e7dab4d793&source=post_page---top_nav_layout_nav-----------------------global_nav--------------------" data-discover="true">Sign in</a></span></p></div></div></div><div class="i j k am cc cd"><div class="am j ce"><a class="bx x by cf ca ab cb ac ae af ag ah ai aj ak am" aria-label="Homepage" data-testid="headerMediumLogo" rel="noopener follow" href="/?source=---top_nav_layout_nav-------------------------------------------" data-discover="true"><svg xmlns="http://www.w3.org/2000/svg" width="719" height="160" fill="none" aria-labelledby="wordmark-medium-desc" viewBox="0 0 719 160" class="cg ch ci"><desc>Medium Logo</desc><path fill="#242424" d="m174.104 9.734.215-.047V8.02H130.39L89.6 103.89 48.81 8.021H1.472v1.666l.212.047c8.018 1.81 12.09 4.509 12.09 14.242V137.93c0 9.734-4.087 12.433-12.106 14.243l-.212.047v1.671h32.118v-1.665l-.213-.048c-8.018-1.809-12.089-4.509-12.089-14.242V30.586l52.399 123.305h2.972l53.925-126.743V140.75c-.687 7.688-4.721 10.062-11.982 11.701l-.215.05v1.652h55.948v-1.652l-.215-.05c-7.269-1.639-11.4-4.013-12.087-11.701l-.037-116.774h.037c0-9.733 4.071-12.432 12.087-14.242m25.555 75.488c.915-20.474 8.268-35.252 20.606-35.507 3.806.063 6.998 1.312 9.479 3.714 5.272 5.118 7.751 15.812 7.368 31.793zm-.553 5.77h65.573v-.275c-.186-15.656-4.721-27.834-13.466-36.196-7.559-7.227-18.751-11.203-30.507-11.203h-.263c-6.101 0-13.584 1.48-18.909 4.16-6.061 2.807-11.407 7.003-15.855 12.511-7.161 8.874-11.499 20.866-12.554 34.343q-.05.606-.092 1.212a50 50 0 0 0-.065 1.151 85.807 85.807 0 0 0-.094 5.689c.71 30.524 17.198 54.917 46.483 54.917 25.705 0 40.675-18.791 44.407-44.013l-1.886-.664c-6.557 13.556-18.334 21.771-31.738 20.769-18.297-1.369-32.314-19.922-31.042-42.395m139.722 41.359c-2.151 5.101-6.639 7.908-12.653 7.908s-11.513-4.129-15.418-11.63c-4.197-8.053-6.405-19.436-6.405-32.92 0-28.067 8.729-46.22 22.24-46.22 5.657 0 10.111 2.807 12.236 7.704zm43.499 20.008c-8.019-1.897-12.089-4.722-12.089-14.951V1.309l-48.716 14.353v1.757l.299-.024c6.72-.543 11.278.386 13.925 2.83 2.072 1.915 3.082 4.853 3.082 8.987v18.66c-4.803-3.067-10.516-4.56-17.448-4.56-14.059 0-26.909 5.92-36.176 16.672-9.66 11.205-14.767 26.518-14.767 44.278-.003 31.72 15.612 53.039 38.851 53.039 13.595 0 24.533-7.449 29.54-20.013v16.865h43.711v-1.746zM424.1 19.819c0-9.904-7.468-17.374-17.375-17.374-9.859 0-17.573 7.632-17.573 17.374s7.721 17.374 17.573 17.374c9.907 0 17.375-7.47 17.375-17.374m11.499 132.546c-8.019-1.897-12.089-4.722-12.089-14.951h-.035V43.635l-43.714 12.551v1.705l.263.024c9.458.842 12.047 4.1 12.047 15.152v81.086h43.751v-1.746zm112.013 0c-8.018-1.897-12.089-4.722-12.089-14.951V43.635l-41.621 12.137v1.71l.246.026c7.733.813 9.967 4.257 9.967 15.36v59.279c-2.578 5.102-7.415 8.131-13.274 8.336-9.503 0-14.736-6.419-14.736-18.073V43.638l-43.714 12.55v1.703l.262.024c9.459.84 12.05 4.097 12.05 15.152v50.17a56.3 56.3 0 0 0 .91 10.444l.787 3.423c3.701 13.262 13.398 20.197 28.59 20.197 12.868 0 24.147-7.966 29.115-20.43v17.311h43.714v-1.747zm169.818 1.788v-1.749l-.213-.05c-8.7-2.006-12.089-5.789-12.089-13.49v-63.79c0-19.89-11.171-31.761-29.883-31.761-13.64 0-25.141 7.882-29.569 20.16-3.517-13.01-13.639-20.16-28.606-20.16-13.146 0-23.449 6.938-27.869 18.657V43.643L545.487 55.68v1.715l.263.024c9.345.829 12.047 4.181 12.047 14.95v81.784h40.787v-1.746l-.215-.053c-6.941-1.631-9.181-4.606-9.181-12.239V66.998c1.836-4.289 5.537-9.37 12.853-9.37 9.086 0 13.692 6.296 13.692 18.697v77.828h40.797v-1.746l-.215-.053c-6.94-1.631-9.18-4.606-9.18-12.239V75.066a42 42 0 0 0-.578-7.26c1.947-4.661 5.86-10.177 13.475-10.177 9.214 0 13.691 6.114 13.691 18.696v77.828z"></path></svg></a><div class="cj ck"><div class="am cf cl cm cn j co cp"><div class="bt" aria-describedby="searchResults" aria-labelledby="searchResults" aria-haspopup="listbox"></div><div class="cx cy am"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.09234 11.06C4.09234 10.1473 4.27211 9.24358 4.62138 8.40036C4.97065 7.55715 5.48258 6.79099 6.12795 6.14562C6.77332 5.50026 7.53948 4.98832 8.38269 4.63905C9.2259 4.28978 10.1297 4.11001 11.0423 4.11001C11.955 4.11001 12.8588 4.28978 13.702 4.63905C14.5452 4.98832 15.3114 5.50026 15.9567 6.14562C16.6021 6.79099 17.114 7.55715 17.4633 8.40036C17.8126 9.24358 17.9923 10.1473 17.9923 11.06C17.9923 12.9033 17.2601 14.671 15.9567 15.9744C14.6534 17.2778 12.8856 18.01 11.0423 18.01C9.19909 18.01 7.43133 17.2778 6.12795 15.9744C4.82457 14.671 4.09234 12.9033 4.09234 11.06ZM11.0423 3.01001C9.75141 3.01124 8.4797 3.32292 7.33449 3.91876C6.18929 4.51459 5.20418 5.37711 4.46226 6.43355C3.72034 7.48999 3.24337 8.70937 3.07159 9.98883C2.89981 11.2683 3.03825 12.5703 3.47525 13.785C3.91224 14.9997 4.63497 16.0915 5.58245 16.9683C6.52994 17.8451 7.6744 18.4812 8.9193 18.8229C10.1642 19.1646 11.473 19.2019 12.7353 18.9316C13.9977 18.6613 15.1765 18.0915 16.1723 17.27L19.9223 21.02C19.9727 21.078 20.0345 21.1251 20.1039 21.1582C20.1732 21.1913 20.2487 21.2098 20.3255 21.2125C20.4023 21.2152 20.4788 21.2021 20.5504 21.1739C20.6219 21.1458 20.6868 21.1032 20.7412 21.0488C20.7955 20.9945 20.8381 20.9295 20.8662 20.858C20.8944 20.7865 20.9075 20.71 20.9048 20.6332C20.9021 20.5563 20.8836 20.4809 20.8505 20.4116C20.8174 20.3422 20.7704 20.2804 20.7123 20.23L16.9823 16.5C18.0418 15.3483 18.7426 13.9128 18.999 12.3691C19.2554 10.8253 19.0564 9.24032 18.4261 7.80795C17.7959 6.37559 16.7618 5.15798 15.4504 4.30407C14.1391 3.45017 12.6072 2.997 11.0423 3.00001V3.01001Z" fill="currentColor"></path></svg></div><input role="combobox" aria-controls="searchResults" aria-expanded="false" aria-label="search" data-testid="headerSearchInput" tabindex="0" class="cf cq z cr u cs ct cu cv cw" placeholder="Search" value=""/></div></div></div><div class="ck cz da"><button type="button" class="am j db dc bp cf af dd de" aria-label="Get the Medium app"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" class="df dg dh di"><g clip-path="url(#a)"><path fill="#000" d="M9.75 3.938h-4.5A1.313 1.313 0 0 0 3.938 5.25v4.5a1.313 1.313 0 0 0 1.312 1.313h4.5a1.31 1.31 0 0 0 1.313-1.313v-4.5A1.31 1.31 0 0 0 9.75 3.938m.188 5.812a.187.187 0 0 1-.188.188h-4.5a.187.187 0 0 1-.187-.188v-4.5a.187.187 0 0 1 .187-.187h4.5a.187.187 0 0 1 .188.187zm-.188 3.188h-4.5a1.313 1.313 0 0 0-1.312 1.312v4.5a1.313 1.313 0 0 0 1.312 1.313h4.5a1.31 1.31 0 0 0 1.313-1.313v-4.5a1.31 1.31 0 0 0-1.313-1.312m.188 5.812a.19.19 0 0 1-.188.188h-4.5a.19.19 0 0 1-.187-.188v-4.5a.19.19 0 0 1 .187-.187h4.5a.19.19 0 0 1 .188.187zM18.75 3.938h-4.5a1.313 1.313 0 0 0-1.312 1.312v4.5a1.31 1.31 0 0 0 1.312 1.313h4.5a1.31 1.31 0 0 0 1.313-1.313v-4.5a1.313 1.313 0 0 0-1.313-1.312m.188 5.812a.19.19 0 0 1-.188.188h-4.5a.19.19 0 0 1-.187-.188v-4.5a.19.19 0 0 1 .187-.187h4.5a.19.19 0 0 1 .188.187zm-6 6.75v-3a.562.562 0 1 1 1.124 0v3a.562.562 0 1 1-1.124 0m7.124-1.5a.56.56 0 0 1-.562.563h-2.437V19.5a.56.56 0 0 1-.563.563h-3a.562.562 0 1 1 0-1.125h2.438V13.5a.562.562 0 1 1 1.124 0v.938H19.5a.56.56 0 0 1 .563.562m0 3v1.5a.562.562 0 1 1-1.125 0V18a.562.562 0 1 1 1.125 0"></path></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h24v24H0z"></path></clipPath></defs></svg><span class="z b cr u dj">Get app</span></button></div><div class="ck cz p dk dl"><span data-dd-action-name="Susi presentation tracker new_post_topnav"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" data-testid="headerWriteButton" rel="noopener follow" href="/m/signin?operation=register&redirect=https%3A%2F%2Fmedium.com%2Fnew-story&source=---top_nav_layout_nav-----------------------new_post_topnav--------------------" data-discover="true"><div class="z b cr u w dm dn am j do dp dq"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M14 4C14.2761 4 14.5 3.77614 14.5 3.5C14.5 3.22386 14.2761 3 14 3V4ZM21 10C21 9.72386 20.7761 9.5 20.5 9.5C20.2239 9.5 20 9.72386 20 10H21ZM14 3H4V4H14V3ZM3 4V20H4V4H3ZM4 21H20V20H4V21ZM21 20V10H20V20H21ZM20 21C20.5523 21 21 20.5523 21 20H20V21ZM3 20C3 20.5523 3.44771 21 4 21V20H3ZM4 3C3.44772 3 3 3.44772 3 4H4H4V3Z" fill="currentColor"></path><path d="M17.5 4.5L9.04173 12.9583C9.01429 12.9857 8.99361 13.0192 8.98134 13.056L8.15811 15.5257C8.09297 15.7211 8.2789 15.907 8.47434 15.8419L10.944 15.0187C10.9808 15.0064 11.0143 14.9857 11.0417 14.9583L19.5 6.5M17.5 4.5L19.8232 2.17678C19.9209 2.07915 20.0791 2.07915 20.1768 2.17678L21.8232 3.82322C21.9209 3.92085 21.9209 4.07915 21.8232 4.17678L19.5 6.5M17.5 4.5L19.5 6.5" stroke="currentColor"></path></svg>Write</div></a></span></div><div class="cz da r s"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" data-testid="headerSearchButton" rel="noopener follow" href="/search?source=---top_nav_layout_nav-------------------------------------------" data-discover="true"><div class="z b cr u w dm dn am j do dp dq"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.09234 11.06C4.09234 10.1473 4.27211 9.24358 4.62138 8.40036C4.97065 7.55715 5.48258 6.79099 6.12795 6.14562C6.77332 5.50026 7.53948 4.98832 8.38269 4.63905C9.2259 4.28978 10.1297 4.11001 11.0423 4.11001C11.955 4.11001 12.8588 4.28978 13.702 4.63905C14.5452 4.98832 15.3114 5.50026 15.9567 6.14562C16.6021 6.79099 17.114 7.55715 17.4633 8.40036C17.8126 9.24358 17.9923 10.1473 17.9923 11.06C17.9923 12.9033 17.2601 14.671 15.9567 15.9744C14.6534 17.2778 12.8856 18.01 11.0423 18.01C9.19909 18.01 7.43133 17.2778 6.12795 15.9744C4.82457 14.671 4.09234 12.9033 4.09234 11.06ZM11.0423 3.01001C9.75141 3.01124 8.4797 3.32292 7.33449 3.91876C6.18929 4.51459 5.20418 5.37711 4.46226 6.43355C3.72034 7.48999 3.24337 8.70937 3.07159 9.98883C2.89981 11.2683 3.03825 12.5703 3.47525 13.785C3.91224 14.9997 4.63497 16.0915 5.58245 16.9683C6.52994 17.8451 7.6744 18.4812 8.9193 18.8229C10.1642 19.1646 11.473 19.2019 12.7353 18.9316C13.9977 18.6613 15.1765 18.0915 16.1723 17.27L19.9223 21.02C19.9727 21.078 20.0345 21.1251 20.1039 21.1582C20.1732 21.1913 20.2487 21.2098 20.3255 21.2125C20.4023 21.2152 20.4788 21.2021 20.5504 21.1739C20.6219 21.1458 20.6868 21.1032 20.7412 21.0488C20.7955 20.9945 20.8381 20.9295 20.8662 20.858C20.8944 20.7865 20.9075 20.71 20.9048 20.6332C20.9021 20.5563 20.8836 20.4809 20.8505 20.4116C20.8174 20.3422 20.7704 20.2804 20.7123 20.23L16.9823 16.5C18.0418 15.3483 18.7426 13.9128 18.999 12.3691C19.2554 10.8253 19.0564 9.24032 18.4261 7.80795C17.7959 6.37559 16.7618 5.15798 15.4504 4.30407C14.1391 3.45017 12.6072 2.997 11.0423 3.00001V3.01001Z" fill="currentColor"></path></svg><span class="dr ds dt ac du dv dw dd dx speechify-ignore">Search</span></div></a></div><div class="dy ck cz da"><div class="am j"><p class="z b an ao ap aq ar as at au av aw w"><span data-dd-action-name="Susi presentation tracker global_nav"><button class="z b an ao ax ap aq ay ar as az ba au bb bc aw bd be bf bg bh bi bj bk bl bm bn bo bp bq br bs bt bu bv" data-testid="headerSignUpButton">Sign up</button></span></p><div class="bw e"><p class="z b an ao ap aq ar as at au av aw w"><span data-dd-action-name="Susi presentation tracker global_nav"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" data-testid="headerSignInButton" rel="noopener follow" href="/m/signin?operation=login&redirect=https%3A%2F%2Fmedium.com%2Fmixpaneleng%2Fautomate-rotating-credentials-using-terraform-b0e7dab4d793&source=post_page---top_nav_layout_nav-----------------------global_nav--------------------" data-discover="true">Sign in</a></span></p></div></div></div><div class="e"><div><div class="bt"><div tabindex="-1" class="cq"><button class="cf dz ac am j af dm ea eb ec" aria-label="user options menu" data-testid="headerUserIcon"><div class="e dm"><img alt="Unknown user" class="e bs ee ef eg ei" src="https://miro.medium.com/v2/resize:fill:64:64/1*dmbNkD5D-u45r44go_cf0g.png" width="32" height="32" loading="lazy"/><div class="ed ee e ef eg dr g cf eh"></div></div></button></div></div></div></div></div></div><div class="am"><div class="ej ck cz da r ek" style="width:0px"></div><div class="el cs em eo ep eq" style="width:calc(100% - 0px)"><div class="e"><div><div class="et eu cs e"><div class="am ev"><div class="ew ex ey ez fa fb fc cs"><div class="cd am j"><div class="fd fe ff fg fh e"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" href="https://medium.com/mixpaneleng?source=post_page---publication_nav-b5de3443ad1f-b0e7dab4d793-----------------------------------------" rel="noopener follow"><h2 class="z fi fj ao fk fl aq fm fn fo fp fq fr fs ft fu fv cv"><div class="er dv es dd">Mixpanel Engineering</div></h2></a></div><div class="l n da r s"><span class="fw fx" aria-hidden="true"><span class="z b fy fz cv">·</span></span><p class="z b fy fz cv"></p></div></div></div></div></div></div><nav class="ga" aria-label="Table of contents"><button type="button" aria-label="Table of contents" aria-haspopup="true" aria-expanded="false" aria-controls="_R_fjabr5_" class="gb gc gd ge gf gg am gh gi do ae gj cf af gk gl gm gn go gp gq gr"><span aria-hidden="true" class="e gs gt gu go gv gw gr"></span><span aria-hidden="true" class="e gs gt gu gx de gw gr"></span><span aria-hidden="true" class="e gs gt gu gx de gw gr"></span><span aria-hidden="true" class="e gs gt gu gx de gw gr"></span><span aria-hidden="true" class="e gs gt gu gx de gw gr"></span><span aria-hidden="true" class="e gs gt gu gx de gw gr"></span></button><div id="_R_fjabr5_" class="gb gc gd ge gf gg am gh gy gz dv ha c hb hc hd he gq gr" data-testid="toc-popover"><div class="hf hg hh hi"><ol class="ae ac hj"><li class="hk"><a class="hv x cr bz z ab b ac ae af ag ah ai aj ak am j do u" title="Rotation == Toil" aria-current="location" href="/?source=post_page-----b0e7dab4d793-----------------------------------------#52fc" rel="noopener follow"><span aria-hidden="true" class="dh hl hm ee hn"></span><span class="ho fc z b cr u dv hp es hq hr hs ht hu bx">Rotation == Toil</span></a></li><li class="hk"><a class="w x cr bz z ab b ac ae af ag ah ai aj ak am j do u" title="Terraform" href="/?source=post_page-----b0e7dab4d793-----------------------------------------#bfb9" rel="noopener follow"><span aria-hidden="true" class="dh hl hm ee cu"></span><span class="ho fc z b cr u dv hp es hq hr hs ht hu bx">Terraform</span></a></li><li class="hk"><a class="w x cr bz z ab b ac ae af ag ah ai aj ak am j do u" title="Invalidation" href="/?source=post_page-----b0e7dab4d793-----------------------------------------#fae4" rel="noopener follow"><span aria-hidden="true" class="dh hl hm ee cu"></span><span class="ho fc z b cr u dv hp es hq hr hs ht hu bx">Invalidation</span></a></li><li class="hk"><a class="w x cr bz z ab b ac ae af ag ah ai aj ak am j do u" title="We wrote a Terraform provider: multirotate_set" href="/?source=post_page-----b0e7dab4d793-----------------------------------------#3cad" rel="noopener follow"><span aria-hidden="true" class="dh hl hm ee cu"></span><span class="ho fc z b cr u dv hp es hq hr hs ht hu bx">We wrote a Terraform provider: multirotate_set</span></a></li><li class="hk"><a class="w x cr bz z ab b ac ae af ag ah ai aj ak am j do u" title="Enhancement: Expiration" href="/?source=post_page-----b0e7dab4d793-----------------------------------------#bb9a" rel="noopener follow"><span aria-hidden="true" class="dh hl hm ee cu"></span><span class="ho fc z b cr u dv hp es hq hr hs ht hu bx">Enhancement: Expiration</span></a></li><li class="hk"><a class="w x cr bz z ab b ac ae af ag ah ai aj ak am j do u" title="Automation" href="/?source=post_page-----b0e7dab4d793-----------------------------------------#e145" rel="noopener follow"><span aria-hidden="true" class="dh hl hm ee cu"></span><span class="ho fc z b cr u dv hp es hq hr hs ht hu bx">Automation</span></a></li></ol></div></div></nav><script type="application/ld+json">{"@context":"https://schema.org","@id":"https://medium.com/mixpaneleng/automate-rotating-credentials-using-terraform-b0e7dab4d793","@type":"SocialMediaPosting","image":["https://miro.medium.com/"],"url":"https://medium.com/mixpaneleng/automate-rotating-credentials-using-terraform-b0e7dab4d793","dateCreated":"2024-07-29T22:42:05Z","datePublished":"2024-07-29T22:42:05Z","dateModified":"2025-05-14T20:18:39Z","headline":"Automate Rotating Credentials using Terraform","name":"Automate Rotating Credentials using Terraform","description":"Automate Rotating Credentials using Terraform At Mixpanel, keeping your data secure is of the utmost importance. We strictly adhere to security best practices, including rotating credentials often …","identifier":"b0e7dab4d793","author":{"@context":"https://schema.org","@id":"https://medium.com/@andyleap","@type":"Person","identifier":"andyleap","name":"Andy Leap","url":"https://medium.com/@andyleap"},"creator":{"@context":"https://schema.org","@id":"https://medium.com/@andyleap","@type":"Person","identifier":"andyleap","name":"Andy Leap","url":"https://medium.com/@andyleap"},"publisher":{"@context":"https://schema.org","@type":"Organization","@id":"https://medium.com/mixpaneleng","name":"Mixpanel Engineering","description":"Blog is now hosted at https://mixpanel.substack.com","url":"https://medium.com/mixpaneleng","sameAs":["https://twitter.com/mixpanel"],"logo":{"@type":"ImageObject","width":280,"height":280,"url":"https://miro.medium.com/v2/resize:fit:280/1%2AwdBmRrZ2IldG8fNVhER_xg.png"}},"mainEntityOfPage":"https://medium.com/mixpaneleng/automate-rotating-credentials-using-terraform-b0e7dab4d793","isAccessibleForFree":true}</script><div class="he dr hw hx g hy hz hc ia"><div class="am ev"><div class="ew ex ey ez fa fb fc cs"><div class="ik e"><div class="he dm ib ic id ie if ig ih ii ij"><div class="am il gh im"><a href="https://medium.com/mixpaneleng?source=post_page---post_publication_sidebar-b5de3443ad1f-b0e7dab4d793-----------------------------------------" rel="noopener follow"><div class="dm"><img alt="Mixpanel Engineering" class="ei in e ip io" src="https://miro.medium.com/v2/resize:fill:76:76/1*wdBmRrZ2IldG8fNVhER_xg.png" width="38" height="38" loading="lazy"/><div class="in e io ip dr g ed iq"></div></div></a><p class="z b cr u w">Blog is now hosted at <a class="bx x by bz ca ab cb ac ae af ag ah ai ir is it" href="https://mixpanel.substack.com" rel="noopener ugc nofollow">https://mixpanel.substack.com</a></p><p class="z b cr u cv"></p></div></div></div></div></div></div><div class="iu iv iw ix iy e"><div class="am ev"><div class="fc cs iz ja jb jc"></div></div><article><div class="e"><div class="e"><span class="e"></span><section><div><div class="dr ji jj jk jl he"></div><div><div class="am ev"><div class="fc cs iz ja jb jc"><div class="speechify-ignore jm jn am j jo do"><div class="jp jq bp jr dd"><div class="js"><div class="am"><div class="am" aria-haspopup="dialog"><a class="bx x by cf ca ab cb jt ae af ag ah ai aj ak am j ju jv" rel="noopener follow" href="/tag/terraform?source=post_page---header_tags--b0e7dab4d793-----------------------------------------" data-discover="true"><span class="z b y u cv">Terraform</span></a></div></div></div><button aria-label="Follow Terraform" class="w dn by cf ca ab cb jw ae af ag bm am j jx jy jv jz dp"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M5.96219 1V6M5.96219 11V6M5.96219 6H11M5.96219 6H1" stroke="currentColor" stroke-linecap="round"></path></svg></button></div><div class="jp jq bp jr dd"><div class="js"><div class="am"><div class="am" aria-haspopup="dialog"><a class="bx x by cf ca ab cb jt ae af ag ah ai aj ak am j ju jv" rel="noopener follow" href="/tag/automation?source=post_page---header_tags--b0e7dab4d793-----------------------------------------" data-discover="true"><span class="z b y u cv">Automation</span></a></div></div></div><button aria-label="Follow Automation" class="w dn by cf ca ab cb jw ae af ag bm am j jx jy jv jz dp"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M5.96219 1V6M5.96219 11V6M5.96219 6H11M5.96219 6H1" stroke="currentColor" stroke-linecap="round"></path></svg></button></div><div class="jp jq bp jr dd"><div class="js"><div class="am"><div class="am" aria-haspopup="dialog"><a class="bx x by cf ca ab cb jt ae af ag ah ai aj ak am j ju jv" rel="noopener follow" href="/tag/credentials?source=post_page---header_tags--b0e7dab4d793-----------------------------------------" data-discover="true"><span class="z b y u cv">Credentials</span></a></div></div></div><button aria-label="Follow Credentials" class="w dn by cf ca ab cb jw ae af ag bm am j jx jy jv jz dp"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M5.96219 1V6M5.96219 11V6M5.96219 6H11M5.96219 6H1" stroke="currentColor" stroke-linecap="round"></path></svg></button></div><div class="jp jq bp jr dd"><div class="js"><div class="am"><div class="am" aria-haspopup="dialog"><a class="bx x by cf ca ab cb jt ae af ag ah ai aj ak am j ju jv" rel="noopener follow" href="/tag/security?source=post_page---header_tags--b0e7dab4d793-----------------------------------------" data-discover="true"><span class="z b y u cv">Security</span></a></div></div></div><button aria-label="Follow Security" class="w dn by cf ca ab cb jw ae af ag bm am j jx jy jv jz dp"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M5.96219 1V6M5.96219 11V6M5.96219 6H11M5.96219 6H1" stroke="currentColor" stroke-linecap="round"></path></svg></button></div></div></div></div></div><div class="it is ka kb kc"><div class="am ev"><div class="fc cs iz ja jb jc"><div><h1 id="4ce2" class="pw-post-title kd ke kf z kg kh ki kj kk kl km kn ko kp kq kr ks kt ku kv kw kx ky kz la lb cv" data-testid="storyTitle">Automate Rotating Credentials using Terraform</h1><div><div class="speechify-ignore am lc"><div class="speechify-ignore cs e"><div class="am ld le lf lg lh li lj lk ll lm ln"><div class="am j ln"><div class="am lo"><div><div class="bt"><a rel="noopener follow" href="/@andyleap?source=post_page---byline--b0e7dab4d793-----------------------------------------" data-discover="true"><div class="e lp lq ee lr ls"><div class="e dm"><img alt="Andy Leap" class="e bs ee ef eg ei" src="https://miro.medium.com/v2/resize:fill:64:64/0*9nItFvX1uxUt2po7." width="32" height="32" loading="lazy" data-testid="authorPhoto"/><div class="lt ee e ef eg dr g lu eh"></div></div></div></a></div></div></div><span class="z b cr u cv"><div class="lv am j"><div class="am j lw"><div class="am j"><div><div class="bt"><span class="z b cr u cv"><a class="bx x by bz ca ab cb ac ae af ag ah ai lx" data-testid="authorName" rel="noopener follow" href="/@andyleap?source=post_page---byline--b0e7dab4d793-----------------------------------------" data-discover="true">Andy Leap</a></span></div></div></div><div class="ly bt"></div></div></div></span></div><div class="am j jo"><span class="z b cr u w"><div class="am ce"><span data-testid="storyReadTime">8 min read</span><div class="lz ma e" aria-hidden="true"><span class="e" aria-hidden="true"><span class="z b cr u w">·</span></span></div><span data-testid="storyPublishDate">Jul 29, 2024</span></div></span></div></div><div class="am lc mb mc md me mf mg mh mi mj mk ml mm mn mo mp mq"><div class="ck cz p dk dl j"><div class="am j"><div class="ng e"><div class="am j nh ni"><div class="pw-multi-vote-icon dm nj nk nl nm"><span data-dd-action-name="Susi presentation tracker clap_footer"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" data-testid="headerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fmixpaneleng%2Fb0e7dab4d793&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fmixpaneleng%2Fautomate-rotating-credentials-using-terraform-b0e7dab4d793&user=Andy+Leap&userId=4f202918f2e7&source=---header_actions--b0e7dab4d793---------------------clap_footer--------------------" data-discover="true"><div><div class="bt"><div tabindex="-1" class="cq"><div class="nn af dn no np nq ac nr ns nt nm" role="presentation"><svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-label="clap"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.3702 0.827583L12 3.2822L12.6298 0.827583H11.3702Z"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M13.9159 3.95255L15.4386 1.84138L14.2552 1.45158L13.9159 3.95255Z"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M8.58869 1.84055L10.1114 3.95172L9.77379 1.45076L8.58869 1.84055Z"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M18.523 18.9192C17.6623 19.7799 16.7727 20.1664 15.9029 20.25C16.0419 20.1341 16.1776 20.01 16.3101 19.8776C18.6976 17.4891 19.1702 14.9269 17.7087 12.2547L16.7975 10.6516L16.0072 8.9799C15.7465 8.42046 15.8127 7.99921 16.2099 7.69218C16.2866 7.63312 16.3749 7.59082 16.469 7.56801C16.5631 7.5452 16.6609 7.54239 16.7561 7.55977C17.0392 7.60611 17.3023 7.79149 17.4836 8.06046L19.8472 12.2174C20.8229 13.8411 20.9884 16.4538 18.523 18.9192ZM7.52441 18.4822L3.36992 14.3278C3.25591 14.2118 3.1786 14.0648 3.14765 13.9051C3.1167 13.7454 3.13348 13.5802 3.19591 13.43C3.25833 13.2798 3.36363 13.1513 3.49864 13.0606C3.63365 12.9699 3.79239 12.921 3.95503 12.92C4.16606 12.92 4.37875 13.0011 4.54013 13.1617L6.69765 15.3192C6.76738 15.3812 6.85815 15.4142 6.9514 15.4114C7.04465 15.4087 7.13333 15.3704 7.1993 15.3044C7.26526 15.2385 7.30353 15.1498 7.30627 15.0566C7.30902 14.9633 7.27603 14.8725 7.21406 14.8028L5.05655 12.6445L3.60827 11.1962C3.4532 11.0414 3.36595 10.8314 3.36572 10.6124C3.36549 10.3933 3.45229 10.1831 3.60703 10.028C3.76177 9.87297 3.97177 9.78572 4.19084 9.78549C4.40991 9.78526 4.6201 9.87206 4.77517 10.0268L8.21296 13.4662C8.2468 13.5003 8.28703 13.5273 8.33134 13.5457C8.37566 13.5641 8.42317 13.5736 8.47117 13.5736C8.51916 13.5736 8.56668 13.5641 8.61099 13.5457C8.6553 13.5273 8.69553 13.5003 8.72937 13.4662C8.7634 13.4324 8.79041 13.3922 8.80884 13.3479C8.82726 13.3036 8.83675 13.256 8.83675 13.208C8.83675 13.16 8.82726 13.1125 8.80884 13.0682C8.79041 13.0239 8.7634 12.9837 8.72937 12.9498L5.29323 9.51287L4.3233 8.54377C4.16876 8.38892 4.08197 8.17909 4.08197 7.96032C4.08197 7.74155 4.16876 7.53171 4.3233 7.37687C4.4802 7.22625 4.68926 7.14214 4.90675 7.14214C5.12424 7.14214 5.33331 7.22625 5.4902 7.37687L6.46013 8.34514L9.8971 11.7813C9.93077 11.8156 9.97094 11.8429 10.0153 11.8615C10.0596 11.8801 10.1072 11.8897 10.1553 11.8897C10.2034 11.8897 10.251 11.8801 10.2953 11.8615C10.3397 11.8429 10.3798 11.8156 10.4135 11.7813C10.4818 11.7127 10.5202 11.6199 10.5202 11.5231C10.5202 11.4263 10.4818 11.3334 10.4135 11.2649L6.97655 7.82956C6.89975 7.75312 6.83891 7.66217 6.79756 7.56201C6.75622 7.46185 6.7352 7.35447 6.73572 7.24611C6.73507 7.13769 6.75595 7.03021 6.79715 6.92991C6.83835 6.82962 6.89904 6.7385 6.97572 6.66183C7.13084 6.50719 7.34095 6.42035 7.55999 6.42035C7.77903 6.42035 7.98914 6.50719 8.14427 6.66183L13.9308 12.4491C13.9922 12.5076 14.0721 12.5429 14.1567 12.549C14.2413 12.5552 14.3254 12.5318 14.3947 12.4829C14.464 12.434 14.5142 12.3626 14.5367 12.2809C14.5593 12.1991 14.5528 12.112 14.5183 12.0345L13.4011 9.67094C13.1404 9.11149 13.2066 8.69025 13.6047 8.38239C13.6817 8.32396 13.77 8.28204 13.864 8.25926C13.958 8.23648 14.0556 8.23331 14.1509 8.24997C14.4339 8.29632 14.6963 8.4817 14.8783 8.75149L17.0714 12.6114C18.3732 14.9915 17.9545 17.2003 15.7936 19.3611C14.6383 20.5173 13.1917 20.9882 11.6036 20.7283C10.1859 20.4916 8.73765 19.6955 7.52524 18.4822H7.52441ZM10.7503 5.9708L12.8706 8.09108C12.4593 8.59342 12.4047 9.26128 12.7423 9.98128L12.9616 10.4464L9.43861 6.92335C9.37757 6.81002 9.34438 6.68378 9.34179 6.55508C9.34179 6.33411 9.42786 6.12721 9.58344 5.9708C9.74082 5.82112 9.9497 5.73766 10.1669 5.73766C10.3841 5.73766 10.593 5.82112 10.7503 5.9708ZM18.1051 7.67563C17.7948 7.21466 17.3586 6.91756 16.8753 6.83894C16.6812 6.80632 16.4825 6.81388 16.2915 6.86114C16.1005 6.9084 15.9212 6.99436 15.7647 7.1137C15.4535 7.3537 15.2599 7.65659 15.1754 7.99508C14.9266 7.75301 14.611 7.59102 14.2692 7.52997C13.9911 7.4859 13.7061 7.52267 13.4483 7.6359L11.2668 5.45439C10.9747 5.16339 10.5792 5.00001 10.1669 5.00001C9.7546 5.00001 9.35911 5.16339 9.06703 5.45439C8.87539 5.64887 8.73887 5.89078 8.67144 6.15535C8.5271 6.00929 8.35536 5.89315 8.16606 5.81358C7.97675 5.73401 7.77361 5.69257 7.56826 5.69165C7.36292 5.69073 7.15941 5.73034 6.9694 5.8082C6.77938 5.88607 6.60661 6.00066 6.46096 6.14542C6.25382 6.35175 6.10947 6.6126 6.04468 6.8977C5.42068 6.2737 4.39613 6.2737 3.80772 6.86128C3.51632 7.15315 3.35266 7.54872 3.35266 7.96114C3.35266 8.37357 3.51632 8.76914 3.80772 9.06101C3.56937 9.16032 3.30703 9.29935 3.09268 9.5137C2.80164 9.80592 2.63823 10.2015 2.63823 10.614C2.63823 11.0264 2.80164 11.422 3.09268 11.7142L3.6091 12.229C3.33829 12.291 3.08902 12.4243 2.88721 12.6152C2.6854 12.8061 2.53842 13.0476 2.46154 13.3146C2.38467 13.5815 2.38071 13.8642 2.45008 14.1332C2.51945 14.4022 2.65961 14.6477 2.85599 14.8442L7.00965 18.9987C8.32965 20.3178 9.91861 21.1876 11.4852 21.4475C11.806 21.5011 12.1307 21.5282 12.456 21.5286C13.3051 21.5286 14.1087 21.33 14.8494 20.9493C15.0803 20.9824 15.3087 21.0031 15.5346 21.0031C16.8008 21.0031 17.9917 20.4834 19.0403 19.4356C21.8028 16.6731 21.5917 13.7021 20.4786 11.85L18.1051 7.67645V7.67563Z"></path></svg></div></div></div></div></a></span></div><div class="pw-multi-vote-count e nu nv nw nx ny nz oa"><p class="z b y u w"><span class="ob">--</span></p></div></div></div><div class="oc dy e"><div><div class="bt"><div tabindex="-1" class="cq"><button class="af nn go oe am j dn np of" aria-label="responses"><svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="lb"><path d="M18.0064 16.8029C19.5393 15.347 20.24 13.4782 20.24 11.4818C20.24 7.35659 16.7088 4 12.1914 4C7.67395 4 4 7.35659 4 11.4818C4 15.6077 7.67395 18.9643 12.1914 18.9643C13.0081 18.9643 13.8134 18.8527 14.5839 18.6374C14.815 18.8368 15.064 19.0281 15.3284 19.1956C16.3876 19.8892 17.5312 20.24 18.7266 20.24C18.9505 20.232 19.1273 20.1284 19.2132 19.953C19.2554 19.8711 19.2738 19.7795 19.2664 19.688C19.2589 19.5966 19.2259 19.5089 19.1711 19.4347C18.6763 18.765 18.326 18.0714 18.1313 17.3777C18.0754 17.1816 18.0337 16.9817 18.0064 16.7798V16.8029ZM14.884 17.8585L14.8167 17.6353L14.502 17.7309C13.7529 17.9559 12.9738 18.0698 12.1906 18.069C8.16787 18.069 4.89943 15.1142 4.89943 11.4818C4.89943 7.84932 8.16787 4.89376 12.1906 4.89376C16.2051 4.89376 19.3033 7.85171 19.3033 11.4874C19.3033 13.2813 18.695 14.9556 17.2757 16.2073L17.081 16.3747V16.6299C17.081 16.6857 17.0811 16.7814 17.0973 16.9249C17.1216 17.1561 17.1784 17.4032 17.2514 17.6584C17.4055 18.2165 17.6488 18.7746 17.9732 19.3167C17.2189 19.2051 16.489 18.9261 15.8077 18.4716C15.532 18.2962 15.094 18.0889 14.8669 17.8816L14.884 17.8585Z"></path></svg><p class="z b y u w"><span class="pw-responses-count od lb">1</span></p></button></div></div></div></div><div class="am j w"><div><div class="bt"><div tabindex="-1" class="cq"><span data-dd-action-name="Susi presentation tracker repost_header"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Frepost%2Fp%2Fb0e7dab4d793&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fmixpaneleng%2Fautomate-rotating-credentials-using-terraform-b0e7dab4d793&user=Andy+Leap&userId=4f202918f2e7&source=---header_actions--b0e7dab4d793---------------------repost_header--------------------" data-discover="true"><span class="nn dz bx af go nr am j ns nt nm ac og oh" aria-disabled="false" aria-label="Repost"><div class="dg df e dm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M3 8.72727L5.64706 6M5.64706 6L8.29412 8.72727M5.64706 6V14.1818V15.2475C5.64706 15.9633 5.92589 16.6509 6.42442 17.1646C6.94277 17.6986 7.6553 18 8.39955 18H12" stroke="currentColor" stroke-linecap="round"></path><path d="M21 15.2727L18.3529 18M18.3529 18L15.7059 15.2727M18.3529 18V9.81818V8.75249C18.3529 8.03671 18.0741 7.34908 17.5756 6.83545C17.0572 6.30139 16.3447 6 15.6004 6L12 6" stroke="currentColor" stroke-linecap="round"></path></svg></div></span></a></span></div></div></div><div class="od e"></div></div></div></div><div class="am j mr ms mt mu mv mw mx my mz na nb nc nd ne nf"><div class="gs cz da r s"></div><div class="ck cz"><div><div class="bt"><div tabindex="-1" class="cq"><span data-dd-action-name="Susi presentation tracker bookmark_footer"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" data-testid="headerBookmarkButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2Fb0e7dab4d793&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fmixpaneleng%2Fautomate-rotating-credentials-using-terraform-b0e7dab4d793&source=---header_actions--b0e7dab4d793---------------------bookmark_footer--------------------" data-discover="true"><span class=""><svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg" class="w oi" aria-label="Add to list bookmark button"><path d="M18 2.5C18 2.22386 18.2239 2 18.5 2C18.7762 2 19 2.22386 19 2.5V5H21.5C21.7761 5 22 5.22386 22 5.5C22 5.77614 21.7761 6 21.5 6H19V8.5C19 8.77614 18.7762 9 18.5 9C18.2239 9 18 8.77614 18 8.5V6H15.5C15.2239 6 15 5.77614 15 5.5C15 5.22386 15.2239 5 15.5 5H18V2.5Z" fill="currentColor"></path><path d="M7 7C7 6.44772 7.44772 6 8 6H11.5C11.7761 6 12 5.77614 12 5.5C12 5.22386 11.7761 5 11.5 5H8C6.89543 5 6 5.89543 6 7V21C6 21.1905 6.10823 21.3644 6.27912 21.4486C6.45002 21.5327 6.65387 21.5125 6.80486 21.3963L12.5 17L18.1951 21.3963C18.3461 21.5125 18.55 21.5327 18.7209 21.4486C18.8918 21.3644 19 21.1905 19 21V12.5C19 12.2239 18.7761 12 18.5 12C18.2239 12 18 12.2239 18 12.5V19.9846L12.8049 15.9729C12.6251 15.8346 12.3749 15.8346 12.1951 15.9729L7 19.9846V7Z" fill="currentColor"></path></svg></span></a></span></div></div></div></div><div class="bs jp il"><div class="e ce"><div class="am ev"><div class="oj ok ol om on er fc cs"><div class="am"><span data-dd-action-name="Susi presentation tracker post_audio_button"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2Fplans%3Fdimension%3Dpost_audio_button%26postId%3Db0e7dab4d793&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fmixpaneleng%2Fautomate-rotating-credentials-using-terraform-b0e7dab4d793&source=---header_actions--b0e7dab4d793---------------------post_audio_button--------------------" data-discover="true"><div><div class="bt"><div tabindex="-1" class="cq"><button aria-label="Listen" data-testid="audioPlayButton" class="bx dn by bz ca ab cb oo ae af ag bm op oq or os ot ou ov ow l ox oy oz pa pb pc pd n pe pf pg"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12ZM12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2ZM15.376 12.416L10.7773 15.4818C10.4451 15.7033 10 15.4651 10 15.0657V8.93426C10 8.53491 10.4451 8.29672 10.7774 8.51823L15.376 11.584C15.6728 11.7819 15.6728 12.2181 15.376 12.416Z" fill="currentColor"></path></svg><div class="da r s"><p class="z b cr u w">Listen</p></div></button></div></div></div></a></span></div></div></div></div></div><div class="bt" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu" aria-haspopup="dialog"><div><div class="bt"><div tabindex="-1" class="cq"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="headerSocialShareButton" class="bx dn by bz ca ab cb oo ae af ag bm op oq or os ot ou ov ow l ox oy oz pa pb pc pd n pe pf pg"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.2176 4.93118C15.1883 4.98289 15.1484 5.0278 15.1004 5.06293L15.1118 5.06859C15.024 5.12481 14.9269 5.15261 14.8204 5.14293C14.7004 5.13293 14.6004 5.08293 14.5204 5.01293L12.5004 2.99293V10.0629C12.5004 10.3429 12.2704 10.5629 12.0004 10.5629C11.7304 10.5629 11.5004 10.3429 11.5004 10.0629V3.02293L9.50042 5.02293C9.42474 5.09456 9.32654 5.13771 9.22259 5.14501C9.11863 5.1523 9.01537 5.12329 8.93042 5.06293H8.91042C8.82042 4.99293 8.75042 4.88293 8.75042 4.76293C8.74294 4.70553 8.74801 4.64719 8.76528 4.59195C8.78254 4.5367 8.81159 4.48586 8.85042 4.44293L11.6504 1.64293C11.7439 1.55132 11.8695 1.5 12.0004 1.5C12.1313 1.5 12.257 1.55132 12.3504 1.64293L15.1504 4.43293C15.1931 4.47602 15.2258 4.52782 15.2466 4.58479C15.2673 4.64175 15.2754 4.70252 15.2704 4.76293C15.2649 4.82212 15.2469 4.87946 15.2176 4.93118ZM15.1118 5.06859L15.1204 5.07293V5.06293C15.1175 5.06485 15.1147 5.06674 15.1118 5.06859ZM16 7.06293H17.5C18.0304 7.06293 18.5391 7.27364 18.9142 7.64871C19.2893 8.02379 19.5 8.53249 19.5 9.06293V19.0629C19.5 19.5934 19.2893 20.1021 18.9142 20.4771C18.5391 20.8522 18.0304 21.0629 17.5 21.0629H6.5C5.4 21.0629 4.5 20.1629 4.5 19.0629V9.06293C4.5 8.53249 4.71071 8.02379 5.08579 7.64871C5.46086 7.27364 5.96957 7.06293 6.5 7.06293H8C8.13188 7.06481 8.25769 7.11872 8.35 7.21293C8.44421 7.30524 8.49812 7.43104 8.5 7.56293C8.49812 7.69481 8.44421 7.82061 8.35 7.91293C8.25769 8.00713 8.13188 8.06105 8 8.06293H6.4C5.9 8.06293 5.5 8.46293 5.5 8.96293V19.1629C5.5 19.4016 5.59482 19.6305 5.7636 19.7993C5.93239 19.9681 6.16131 20.0629 6.4 20.0629H17.6C18.1 20.0629 18.5 19.6629 18.5 19.1629V8.96293C18.5 8.46293 18.1 8.06293 17.6 8.06293H16C15.8674 8.06293 15.7402 8.01025 15.6464 7.91648C15.5527 7.82271 15.5 7.69554 15.5 7.56293C15.5 7.43032 15.5527 7.30314 15.6464 7.20937C15.7402 7.11561 15.8674 7.06293 16 7.06293Z" fill="currentColor"></path></svg><div class="da r s"><p class="z b cr u w">Share</p></div></button></div></div></div></div></div></div></div></div></div></div><p id="e636" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">At Mixpanel, keeping your data secure is of the utmost importance. We strictly adhere to security best practices, including rotating credentials often. Anyone who has to rotate credentials periodically knows that, without automation, it can be a super time consuming task. This article will discuss our novel approach to automating credential rotations using terraform.</p><h2 id="52fc" class="qc qd kf z qe qf qg qh fk qi qj qk fm ql qm qn qo qp qq qr qs qt qu qv qw qx cv">Rotation == Toil</h2><p id="eef1" class="pw-post-body-paragraph ph pi kf pj b pk qy pm pn po qz pq pr fn ra pt pu fq rb pw px ft rc pz qa qb it cv">Without any automation in place, rotating credentials is pure toil. You have to have an engineer go in and create a new credential and then update everything that uses it regularly. If the credentials don’t expire, you don’t have a strong incentive to be diligent. If they do expire, you are deliberately scheduling a future outage. Obviously, both of these options are bad. As an engineer on the DevInfra team at Mixpanel, one of my main enemies is toil. So any kind of “oh, we should manually update a dozen or more secrets with new credentials every month” is just antithetical to my very role.</p><p id="a420" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">So let’s start working on how we can automate this process.</p><h2 id="bfb9" class="qc qd kf z qe qf qg qh fk qi qj qk fm ql qm qn qo qp qq qr qs qt qu qv qw qx cv">Terraform</h2><p id="596c" class="pw-post-body-paragraph ph pi kf pj b pk qy pm pn po qz pq pr fn ra pt pu fq rb pw px ft rc pz qa qb it cv">Terraform is the bog standard way of automating anything involving cloud platforms, so it seems like an obvious choice for this stuff. Let’s ensure that, though, so we’ll start by setting up an example for testing. We run on GCP, so GCP service accounts are commonly used for giving services access to various GCP resources, as well as for allowing external services to reach into our GCP stuff on our behalf.</p><p id="5401" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">We’ll create a simple service account:</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="16e1" class="rm qd kf rj b cr rn ro e rp rq">resource "google_service_account" "rotation-test" {<br/> account_id = "rotation-test"<br/> display_name = "Rotation Test Account"<br/>}</span></pre><p id="9c11" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">and create a service account key for that account</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="5eed" class="rm qd kf rj b cr rn ro e rp rq">resource "google_service_account_key" "rotation-test" {<br/> service_account_id = google_service_account.rotation-test.id<br/>}</span></pre><p id="5b9f" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">Run <code class="ei rr rs rt rj b">terraform plan</code> on this, and you get:</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="5198" class="rm qd kf rj b cr rn ro e rp rq"># google_service_account.rotation-test will be created<br/>+ resource "google_service_account" "rotation-test" {<br/>+ account_id = "rotation-test"<br/>+ disabled = false<br/>+ display_name = "Rotation Test Account"<br/>+ email = (known after apply)<br/>+ id = (known after apply)<br/>+ member = (known after apply)<br/>+ name = (known after apply)<br/>+ project = "mixpanel-tools"<br/>+ unique_id = (known after apply)<br/> }<br/># google_service_account_key.rotation-test will be created<br/>+ resource "google_service_account_key" "rotation-test" {<br/>+ id = (known after apply)<br/>+ key_algorithm = "KEY_ALG_RSA_2048"<br/>+ name = (known after apply)<br/>+ private_key = (sensitive value)<br/>+ private_key_type = "TYPE_GOOGLE_CREDENTIALS_FILE"<br/>+ public_key = (known after apply)<br/>+ public_key_type = "TYPE_X509_PEM_FILE"<br/>+ service_account_id = (known after apply)<br/>+ valid_after = (known after apply)<br/>+ valid_before = (known after apply)<br/> }<br/>Plan: 2 to add, 0 to change, 0 to destroy.</span></pre><p id="3dfb" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">So we can apply this and export that private_key field to somewhere and we’ve got our service account. We’ll go ahead and throw that in now:</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="7aec" class="rm qd kf rj b cr rn ro e rp rq">resource "google_secret_manager_secret" "rotation-test" {<br/> secret_id = "rotation-test-key"<br/> replication {<br/> auto {}<br/> }<br/>}<br/>resource "google_secret_manager_secret_version" "rotation-test" {<br/> secret = google_secret_manager_secret.rotation-test.id<br/> secret_data = google_service_account_key.rotation-test.private_key<br/>}</span></pre><p id="23f9" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">And after planning and applying, we have a service account with a key, with the credentials loaded into GCP secrets manager. But this key is static, and we need to rotate it. Simple thing first, we can just taint the service account key in terraform</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="1a57" class="rm qd kf rj b cr rn ro e rp rq">terraform taint google_service_account_key.rotation-test</span></pre><p id="15cf" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">Plan that and apply it:</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="48ec" class="rm qd kf rj b cr rn ro e rp rq">google_service_account_key.rotation-test: Destroying... [id=projects/mixpanel-tools/serviceAccounts/rotation-test@mixpanel-tools.iam.gserviceaccount.com/keys/e7e71f25bfa52b39bef5273387e1f1be5b218b02]<br/>google_secret_manager_secret.rotation-test: Creating...<br/>google_service_account_key.rotation-test: Destruction complete after 0s<br/>google_service_account_key.rotation-test: Creating...<br/>google_secret_manager_secret.rotation-test: Creation complete after 0s [id=projects/mixpanel-tools/secrets/rotation-test-key]<br/>google_service_account_key.rotation-test: Creation complete after 0s [id=projects/mixpanel-tools/serviceAccounts/rotation-test@mixpanel-tools.iam.gserviceaccount.com/keys/3dd8bd10e9a34ca4b0b115caef84311f5151ba31]<br/>google_secret_manager_secret_version.rotation-test: Creating...<br/>google_secret_manager_secret_version.rotation-test: Creation complete after 1s [id=projects/839233470602/secrets/rotation-test-key/versions/1]</span></pre><p id="1282" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">and we’ve got a new key. But this is manual effort, so how can we automate this? Well, Terraform has a bunch of providers, including some that aren’t actually managing any kind of external resources, like the Time provider, which has a <code class="ei rr rs rt rj b">time_rotating</code> resource. Reading the description, it seems ideal, so let’s try it out (with a very fast rotation, so I don’t spend weeks/months writing this post)</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="15b3" class="rm qd kf rj b cr rn ro e rp rq">resource "time_rotating" "rotation-test" {<br/> rotation_minutes = 5<br/>}<br/>resource "google_service_account_key" "rotation-test" {<br/> service_account_id = google_service_account.rotation-test.id<br/> keepers = {<br/> rotation = time_rotating.rotation-test.id<br/> }<br/>}</span></pre><p id="ebd6" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">Applying this will immediately trigger the creation of a new service account key and update the secret with the new value</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="50af" class="rm qd kf rj b cr rn ro e rp rq">google_secret_manager_secret_version.rotation-test: Destroying... [id=projects/839233470602/secrets/rotation-test-key/versions/1]<br/>google_secret_manager_secret_version.rotation-test: Destruction complete after 0s<br/>google_service_account_key.rotation-test: Destroying... [id=projects/mixpanel-tools/serviceAccounts/rotation-test@mixpanel-tools.iam.gserviceaccount.com/keys/3dd8bd10e9a34ca4b0b115caef84311f5151ba31]<br/>google_service_account_key.rotation-test: Destruction complete after 0s<br/>time_rotating.rotation-test: Creating...<br/>time_rotating.rotation-test: Creation complete after 0s [id=2024-07-24T20:12:33Z]<br/>google_service_account_key.rotation-test: Creating...<br/>google_service_account_key.rotation-test: Creation complete after 1s [id=projects/mixpanel-tools/serviceAccounts/rotation-test@mixpanel-tools.iam.gserviceaccount.com/keys/03f5bc6e8d62bc30b4739c6016374d0608053bc4]<br/>google_secret_manager_secret_version.rotation-test: Creating...<br/>google_secret_manager_secret_version.rotation-test: Creation complete after 0s [id=projects/839233470602/secrets/rotation-test-key/versions/2]</span></pre><p id="a24b" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">And then, after a little over 5 minutes we plan and apply again</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="e791" class="rm qd kf rj b cr rn ro e rp rq">google_secret_manager_secret_version.rotation-test: Destroying... [id=projects/839233470602/secrets/rotation-test-key/versions/2]<br/>google_secret_manager_secret_version.rotation-test: Destruction complete after 0s<br/>google_service_account_key.rotation-test: Destroying... [id=projects/mixpanel-tools/serviceAccounts/rotation-test@mixpanel-tools.iam.gserviceaccount.com/keys/03f5bc6e8d62bc30b4739c6016374d0608053bc4]<br/>google_service_account_key.rotation-test: Destruction complete after 0s<br/>time_rotating.rotation-test: Creating...<br/>time_rotating.rotation-test: Creation complete after 0s [id=2024-07-24T20:18:29Z]<br/>google_service_account_key.rotation-test: Creating...<br/>google_service_account_key.rotation-test: Creation complete after 1s [id=projects/mixpanel-tools/serviceAccounts/rotation-test@mixpanel-tools.iam.gserviceaccount.com/keys/5d7dee0097010a88a1792f3fb79423ea6a0f0f77]<br/>google_secret_manager_secret_version.rotation-test: Creating...<br/>google_secret_manager_secret_version.rotation-test: Creation complete after 0s [id=projects/839233470602/secrets/rotation-test-key/versions/3]</span></pre><p id="3b38" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">Success! Terraform is rotating our service account key automatically for us!</p><h2 id="fae4" class="qc qd kf z qe qf qg qh fk qi qj qk fm ql qm qn qo qp qq qr qs qt qu qv qw qx cv">Invalidation</h2><p id="dfb5" class="pw-post-body-paragraph ph pi kf pj b pk qy pm pn po qz pq pr fn ra pt pu fq rb pw px ft rc pz qa qb it cv">Unfortunately, now we run into a rather thorny issue, invalidation. Terraform immediately destroys the old service account key and creates a new one, which means that anything using that secret loses access to our project until it gets the updated credentials. If you are using Kubernetes, pods can take up to a minute to update secrets. <a class="bx ir" href="https://external-secrets.io/" rel="noopener ugc nofollow" target="_blank">External Secrets Operator</a> (which we use) can add up to an hour on top of that. Furthermore, some services might only load the secret on startup. This all boils down to our initial path causing outages every time it rotates the credential.</p><p id="daaf" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">The common fix here is to have 2 (or more) credentials, rotating them in an offset pattern, and using whichever is the newest at all times. That way, when you update, you are invalidating the older key, which is (hopefully) not in use anymore, and creating a new key, which is now passed out to all the services.</p><p id="1efe" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">Let’s implement this:</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="3ff5" class="rm qd kf rj b cr rn ro e rp rq">resource "time_rotating" "rotation-test" {<br/> count = 2<br/> rotation_minutes = 5<br/>}<br/>resource "google_service_account_key" "rotation-test" {<br/> count = 2<br/> service_account_id = google_service_account.rotation-test.id<br/> keepers = {<br/> rotation = time_rotating.rotation-test[count.index].id<br/> }<br/>}<br/>locals {<br/> older = timecmp(time_rotating.rotation-test[0].id, time_rotating.rotation-test[1].id) > 0 ? 1 : 0<br/>}<br/>resource "google_secret_manager_secret_version" "rotation-test" {<br/> secret = google_secret_manager_secret.rotation-test.id<br/> secret_data = google_service_account_key.rotation-test[local.older].private_key<br/>}</span></pre><p id="28bd" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">This technically works, though it’s… not fun to set up, as initially on applying, the keys will rotate simultaneously, so you don’t get any benefit. You can do a custom import on the rotating_time objects to get them offset, or just wait half the period and <code class="ei rr rs rt rj b">terraform state rm time_rotating.rotation-test[1]</code> to force it to rotate early and thus offset them, but there’s a deeper issue here. The <code class="ei rr rs rt rj b">time_rotating</code> resource doesn’t rotate on a fixed schedule, i.e. 1:00:00PM then 1:05:00PM then 1:10:00PM, but instead considers the planning time as the start of a new rotation period. If the first one was at 1:00:00PM, but you don’t plan/apply again til 1:05:30PM, the next expiration will be 1:10:30PM, not 1:10:00PM. This can compound over time, til you potentially wind up with both keys rotating at the same time again, which then becomes an outage, and a particularly nasty one as you’ve probably got something doing those apply operations automatically (which we do, I’ll circle back to that later)</p><p id="d51e" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">How do we fix this? I did a bunch of research, and… couldn’t find any answers. Plenty of threads about other people running into the same issues, but no solutions in sight. So I did what any sane engineer would do…</p><h2 id="3cad" class="qc qd kf z qe qf qg qh fk qi qj qk fm ql qm qn qo qp qq qr qs qt qu qv qw qx cv">We wrote a Terraform provider: multirotate_set</h2><p id="6c5a" class="pw-post-body-paragraph ph pi kf pj b pk qy pm pn po qz pq pr fn ra pt pu fq rb pw px ft rc pz qa qb it cv">We released a Terraform provider to plug all the aforementioned gaps once and for all:<code class="ei rr rs rt rj b"><a class="bx ir" href="https://registry.terraform.io/providers/mixpanel/multirotate/latest/docs/resources/set" rel="noopener ugc nofollow" target="_blank">multirotate_set</a></code>.</p><p id="25df" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">Let’s put our new <code class="ei rr rs rt rj b">multirotate_set</code> resource into play:</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="c295" class="rm qd kf rj b cr rn ro e rp rq">resource "multirotate_set" "rotation-test" {<br/> rotation_period = "5m"<br/> number = 2<br/>}<br/>resource "google_service_account_key" "rotation-test" {<br/> count = 2<br/> service_account_id = google_service_account.rotation-test.id<br/> keepers = {<br/> rotation = multirotate_set.rotation-test.rotation_set[count.index].expiration<br/> }<br/>}<br/>resource "google_secret_manager_secret_version" "rotation-test" {<br/> secret = google_secret_manager_secret.rotation-test.id<br/> secret_data = google_service_account_key.rotation-test[multirotate_set.rotation-test.current_rotation].private_key<br/>}</span></pre><p id="7fdc" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">A bit simpler than the <code class="ei rr rs rt rj b">time_rotating</code> shenanigans. And after 5 minutes, we get:</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="f40a" class="rm qd kf rj b cr rn ro e rp rq"># multirotate_set.rotation-test will be updated in-place<br/> resource "multirotate_set" "rotation-test" {<br/>! current_rotation = 1 -> 0<br/>! last_rotate = "2024-07-24T20:52:25Z" -> "2024-07-24T20:57:25Z"<br/> rotation_set = [<br/> {<br/>! creation = "2024-07-24T20:47:25Z" -> "2024-07-24T20:52:42Z"<br/>! expiration = "2024-07-24T20:52:25Z" -> "2024-07-24T21:02:25Z"<br/> # (1 unchanged attribute hidden)<br/> },<br/> # (1 unchanged element hidden)<br/> ]<br/> # (3 unchanged attributes hidden)<br/> }</span></pre><p id="5ba8" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">along with the service account key being recreated, and the secret value updating. Success! Again!</p><h2 id="bb9a" class="qc qd kf z qe qf qg qh fk qi qj qk fm ql qm qn qo qp qq qr qs qt qu qv qw qx cv">Enhancement: Expiration</h2><p id="006b" class="pw-post-body-paragraph ph pi kf pj b pk qy pm pn po qz pq pr fn ra pt pu fq rb pw px ft rc pz qa qb it cv">One thing that’s missing, in my eyes, is key expiration. This is more of an optional thing, but it does look better on audits and is more of a forcing function to make sure you are rotating keys. This is starting to get into the specifics of GCP + Terraform, but let’s carry on and get it done.</p><p id="7f2a" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">First up: GCP won’t create an expiring service account key for you, so you’re stuck doing things manually, but that’s what Terraform is for. Start with a private key.</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="43a6" class="rm qd kf rj b cr rn ro e rp rq">resource "tls_private_key" "rotation-test" {<br/> count = 2<br/> algorithm = "RSA"<br/> rsa_bits = 2048<br/> lifecycle {<br/> replace_triggered_by = [multirotate_set.rotation-test.rotation_set[count.index]]<br/> }<br/>}</span></pre><p id="2a71" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">The private key triggers the rotation, as we want a brand new key each time. Next up, generate a self-signed cert.</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="7446" class="rm qd kf rj b cr rn ro e rp rq">resource "tls_self_signed_cert" "rotation-test" {<br/> count = 2<br/> private_key_pem = tls_private_key.rotation-test[count.index].private_key_pem<br/> subject {<br/> common_name = "unused"<br/> }<br/> validity_period_hours = 1<br/> allowed_uses = [<br/> "key_encipherment",<br/> ]<br/>}</span></pre><p id="85db" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">Note that you want the validity period to be longer than the rotation period, so the key stays valid. Next up, pass that off to Google.</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="c49f" class="rm qd kf rj b cr rn ro e rp rq">resource "google_service_account_key" "rotation-test" {<br/> count = 2<br/> service_account_id = google_service_account.rotation-test.id<br/> public_key_data = base64encode(tls_self_signed_cert.rotation-test[count.index].cert_pem)<br/>}</span></pre><p id="c976" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">And the final step, where it gets a little more complex as Google isn’t doing it for you: Build a credentials file to use, and stick it somewhere. (GCP secrets manager in this case)</p><pre class="rd re rf rg rh ri rj rk jf rl cn cv"><span id="9ff6" class="rm qd kf rj b cr rn ro e rp rq">resource "google_secret_manager_secret_version" "rotation-test" {<br/> secret = google_secret_manager_secret.rotation-test.id<br/> secret_data = jsonencode({<br/> type : "service_account",<br/> project_id : resource.google_service_account.rotation-test.project,<br/> "private_key_id" : resource.tls_private_key.rotation-test[multirotate_set.rotation-test.current_rotation].id,<br/> "private_key" : resource.tls_private_key.rotation-test[multirotate_set.rotation-test.current_rotation].private_key_pem,<br/> "client_email" : resource.google_service_account.rotation-test.email,<br/> "client_id" : resource.google_service_account.rotation-test.unique_id,<br/> "auth_uri" : "<https://accounts.google.com/o/oauth2/auth>",<br/> "token_uri" : "<https://oauth2.googleapis.com/token>",<br/> "auth_provider_x509_cert_url" : "<https://www.googleapis.com/oauth2/v1/certs>",<br/> "client_x509_cert_url" : "<https://www.googleapis.com/robot/v1/metadata/x509/${resource.google_service_account.rotation-test.email}>"<br/> })<br/>}</span></pre><p id="39f4" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">And there you go! Rotating, expiring credentials without outages. As long as you keep on top of applying the terraform regularly of course.</p><h2 id="e145" class="qc qd kf z qe qf qg qh fk qi qj qk fm ql qm qn qo qp qq qr qs qt qu qv qw qx cv">Automation</h2><p id="f9c9" class="pw-post-body-paragraph ph pi kf pj b pk qy pm pn po qz pq pr fn ra pt pu fq rb pw px ft rc pz qa qb it cv">It is trivial to set up a GitHub Action or some other kind of cron job to automate running terraform apply on a regular schedule. You could definitely stop there and you can consider your problem solved. However, definitely wanted to call out a SaaS tool we use that makes this automation super trival: <a class="bx ir" href="https://terrateam.io/" rel="noopener ugc nofollow" target="_blank">Terrateam</a>. With Terrateam, all we had to do to start rotating our credentials automatically was flip on <a class="bx ir" href="https://terrateam.io/features/drift" rel="noopener ugc nofollow" target="_blank">drift detection and auto reconciliation</a>, and bing bang boom, our credentials get automatically rotated regularly. No more toil.</p><p id="bc40" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">Before tackling this credential rotation automation problem, we had already deployed <a class="bx ir" href="https://terrateam.io/" rel="noopener ugc nofollow" target="_blank">Terrateam</a> to help us scale our Terraform usage to meet the needs of 70+ engineers working in a monorepo. By enabling a gitops style Terraform workflow, we’ve completely sidestepped all the issues that come with multiple devs stepping on each other’s toes trying to make changes to terraform configurations at the same time. Terrateam has been great a great partner in deploying Terraform at scale, I’m always happy to recommend them whenever given the opportunity to do so!</p><p id="de1d" class="pw-post-body-paragraph ph pi kf pj b pk pl pm pn po pp pq pr fn ps pt pu fq pv pw px ft py pz qa qb it cv">If you enjoy eliminating toil like we did in this blog — Mixpanel engineering is <a class="bx ir" href="https://mixpanel.com/jobs/" rel="noopener ugc nofollow" target="_blank">hiring</a>!</p></div></div></div></div></section></div></div></article></div><div class="am ev"><div class="fc cs iz ja jb jc"><div class="ru rv am jo do"><div class="am"><div class="jp jq bp jr dd"><div class="js"><div class="am"><div class="am" aria-haspopup="dialog"><a class="bx x by cf ca ab cb rw ae af ag ah ai aj ak am j ju jv" rel="noopener follow" href="/tag/terraform?source=post_page---footer_tags--b0e7dab4d793-----------------------------------------" data-discover="true"><span class="z b cr u cv">Terraform</span></a></div></div></div><button aria-label="Follow Terraform" class="w dn by cf ca ab cb rx ae af ag bm am j jx jy jv jz dp"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M5.96219 1V6M5.96219 11V6M5.96219 6H11M5.96219 6H1" stroke="currentColor" stroke-linecap="round"></path></svg></button></div></div><div class="am"><div class="jp jq bp jr dd"><div class="js"><div class="am"><div class="am" aria-haspopup="dialog"><a class="bx x by cf ca ab cb rw ae af ag ah ai aj ak am j ju jv" rel="noopener follow" href="/tag/automation?source=post_page---footer_tags--b0e7dab4d793-----------------------------------------" data-discover="true"><span class="z b cr u cv">Automation</span></a></div></div></div><button aria-label="Follow Automation" class="w dn by cf ca ab cb rx ae af ag bm am j jx jy jv jz dp"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M5.96219 1V6M5.96219 11V6M5.96219 6H11M5.96219 6H1" stroke="currentColor" stroke-linecap="round"></path></svg></button></div></div><div class="am"><div class="jp jq bp jr dd"><div class="js"><div class="am"><div class="am" aria-haspopup="dialog"><a class="bx x by cf ca ab cb rw ae af ag ah ai aj ak am j ju jv" rel="noopener follow" href="/tag/credentials?source=post_page---footer_tags--b0e7dab4d793-----------------------------------------" data-discover="true"><span class="z b cr u cv">Credentials</span></a></div></div></div><button aria-label="Follow Credentials" class="w dn by cf ca ab cb rx ae af ag bm am j jx jy jv jz dp"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M5.96219 1V6M5.96219 11V6M5.96219 6H11M5.96219 6H1" stroke="currentColor" stroke-linecap="round"></path></svg></button></div></div><div class="am"><div class="jp jq bp jr dd"><div class="js"><div class="am"><div class="am" aria-haspopup="dialog"><a class="bx x by cf ca ab cb rw ae af ag ah ai aj ak am j ju jv" rel="noopener follow" href="/tag/security?source=post_page---footer_tags--b0e7dab4d793-----------------------------------------" data-discover="true"><span class="z b cr u cv">Security</span></a></div></div></div><button aria-label="Follow Security" class="w dn by cf ca ab cb rx ae af ag bm am j jx jy jv jz dp"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M5.96219 1V6M5.96219 11V6M5.96219 6H11M5.96219 6H1" stroke="currentColor" stroke-linecap="round"></path></svg></button></div></div></div></div></div><div class="e"></div><footer class="ry rz sa sb sc am j sd se"><div class="e ce"><div class="am ev"><div class="fc cs iz ja jb jc"><div class="am lc gg"><div class="am j nh"><div class="sf e"><span class="e sg sh si sj s"><div class="am j nh ni"><div class="pw-multi-vote-icon dm nj nk nl nm"><span data-dd-action-name="Susi presentation tracker clap_footer"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" data-testid="footerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fmixpaneleng%2Fb0e7dab4d793&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fmixpaneleng%2Fautomate-rotating-credentials-using-terraform-b0e7dab4d793&user=Andy+Leap&userId=4f202918f2e7&source=---footer_actions--b0e7dab4d793---------------------clap_footer--------------------" data-discover="true"><div><div class="bt"><div tabindex="-1" class="cq"><div class="nn af dn no np nq ac nr ns nt nm" role="presentation"><svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-label="clap"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.3702 0.827583L12 3.2822L12.6298 0.827583H11.3702Z"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M13.9159 3.95255L15.4386 1.84138L14.2552 1.45158L13.9159 3.95255Z"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M8.58869 1.84055L10.1114 3.95172L9.77379 1.45076L8.58869 1.84055Z"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M18.523 18.9192C17.6623 19.7799 16.7727 20.1664 15.9029 20.25C16.0419 20.1341 16.1776 20.01 16.3101 19.8776C18.6976 17.4891 19.1702 14.9269 17.7087 12.2547L16.7975 10.6516L16.0072 8.9799C15.7465 8.42046 15.8127 7.99921 16.2099 7.69218C16.2866 7.63312 16.3749 7.59082 16.469 7.56801C16.5631 7.5452 16.6609 7.54239 16.7561 7.55977C17.0392 7.60611 17.3023 7.79149 17.4836 8.06046L19.8472 12.2174C20.8229 13.8411 20.9884 16.4538 18.523 18.9192ZM7.52441 18.4822L3.36992 14.3278C3.25591 14.2118 3.1786 14.0648 3.14765 13.9051C3.1167 13.7454 3.13348 13.5802 3.19591 13.43C3.25833 13.2798 3.36363 13.1513 3.49864 13.0606C3.63365 12.9699 3.79239 12.921 3.95503 12.92C4.16606 12.92 4.37875 13.0011 4.54013 13.1617L6.69765 15.3192C6.76738 15.3812 6.85815 15.4142 6.9514 15.4114C7.04465 15.4087 7.13333 15.3704 7.1993 15.3044C7.26526 15.2385 7.30353 15.1498 7.30627 15.0566C7.30902 14.9633 7.27603 14.8725 7.21406 14.8028L5.05655 12.6445L3.60827 11.1962C3.4532 11.0414 3.36595 10.8314 3.36572 10.6124C3.36549 10.3933 3.45229 10.1831 3.60703 10.028C3.76177 9.87297 3.97177 9.78572 4.19084 9.78549C4.40991 9.78526 4.6201 9.87206 4.77517 10.0268L8.21296 13.4662C8.2468 13.5003 8.28703 13.5273 8.33134 13.5457C8.37566 13.5641 8.42317 13.5736 8.47117 13.5736C8.51916 13.5736 8.56668 13.5641 8.61099 13.5457C8.6553 13.5273 8.69553 13.5003 8.72937 13.4662C8.7634 13.4324 8.79041 13.3922 8.80884 13.3479C8.82726 13.3036 8.83675 13.256 8.83675 13.208C8.83675 13.16 8.82726 13.1125 8.80884 13.0682C8.79041 13.0239 8.7634 12.9837 8.72937 12.9498L5.29323 9.51287L4.3233 8.54377C4.16876 8.38892 4.08197 8.17909 4.08197 7.96032C4.08197 7.74155 4.16876 7.53171 4.3233 7.37687C4.4802 7.22625 4.68926 7.14214 4.90675 7.14214C5.12424 7.14214 5.33331 7.22625 5.4902 7.37687L6.46013 8.34514L9.8971 11.7813C9.93077 11.8156 9.97094 11.8429 10.0153 11.8615C10.0596 11.8801 10.1072 11.8897 10.1553 11.8897C10.2034 11.8897 10.251 11.8801 10.2953 11.8615C10.3397 11.8429 10.3798 11.8156 10.4135 11.7813C10.4818 11.7127 10.5202 11.6199 10.5202 11.5231C10.5202 11.4263 10.4818 11.3334 10.4135 11.2649L6.97655 7.82956C6.89975 7.75312 6.83891 7.66217 6.79756 7.56201C6.75622 7.46185 6.7352 7.35447 6.73572 7.24611C6.73507 7.13769 6.75595 7.03021 6.79715 6.92991C6.83835 6.82962 6.89904 6.7385 6.97572 6.66183C7.13084 6.50719 7.34095 6.42035 7.55999 6.42035C7.77903 6.42035 7.98914 6.50719 8.14427 6.66183L13.9308 12.4491C13.9922 12.5076 14.0721 12.5429 14.1567 12.549C14.2413 12.5552 14.3254 12.5318 14.3947 12.4829C14.464 12.434 14.5142 12.3626 14.5367 12.2809C14.5593 12.1991 14.5528 12.112 14.5183 12.0345L13.4011 9.67094C13.1404 9.11149 13.2066 8.69025 13.6047 8.38239C13.6817 8.32396 13.77 8.28204 13.864 8.25926C13.958 8.23648 14.0556 8.23331 14.1509 8.24997C14.4339 8.29632 14.6963 8.4817 14.8783 8.75149L17.0714 12.6114C18.3732 14.9915 17.9545 17.2003 15.7936 19.3611C14.6383 20.5173 13.1917 20.9882 11.6036 20.7283C10.1859 20.4916 8.73765 19.6955 7.52524 18.4822H7.52441ZM10.7503 5.9708L12.8706 8.09108C12.4593 8.59342 12.4047 9.26128 12.7423 9.98128L12.9616 10.4464L9.43861 6.92335C9.37757 6.81002 9.34438 6.68378 9.34179 6.55508C9.34179 6.33411 9.42786 6.12721 9.58344 5.9708C9.74082 5.82112 9.9497 5.73766 10.1669 5.73766C10.3841 5.73766 10.593 5.82112 10.7503 5.9708ZM18.1051 7.67563C17.7948 7.21466 17.3586 6.91756 16.8753 6.83894C16.6812 6.80632 16.4825 6.81388 16.2915 6.86114C16.1005 6.9084 15.9212 6.99436 15.7647 7.1137C15.4535 7.3537 15.2599 7.65659 15.1754 7.99508C14.9266 7.75301 14.611 7.59102 14.2692 7.52997C13.9911 7.4859 13.7061 7.52267 13.4483 7.6359L11.2668 5.45439C10.9747 5.16339 10.5792 5.00001 10.1669 5.00001C9.7546 5.00001 9.35911 5.16339 9.06703 5.45439C8.87539 5.64887 8.73887 5.89078 8.67144 6.15535C8.5271 6.00929 8.35536 5.89315 8.16606 5.81358C7.97675 5.73401 7.77361 5.69257 7.56826 5.69165C7.36292 5.69073 7.15941 5.73034 6.9694 5.8082C6.77938 5.88607 6.60661 6.00066 6.46096 6.14542C6.25382 6.35175 6.10947 6.6126 6.04468 6.8977C5.42068 6.2737 4.39613 6.2737 3.80772 6.86128C3.51632 7.15315 3.35266 7.54872 3.35266 7.96114C3.35266 8.37357 3.51632 8.76914 3.80772 9.06101C3.56937 9.16032 3.30703 9.29935 3.09268 9.5137C2.80164 9.80592 2.63823 10.2015 2.63823 10.614C2.63823 11.0264 2.80164 11.422 3.09268 11.7142L3.6091 12.229C3.33829 12.291 3.08902 12.4243 2.88721 12.6152C2.6854 12.8061 2.53842 13.0476 2.46154 13.3146C2.38467 13.5815 2.38071 13.8642 2.45008 14.1332C2.51945 14.4022 2.65961 14.6477 2.85599 14.8442L7.00965 18.9987C8.32965 20.3178 9.91861 21.1876 11.4852 21.4475C11.806 21.5011 12.1307 21.5282 12.456 21.5286C13.3051 21.5286 14.1087 21.33 14.8494 20.9493C15.0803 20.9824 15.3087 21.0031 15.5346 21.0031C16.8008 21.0031 17.9917 20.4834 19.0403 19.4356C21.8028 16.6731 21.5917 13.7021 20.4786 11.85L18.1051 7.67645V7.67563Z"></path></svg></div></div></div></div></a></span></div><div class="pw-multi-vote-count e nu nv nw nx ny nz oa"><p class="z b y u w"><span class="ob">--</span></p></div></div></span><span class="e ck sk ga sl sm"><div class="am j nh ni"><div class="pw-multi-vote-icon dm nj nk nl nm"><span data-dd-action-name="Susi presentation tracker clap_footer"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" data-testid="footerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fmixpaneleng%2Fb0e7dab4d793&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fmixpaneleng%2Fautomate-rotating-credentials-using-terraform-b0e7dab4d793&user=Andy+Leap&userId=4f202918f2e7&source=---footer_actions--b0e7dab4d793---------------------clap_footer--------------------" data-discover="true"><div><div class="bt"><div tabindex="-1" class="cq"><div class="nn af dn no np nq ac nr ns nt nm" role="presentation"><svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-label="clap"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.3702 0.827583L12 3.2822L12.6298 0.827583H11.3702Z"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M13.9159 3.95255L15.4386 1.84138L14.2552 1.45158L13.9159 3.95255Z"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M8.58869 1.84055L10.1114 3.95172L9.77379 1.45076L8.58869 1.84055Z"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M18.523 18.9192C17.6623 19.7799 16.7727 20.1664 15.9029 20.25C16.0419 20.1341 16.1776 20.01 16.3101 19.8776C18.6976 17.4891 19.1702 14.9269 17.7087 12.2547L16.7975 10.6516L16.0072 8.9799C15.7465 8.42046 15.8127 7.99921 16.2099 7.69218C16.2866 7.63312 16.3749 7.59082 16.469 7.56801C16.5631 7.5452 16.6609 7.54239 16.7561 7.55977C17.0392 7.60611 17.3023 7.79149 17.4836 8.06046L19.8472 12.2174C20.8229 13.8411 20.9884 16.4538 18.523 18.9192ZM7.52441 18.4822L3.36992 14.3278C3.25591 14.2118 3.1786 14.0648 3.14765 13.9051C3.1167 13.7454 3.13348 13.5802 3.19591 13.43C3.25833 13.2798 3.36363 13.1513 3.49864 13.0606C3.63365 12.9699 3.79239 12.921 3.95503 12.92C4.16606 12.92 4.37875 13.0011 4.54013 13.1617L6.69765 15.3192C6.76738 15.3812 6.85815 15.4142 6.9514 15.4114C7.04465 15.4087 7.13333 15.3704 7.1993 15.3044C7.26526 15.2385 7.30353 15.1498 7.30627 15.0566C7.30902 14.9633 7.27603 14.8725 7.21406 14.8028L5.05655 12.6445L3.60827 11.1962C3.4532 11.0414 3.36595 10.8314 3.36572 10.6124C3.36549 10.3933 3.45229 10.1831 3.60703 10.028C3.76177 9.87297 3.97177 9.78572 4.19084 9.78549C4.40991 9.78526 4.6201 9.87206 4.77517 10.0268L8.21296 13.4662C8.2468 13.5003 8.28703 13.5273 8.33134 13.5457C8.37566 13.5641 8.42317 13.5736 8.47117 13.5736C8.51916 13.5736 8.56668 13.5641 8.61099 13.5457C8.6553 13.5273 8.69553 13.5003 8.72937 13.4662C8.7634 13.4324 8.79041 13.3922 8.80884 13.3479C8.82726 13.3036 8.83675 13.256 8.83675 13.208C8.83675 13.16 8.82726 13.1125 8.80884 13.0682C8.79041 13.0239 8.7634 12.9837 8.72937 12.9498L5.29323 9.51287L4.3233 8.54377C4.16876 8.38892 4.08197 8.17909 4.08197 7.96032C4.08197 7.74155 4.16876 7.53171 4.3233 7.37687C4.4802 7.22625 4.68926 7.14214 4.90675 7.14214C5.12424 7.14214 5.33331 7.22625 5.4902 7.37687L6.46013 8.34514L9.8971 11.7813C9.93077 11.8156 9.97094 11.8429 10.0153 11.8615C10.0596 11.8801 10.1072 11.8897 10.1553 11.8897C10.2034 11.8897 10.251 11.8801 10.2953 11.8615C10.3397 11.8429 10.3798 11.8156 10.4135 11.7813C10.4818 11.7127 10.5202 11.6199 10.5202 11.5231C10.5202 11.4263 10.4818 11.3334 10.4135 11.2649L6.97655 7.82956C6.89975 7.75312 6.83891 7.66217 6.79756 7.56201C6.75622 7.46185 6.7352 7.35447 6.73572 7.24611C6.73507 7.13769 6.75595 7.03021 6.79715 6.92991C6.83835 6.82962 6.89904 6.7385 6.97572 6.66183C7.13084 6.50719 7.34095 6.42035 7.55999 6.42035C7.77903 6.42035 7.98914 6.50719 8.14427 6.66183L13.9308 12.4491C13.9922 12.5076 14.0721 12.5429 14.1567 12.549C14.2413 12.5552 14.3254 12.5318 14.3947 12.4829C14.464 12.434 14.5142 12.3626 14.5367 12.2809C14.5593 12.1991 14.5528 12.112 14.5183 12.0345L13.4011 9.67094C13.1404 9.11149 13.2066 8.69025 13.6047 8.38239C13.6817 8.32396 13.77 8.28204 13.864 8.25926C13.958 8.23648 14.0556 8.23331 14.1509 8.24997C14.4339 8.29632 14.6963 8.4817 14.8783 8.75149L17.0714 12.6114C18.3732 14.9915 17.9545 17.2003 15.7936 19.3611C14.6383 20.5173 13.1917 20.9882 11.6036 20.7283C10.1859 20.4916 8.73765 19.6955 7.52524 18.4822H7.52441ZM10.7503 5.9708L12.8706 8.09108C12.4593 8.59342 12.4047 9.26128 12.7423 9.98128L12.9616 10.4464L9.43861 6.92335C9.37757 6.81002 9.34438 6.68378 9.34179 6.55508C9.34179 6.33411 9.42786 6.12721 9.58344 5.9708C9.74082 5.82112 9.9497 5.73766 10.1669 5.73766C10.3841 5.73766 10.593 5.82112 10.7503 5.9708ZM18.1051 7.67563C17.7948 7.21466 17.3586 6.91756 16.8753 6.83894C16.6812 6.80632 16.4825 6.81388 16.2915 6.86114C16.1005 6.9084 15.9212 6.99436 15.7647 7.1137C15.4535 7.3537 15.2599 7.65659 15.1754 7.99508C14.9266 7.75301 14.611 7.59102 14.2692 7.52997C13.9911 7.4859 13.7061 7.52267 13.4483 7.6359L11.2668 5.45439C10.9747 5.16339 10.5792 5.00001 10.1669 5.00001C9.7546 5.00001 9.35911 5.16339 9.06703 5.45439C8.87539 5.64887 8.73887 5.89078 8.67144 6.15535C8.5271 6.00929 8.35536 5.89315 8.16606 5.81358C7.97675 5.73401 7.77361 5.69257 7.56826 5.69165C7.36292 5.69073 7.15941 5.73034 6.9694 5.8082C6.77938 5.88607 6.60661 6.00066 6.46096 6.14542C6.25382 6.35175 6.10947 6.6126 6.04468 6.8977C5.42068 6.2737 4.39613 6.2737 3.80772 6.86128C3.51632 7.15315 3.35266 7.54872 3.35266 7.96114C3.35266 8.37357 3.51632 8.76914 3.80772 9.06101C3.56937 9.16032 3.30703 9.29935 3.09268 9.5137C2.80164 9.80592 2.63823 10.2015 2.63823 10.614C2.63823 11.0264 2.80164 11.422 3.09268 11.7142L3.6091 12.229C3.33829 12.291 3.08902 12.4243 2.88721 12.6152C2.6854 12.8061 2.53842 13.0476 2.46154 13.3146C2.38467 13.5815 2.38071 13.8642 2.45008 14.1332C2.51945 14.4022 2.65961 14.6477 2.85599 14.8442L7.00965 18.9987C8.32965 20.3178 9.91861 21.1876 11.4852 21.4475C11.806 21.5011 12.1307 21.5282 12.456 21.5286C13.3051 21.5286 14.1087 21.33 14.8494 20.9493C15.0803 20.9824 15.3087 21.0031 15.5346 21.0031C16.8008 21.0031 17.9917 20.4834 19.0403 19.4356C21.8028 16.6731 21.5917 13.7021 20.4786 11.85L18.1051 7.67645V7.67563Z"></path></svg></div></div></div></div></a></span></div><div class="pw-multi-vote-count e nu nv nw nx ny nz oa"><p class="z b y u cv"><span class="ob">--</span></p></div></div></span></div><div class="sn am"><div><div class="bt"><div tabindex="-1" class="cq"><button class="af nn go oe am j dn np of" aria-label="responses"><svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="lb"><path d="M18.0064 16.8029C19.5393 15.347 20.24 13.4782 20.24 11.4818C20.24 7.35659 16.7088 4 12.1914 4C7.67395 4 4 7.35659 4 11.4818C4 15.6077 7.67395 18.9643 12.1914 18.9643C13.0081 18.9643 13.8134 18.8527 14.5839 18.6374C14.815 18.8368 15.064 19.0281 15.3284 19.1956C16.3876 19.8892 17.5312 20.24 18.7266 20.24C18.9505 20.232 19.1273 20.1284 19.2132 19.953C19.2554 19.8711 19.2738 19.7795 19.2664 19.688C19.2589 19.5966 19.2259 19.5089 19.1711 19.4347C18.6763 18.765 18.326 18.0714 18.1313 17.3777C18.0754 17.1816 18.0337 16.9817 18.0064 16.7798V16.8029ZM14.884 17.8585L14.8167 17.6353L14.502 17.7309C13.7529 17.9559 12.9738 18.0698 12.1906 18.069C8.16787 18.069 4.89943 15.1142 4.89943 11.4818C4.89943 7.84932 8.16787 4.89376 12.1906 4.89376C16.2051 4.89376 19.3033 7.85171 19.3033 11.4874C19.3033 13.2813 18.695 14.9556 17.2757 16.2073L17.081 16.3747V16.6299C17.081 16.6857 17.0811 16.7814 17.0973 16.9249C17.1216 17.1561 17.1784 17.4032 17.2514 17.6584C17.4055 18.2165 17.6488 18.7746 17.9732 19.3167C17.2189 19.2051 16.489 18.9261 15.8077 18.4716C15.532 18.2962 15.094 18.0889 14.8669 17.8816L14.884 17.8585Z"></path></svg><p class="z b cr u w"><span class="pw-responses-count od lb">1</span></p></button></div></div></div></div><div class="am j w"><div><div class="bt"><div tabindex="-1" class="cq"><span data-dd-action-name="Susi presentation tracker repost_footer"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Frepost%2Fp%2Fb0e7dab4d793&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fmixpaneleng%2Fautomate-rotating-credentials-using-terraform-b0e7dab4d793&user=Andy+Leap&userId=4f202918f2e7&source=---footer_actions--b0e7dab4d793---------------------repost_footer--------------------" data-discover="true"><span class="nn dz bx af go nr am j ns nt nm ac og oh" aria-disabled="false" aria-label="Repost"><div class="dg df e dm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M3 8.72727L5.64706 6M5.64706 6L8.29412 8.72727M5.64706 6V14.1818V15.2475C5.64706 15.9633 5.92589 16.6509 6.42442 17.1646C6.94277 17.6986 7.6553 18 8.39955 18H12" stroke="currentColor" stroke-linecap="round"></path><path d="M21 15.2727L18.3529 18M18.3529 18L15.7059 15.2727M18.3529 18V9.81818V8.75249C18.3529 8.03671 18.0741 7.34908 17.5756 6.83545C17.0572 6.30139 16.3447 6 15.6004 6L12 6" stroke="currentColor" stroke-linecap="round"></path></svg></div></span></a></span></div></div></div><div class="od e"></div></div></div><div class="am j"><div class="ck"><div class="so e ej"><div><div class="bt"><div tabindex="-1" class="cq"><span data-dd-action-name="Susi presentation tracker bookmark_footer"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" data-testid="footerBookmarkButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2Fb0e7dab4d793&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fmixpaneleng%2Fautomate-rotating-credentials-using-terraform-b0e7dab4d793&source=---footer_actions--b0e7dab4d793---------------------bookmark_footer--------------------" data-discover="true"><span class=""><svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg" class="w oi" aria-label="Add to list bookmark button"><path d="M18 2.5C18 2.22386 18.2239 2 18.5 2C18.7762 2 19 2.22386 19 2.5V5H21.5C21.7761 5 22 5.22386 22 5.5C22 5.77614 21.7761 6 21.5 6H19V8.5C19 8.77614 18.7762 9 18.5 9C18.2239 9 18 8.77614 18 8.5V6H15.5C15.2239 6 15 5.77614 15 5.5C15 5.22386 15.2239 5 15.5 5H18V2.5Z" fill="currentColor"></path><path d="M7 7C7 6.44772 7.44772 6 8 6H11.5C11.7761 6 12 5.77614 12 5.5C12 5.22386 11.7761 5 11.5 5H8C6.89543 5 6 5.89543 6 7V21C6 21.1905 6.10823 21.3644 6.27912 21.4486C6.45002 21.5327 6.65387 21.5125 6.80486 21.3963L12.5 17L18.1951 21.3963C18.3461 21.5125 18.55 21.5327 18.7209 21.4486C18.8918 21.3644 19 21.1905 19 21V12.5C19 12.2239 18.7761 12 18.5 12C18.2239 12 18 12.2239 18 12.5V19.9846L12.8049 15.9729C12.6251 15.8346 12.3749 15.8346 12.1951 15.9729L7 19.9846V7Z" fill="currentColor"></path></svg></span></a></span></div></div></div></div></div><div class="so e ej"><div class="bt" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu" aria-haspopup="dialog"><div><div class="bt"><div tabindex="-1" class="cq"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="footerSocialShareButton" class="bx dn by bz ca ab cb oo ae af ag bm op oq or os"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.2176 4.93118C15.1883 4.98289 15.1484 5.0278 15.1004 5.06293L15.1118 5.06859C15.024 5.12481 14.9269 5.15261 14.8204 5.14293C14.7004 5.13293 14.6004 5.08293 14.5204 5.01293L12.5004 2.99293V10.0629C12.5004 10.3429 12.2704 10.5629 12.0004 10.5629C11.7304 10.5629 11.5004 10.3429 11.5004 10.0629V3.02293L9.50042 5.02293C9.42474 5.09456 9.32654 5.13771 9.22259 5.14501C9.11863 5.1523 9.01537 5.12329 8.93042 5.06293H8.91042C8.82042 4.99293 8.75042 4.88293 8.75042 4.76293C8.74294 4.70553 8.74801 4.64719 8.76528 4.59195C8.78254 4.5367 8.81159 4.48586 8.85042 4.44293L11.6504 1.64293C11.7439 1.55132 11.8695 1.5 12.0004 1.5C12.1313 1.5 12.257 1.55132 12.3504 1.64293L15.1504 4.43293C15.1931 4.47602 15.2258 4.52782 15.2466 4.58479C15.2673 4.64175 15.2754 4.70252 15.2704 4.76293C15.2649 4.82212 15.2469 4.87946 15.2176 4.93118ZM15.1118 5.06859L15.1204 5.07293V5.06293C15.1175 5.06485 15.1147 5.06674 15.1118 5.06859ZM16 7.06293H17.5C18.0304 7.06293 18.5391 7.27364 18.9142 7.64871C19.2893 8.02379 19.5 8.53249 19.5 9.06293V19.0629C19.5 19.5934 19.2893 20.1021 18.9142 20.4771C18.5391 20.8522 18.0304 21.0629 17.5 21.0629H6.5C5.4 21.0629 4.5 20.1629 4.5 19.0629V9.06293C4.5 8.53249 4.71071 8.02379 5.08579 7.64871C5.46086 7.27364 5.96957 7.06293 6.5 7.06293H8C8.13188 7.06481 8.25769 7.11872 8.35 7.21293C8.44421 7.30524 8.49812 7.43104 8.5 7.56293C8.49812 7.69481 8.44421 7.82061 8.35 7.91293C8.25769 8.00713 8.13188 8.06105 8 8.06293H6.4C5.9 8.06293 5.5 8.46293 5.5 8.96293V19.1629C5.5 19.4016 5.59482 19.6305 5.7636 19.7993C5.93239 19.9681 6.16131 20.0629 6.4 20.0629H17.6C18.1 20.0629 18.5 19.6629 18.5 19.1629V8.96293C18.5 8.46293 18.1 8.06293 17.6 8.06293H16C15.8674 8.06293 15.7402 8.01025 15.6464 7.91648C15.5527 7.82271 15.5 7.69554 15.5 7.56293C15.5 7.43032 15.5527 7.30314 15.6464 7.20937C15.7402 7.11561 15.8674 7.06293 16 7.06293Z" fill="currentColor"></path></svg></button></div></div></div></div></div></div></div></div></div></div></footer><div class="sp e"><div class="am ev"><div class="fc cs iz ja jb jc"><div class="am gh sq"><div class="am lm ss lk st li su sv sw sx sy"><div class="sz ta tb tc td te tf tg th ti am lc"><div class="ck cz"><a href="https://medium.com/mixpaneleng?source=post_page---post_publication_info--b0e7dab4d793-----------------------------------------" rel="noopener follow"><div class="dm"><img alt="Mixpanel Engineering" class="ei in e tk tj" src="https://miro.medium.com/v2/resize:fill:96:96/1*wdBmRrZ2IldG8fNVhER_xg.png" width="48" height="48" loading="lazy"/><div class="in e tj tk dr g ed iq"></div></div></a></div><div class="da r s"><a href="https://medium.com/mixpaneleng?source=post_page---post_publication_info--b0e7dab4d793-----------------------------------------" rel="noopener follow"><div class="dm"><img alt="Mixpanel Engineering" class="ei in e tm tl" src="https://miro.medium.com/v2/resize:fill:128:128/1*wdBmRrZ2IldG8fNVhER_xg.png" width="64" height="64" loading="lazy"/><div class="in e tl tm dr g ed iq"></div></div></a></div><div class="da r s tn ej"></div></div><div class="fc am gh el"><div class="to tp tq tr ts e"><a class="bx x by ca ab cb ac ae af ag ah ai aj ak" href="https://medium.com/mixpaneleng?source=post_page---post_publication_info--b0e7dab4d793-----------------------------------------" rel="noopener follow"><h2 class="z fi tt tu tv tw tx ty fn fo fp fq fr fs ft fu fv cv">Published in <!-- -->Mixpanel Engineering</h2></a><div class="tz am lo"><div class="e ej"><span class="pw-follower-count z b cr u w"><a class="bx x by bz ca ab cb ac ae af ag ah ai lx" rel="noopener follow" href="/mixpaneleng/followers?source=post_page---post_publication_info--b0e7dab4d793-----------------------------------------" data-discover="true">341 followers</a></span></div><div class="z b cr u w am sr"><span class="fw e" aria-hidden="true"><span class="z b cr u w">·</span></span><a class="bx x by bz ca ab cb ac ae af ag ah ai lx" rel="noopener follow" href="/mixpaneleng/why-we-left-medium-10cddd141c70?source=post_page---post_publication_info--b0e7dab4d793-----------------------------------------" data-discover="true">Last published <span>May 16, 2025</span></a></div></div><div class="ua e"><p class="z b cr u cv">Blog is now hosted at <a class="bx x by bz ca ab cb ac ae af ag ah ai ir is it" href="https://mixpanel.substack.com" rel="noopener ugc nofollow">https://mixpanel.substack.com</a></p></div></div></div><div class="ck cz"><div class="e ej"></div></div></div><div class="am lm ss lk st li su sv sw sx sy"><div class="sz ta tb tc td te tf tg th ti am lc"><div class="ck cz"><a tabindex="0" rel="noopener follow" href="/@andyleap?source=post_page---post_author_info--b0e7dab4d793-----------------------------------------" data-discover="true"><div class="e dm"><img alt="Andy Leap" class="e bs ee tj tk ei" src="https://miro.medium.com/v2/resize:fill:96:96/0*9nItFvX1uxUt2po7." width="48" height="48" loading="lazy"/><div class="ed ee e tj tk dr g cf iq"></div></div></a></div><div class="da r s"><a tabindex="0" rel="noopener follow" href="/@andyleap?source=post_page---post_author_info--b0e7dab4d793-----------------------------------------" data-discover="true"><div class="e dm"><img alt="Andy Leap" class="e bs ee tl tm ei" src="https://miro.medium.com/v2/resize:fill:128:128/0*9nItFvX1uxUt2po7." width="64" height="64" loading="lazy"/><div class="ed ee e tl tm dr g cf iq"></div></div></a></div><div class="da r s tn ej"><div class="am do"><!--$--><!--/$--></div></div></div><div class="fc am gh el"><div class="to tp tq tr ts e"><a class="bx x by ca ab cb ac ae af ag ah ai aj ak" rel="noopener follow" href="/@andyleap?source=post_page---post_author_info--b0e7dab4d793-----------------------------------------" data-discover="true"><h2 class="z fi tt tu tv tw tx ty fn fo fp fq fr fs ft fu fv cv">Written by <!-- -->Andy Leap</h2></a><div class="tz am lo"><div class="e ej"><span class="pw-follower-count z b cr u w"><a class="bx x by bz ca ab cb ac ae af ag ah ai lx" rel="noopener follow" href="/@andyleap/followers?source=post_page---post_author_info--b0e7dab4d793-----------------------------------------" data-discover="true">15 followers</a></span></div><div class="z b cr u w am sr"><span class="fw e" aria-hidden="true"><span class="z b cr u w">·</span></span><a class="bx x by bz ca ab cb ac ae af ag ah ai lx" rel="noopener follow" href="/@andyleap/following?source=post_page---post_author_info--b0e7dab4d793-----------------------------------------" data-discover="true">1 following</a></div></div></div></div><div class="ck cz"><div class="e ej"><div class="am do"><!--$--><!--/$--></div></div></div></div></div></div></div></div><div><div class="am ev"><div class="fc cs iz ja jb jc"><div class="ub uc"><div class="am nh"><div class="ud ef eg e ei"></div><div class="v ue e"><div class="uf ug uh e ei"></div><div class="ug ui e ei"></div></div></div><div class="uj e"><div class="uf uk cs e ei"></div><div class="uf uk cs e ei"></div><div class="uk ul e ei"></div></div></div></div></div></div><div><div class="um un uo up uq e"><div class="ur cs k us ut iw ix iy"></div><div class="am ev"><div class="fc cs iz ja jb jc"><div class="uf uu uv e ei"></div><div class="uu uw e ei"></div><div class="ux am im"><div class="uy cm e ei"></div><div class="uy cm e ei"></div></div><div class="uz uu tk e ei"></div></div></div></div></div><div class="va vb vc vd ve e"><div><div class="am ev"><div class="fc cs iz ja jb jc"><div class="jq am nh jo vf vg vh vi vj vk vl vm vn vo vp vq vr vs vt"><div class="vu vv vw ts vx vy vz tr wa wb wc wd we wf wg wh wi wj wk wl wm"><div class="uz wn cs e ei"></div><div class="wo ef wp e ei"></div><div class="uf wq wr e ei"></div><div class="uf wq ws e ei"></div><div class="wt wq wu e ei"></div></div><div class="vu vv vw ts vx vy vz tr wa wb wc wd we wf wg wh wi wj wk wl wm"><div class="uz wn cs e ei"></div><div class="wo ef wp e ei"></div><div class="uf wq wr e ei"></div><div class="uf wq ws e ei"></div><div class="wt wq wu e ei"></div></div></div></div></div></div><div><div class="am ev"><div class="fc cs iz ja jb jc"><div class="jq am nh jo vf vg vh vi vj vk vl vm vn vo vp vq vr vs vt"><div class="vu vv vw ts vx vy vz tr wa wb wc wd we wf wg wh wi wj wk wl wm"><div class="uz wn cs e ei"></div><div class="wo ef wp e ei"></div><div class="uf wq wr e ei"></div><div class="uf wq ws e ei"></div><div class="wt wq wu e ei"></div></div><div class="vu vv vw ts vx vy vz tr wa wb wc wd we wf wg wh wi wj wk wl wm"><div class="uz wn cs e ei"></div><div class="wo ef wp e ei"></div><div class="uf wq wr e ei"></div><div class="uf wq ws e ei"></div><div class="wt wq wu e ei"></div></div></div></div></div></div><div class="ck cz da"><div class="ur cs wv ww"></div><div class="am ev"><div class="fc cs iz ja jb jc"><div class="wx am nh jo"><div class="wy wz e"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" href="https://help.medium.com/hc/en-us?source=post_page-----b0e7dab4d793-----------------------------------------" rel="noopener follow"><p class="z b y u w">Help</p></a></div><div class="wy wz e"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" href="https://status.medium.com/?source=post_page-----b0e7dab4d793-----------------------------------------" rel="noopener follow"><p class="z b y u w">Status</p></a></div><div class="wy wz e"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" rel="noopener follow" href="/about?autoplay=1&source=post_page-----b0e7dab4d793-----------------------------------------" data-discover="true"><p class="z b y u w">About</p></a></div><div class="wy wz e"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" rel="noopener follow" href="/jobs-at-medium/work-at-medium-959d1a85284e?source=post_page-----b0e7dab4d793-----------------------------------------" data-discover="true"><p class="z b y u w">Careers</p></a></div><div class="wy wz e"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" href="mailto:pressinquiries@medium.com" rel="noopener follow"><p class="z b y u w">Press</p></a></div><div class="wy wz e"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" href="https://blog.medium.com/?source=post_page-----b0e7dab4d793-----------------------------------------" rel="noopener follow"><p class="z b y u w">Blog</p></a></div><div class="wy wz e"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" href="https://medium.com/store" rel="noopener follow" target="_blank"><p class="z b y u w">Store</p></a></div><div class="wy wz e"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" href="https://policy.medium.com/medium-privacy-policy-f03bf92035c9?source=post_page-----b0e7dab4d793-----------------------------------------" rel="noopener follow"><p class="z b y u w">Privacy</p></a></div><div class="wy wz e"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" href="https://policy.medium.com/medium-rules-30e5502c4eb4?source=post_page-----b0e7dab4d793-----------------------------------------" rel="noopener follow"><p class="z b y u w">Rules</p></a></div><div class="wy wz e"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" href="https://policy.medium.com/medium-terms-of-service-9db0094a1e0f?source=post_page-----b0e7dab4d793-----------------------------------------" rel="noopener follow"><p class="z b y u w">Terms</p></a></div><div class="wy e"><a class="bx x by bz ca ab cb ac ae af ag ah ai aj ak" href="https://speechify.com/medium?source=post_page-----b0e7dab4d793-----------------------------------------" rel="noopener follow"><p class="z b y u w">Text to speech</p></a></div></div></div></div></div></div></div></div></div></div><script>((storageKey2, restoreKey) => {
|
||
if (!window.history.state || !window.history.state.key) {
|
||
let key = Math.random().toString(32).slice(2);
|
||
window.history.replaceState({ key }, "");
|
||
}
|
||
try {
|
||
let positions = JSON.parse(sessionStorage.getItem(storageKey2) || "{}");
|
||
let storedY = positions[restoreKey || window.history.state.key];
|
||
if (typeof storedY === "number") {
|
||
window.scrollTo(0, storedY);
|
||
}
|
||
} catch (error) {
|
||
console.error(error);
|
||
sessionStorage.removeItem(storageKey2);
|
||
}
|
||
})("react-router-scroll-positions", null)</script><script>window.__reactRouterContext = {"basename":"/","future":{"unstable_optimizeDeps":true,"v8_passThroughRequests":false,"v8_trailingSlashAwareDataRequests":false,"unstable_previewServerPrerendering":false,"v8_middleware":true,"v8_splitRouteModules":false,"v8_viteEnvironmentApi":false},"routeDiscovery":{"mode":"initial"},"ssr":true,"isSpaMode":false};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());</script><script type="module" async="">import "https://cdn-client.medium.com/lite/static/manifest-3cf8583e.js";
|
||
import * as route0 from "https://cdn-client.medium.com/lite/assets/entry-fBNTF2ig9x.js";
|
||
import * as route1 from "https://cdn-client.medium.com/lite/assets/entry-DJjt4aY773.js";
|
||
|
||
window.__reactRouterRouteModules = {"root":route0,"routes/pages/entity-routes/ShowEntityPost":route1};
|
||
|
||
import("https://cdn-client.medium.com/lite/assets/entry-C9P2t20qJW.js");</script><!--$--><script>window.__reactRouterContext.streamController.enqueue("[{\"_1\":2,\"_3\":-5,\"_4\":-5},\"loaderData\",{\"_5\":6},\"actionData\",\"errors\",\"routes/pages/entity-routes/ShowEntityPost\",{}]\n");</script><!--$--><script>window.__reactRouterContext.streamController.close();</script><!--/$--><!--/$--><script>window.__APOLLO_STATE__ = {"ROOT_QUERY":{"__typename":"Query","viewer":null,"postResult({\"id\":\"b0e7dab4d793\"})":{"__ref":"Post:b0e7dab4d793"}},"User:5e2bfa799359":{"__typename":"User","id":"5e2bfa799359","customDomainState":null,"hasSubdomain":false,"username":"neal.kaviratna"},"Collection:b5de3443ad1f":{"__typename":"Collection","id":"b5de3443ad1f","domain":null,"slug":"mixpaneleng","googleAnalyticsId":null,"name":"Mixpanel Engineering","avatar":{"__typename":"ImageMetadata","id":"1*wdBmRrZ2IldG8fNVhER_xg.png"},"description":"Blog is now hosted at https:\u002F\u002Fmixpanel.substack.com","latestPostsConnection({\"paging\":{\"limit\":1}})":{"__typename":"PostConnection","posts":[{"__ref":"Post:10cddd141c70"}]},"subscriberCount":341,"viewerEdge":{"__ref":"CollectionViewerEdge:collectionId:b5de3443ad1f-viewerId:lo_a3f25f83c6fa"},"twitterUsername":"mixpanel","facebookPageId":null},"Post:10cddd141c70":{"__typename":"Post","id":"10cddd141c70","firstPublishedAt":1747430207625,"creator":{"__ref":"User:5e2bfa799359"},"collection":{"__ref":"Collection:b5de3443ad1f"},"isSeries":false,"mediumUrl":"https:\u002F\u002Fmedium.com\u002Fmixpaneleng\u002Fwhy-we-left-medium-10cddd141c70","sequence":null,"uniqueSlug":"why-we-left-medium-10cddd141c70"},"LinkedAccounts:4f202918f2e7":{"__typename":"LinkedAccounts","mastodon":null,"id":"4f202918f2e7"},"User:4f202918f2e7":{"__typename":"User","id":"4f202918f2e7","linkedAccounts":{"__ref":"LinkedAccounts:4f202918f2e7"},"isSuspended":false,"name":"Andy Leap","customDomainState":null,"hasSubdomain":false,"username":"andyleap","bio":"","verifications":{"__typename":"VerifiedInfo","isBookAuthor":false},"imageId":"0*9nItFvX1uxUt2po7.","socialStats":{"__typename":"SocialStats","followerCount":15,"followingCount":1,"collectionFollowingCount":0},"newsletterV3":null,"allowNotes":true,"membership":null,"viewerEdge":{"__ref":"UserViewerEdge:userId:4f202918f2e7-viewerId:lo_a3f25f83c6fa"},"twitterScreenName":""},"Paragraph:d46ec452c2ed_0":{"__typename":"Paragraph","id":"d46ec452c2ed_0","name":"4ce2","type":"H3","href":null,"layout":null,"metadata":null,"text":"Automate Rotating Credentials using Terraform","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_1":{"__typename":"Paragraph","id":"d46ec452c2ed_1","name":"e636","type":"P","href":null,"layout":null,"metadata":null,"text":"At Mixpanel, keeping your data secure is of the utmost importance. We strictly adhere to security best practices, including rotating credentials often. Anyone who has to rotate credentials periodically knows that, without automation, it can be a super time consuming task. This article will discuss our novel approach to automating credential rotations using terraform.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_2":{"__typename":"Paragraph","id":"d46ec452c2ed_2","name":"52fc","type":"H3","href":null,"layout":null,"metadata":null,"text":"Rotation == Toil","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_3":{"__typename":"Paragraph","id":"d46ec452c2ed_3","name":"eef1","type":"P","href":null,"layout":null,"metadata":null,"text":"Without any automation in place, rotating credentials is pure toil. You have to have an engineer go in and create a new credential and then update everything that uses it regularly. If the credentials don’t expire, you don’t have a strong incentive to be diligent. If they do expire, you are deliberately scheduling a future outage. Obviously, both of these options are bad. As an engineer on the DevInfra team at Mixpanel, one of my main enemies is toil. So any kind of “oh, we should manually update a dozen or more secrets with new credentials every month” is just antithetical to my very role.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_4":{"__typename":"Paragraph","id":"d46ec452c2ed_4","name":"a420","type":"P","href":null,"layout":null,"metadata":null,"text":"So let’s start working on how we can automate this process.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_5":{"__typename":"Paragraph","id":"d46ec452c2ed_5","name":"bfb9","type":"H3","href":null,"layout":null,"metadata":null,"text":"Terraform","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_6":{"__typename":"Paragraph","id":"d46ec452c2ed_6","name":"596c","type":"P","href":null,"layout":null,"metadata":null,"text":"Terraform is the bog standard way of automating anything involving cloud platforms, so it seems like an obvious choice for this stuff. Let’s ensure that, though, so we’ll start by setting up an example for testing. We run on GCP, so GCP service accounts are commonly used for giving services access to various GCP resources, as well as for allowing external services to reach into our GCP stuff on our behalf.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_7":{"__typename":"Paragraph","id":"d46ec452c2ed_7","name":"5401","type":"P","href":null,"layout":null,"metadata":null,"text":"We’ll create a simple service account:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_8":{"__typename":"Paragraph","id":"d46ec452c2ed_8","name":"16e1","type":"PRE","href":null,"layout":null,"metadata":null,"text":"resource \"google_service_account\" \"rotation-test\" {\n account_id = \"rotation-test\"\n display_name = \"Rotation Test Account\"\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"bash"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_9":{"__typename":"Paragraph","id":"d46ec452c2ed_9","name":"9c11","type":"P","href":null,"layout":null,"metadata":null,"text":"and create a service account key for that account","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_10":{"__typename":"Paragraph","id":"d46ec452c2ed_10","name":"5eed","type":"PRE","href":null,"layout":null,"metadata":null,"text":"resource \"google_service_account_key\" \"rotation-test\" {\n service_account_id = google_service_account.rotation-test.id\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"python"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_11":{"__typename":"Paragraph","id":"d46ec452c2ed_11","name":"5b9f","type":"P","href":null,"layout":null,"metadata":null,"text":"Run terraform plan on this, and you get:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":4,"end":18,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_12":{"__typename":"Paragraph","id":"d46ec452c2ed_12","name":"5198","type":"PRE","href":null,"layout":null,"metadata":null,"text":"# google_service_account.rotation-test will be created\n+ resource \"google_service_account\" \"rotation-test\" {\n+ account_id = \"rotation-test\"\n+ disabled = false\n+ display_name = \"Rotation Test Account\"\n+ email = (known after apply)\n+ id = (known after apply)\n+ member = (known after apply)\n+ name = (known after apply)\n+ project = \"mixpanel-tools\"\n+ unique_id = (known after apply)\n }\n# google_service_account_key.rotation-test will be created\n+ resource \"google_service_account_key\" \"rotation-test\" {\n+ id = (known after apply)\n+ key_algorithm = \"KEY_ALG_RSA_2048\"\n+ name = (known after apply)\n+ private_key = (sensitive value)\n+ private_key_type = \"TYPE_GOOGLE_CREDENTIALS_FILE\"\n+ public_key = (known after apply)\n+ public_key_type = \"TYPE_X509_PEM_FILE\"\n+ service_account_id = (known after apply)\n+ valid_after = (known after apply)\n+ valid_before = (known after apply)\n }\nPlan: 2 to add, 0 to change, 0 to destroy.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"diff"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_13":{"__typename":"Paragraph","id":"d46ec452c2ed_13","name":"3dfb","type":"P","href":null,"layout":null,"metadata":null,"text":"So we can apply this and export that private_key field to somewhere and we’ve got our service account. We’ll go ahead and throw that in now:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_14":{"__typename":"Paragraph","id":"d46ec452c2ed_14","name":"7aec","type":"PRE","href":null,"layout":null,"metadata":null,"text":"resource \"google_secret_manager_secret\" \"rotation-test\" {\n secret_id = \"rotation-test-key\"\n replication {\n auto {}\n }\n}\nresource \"google_secret_manager_secret_version\" \"rotation-test\" {\n secret = google_secret_manager_secret.rotation-test.id\n secret_data = google_service_account_key.rotation-test.private_key\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"bash"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_15":{"__typename":"Paragraph","id":"d46ec452c2ed_15","name":"23f9","type":"P","href":null,"layout":null,"metadata":null,"text":"And after planning and applying, we have a service account with a key, with the credentials loaded into GCP secrets manager. But this key is static, and we need to rotate it. Simple thing first, we can just taint the service account key in terraform","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_16":{"__typename":"Paragraph","id":"d46ec452c2ed_16","name":"1a57","type":"PRE","href":null,"layout":null,"metadata":null,"text":"terraform taint google_service_account_key.rotation-test","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"typescript"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_17":{"__typename":"Paragraph","id":"d46ec452c2ed_17","name":"15cf","type":"P","href":null,"layout":null,"metadata":null,"text":"Plan that and apply it:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_18":{"__typename":"Paragraph","id":"d46ec452c2ed_18","name":"48ec","type":"PRE","href":null,"layout":null,"metadata":null,"text":"google_service_account_key.rotation-test: Destroying... [id=projects\u002Fmixpanel-tools\u002FserviceAccounts\u002Frotation-test@mixpanel-tools.iam.gserviceaccount.com\u002Fkeys\u002Fe7e71f25bfa52b39bef5273387e1f1be5b218b02]\ngoogle_secret_manager_secret.rotation-test: Creating...\ngoogle_service_account_key.rotation-test: Destruction complete after 0s\ngoogle_service_account_key.rotation-test: Creating...\ngoogle_secret_manager_secret.rotation-test: Creation complete after 0s [id=projects\u002Fmixpanel-tools\u002Fsecrets\u002Frotation-test-key]\ngoogle_service_account_key.rotation-test: Creation complete after 0s [id=projects\u002Fmixpanel-tools\u002FserviceAccounts\u002Frotation-test@mixpanel-tools.iam.gserviceaccount.com\u002Fkeys\u002F3dd8bd10e9a34ca4b0b115caef84311f5151ba31]\ngoogle_secret_manager_secret_version.rotation-test: Creating...\ngoogle_secret_manager_secret_version.rotation-test: Creation complete after 1s [id=projects\u002F839233470602\u002Fsecrets\u002Frotation-test-key\u002Fversions\u002F1]","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"bash"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_19":{"__typename":"Paragraph","id":"d46ec452c2ed_19","name":"1282","type":"P","href":null,"layout":null,"metadata":null,"text":"and we’ve got a new key. But this is manual effort, so how can we automate this? Well, Terraform has a bunch of providers, including some that aren’t actually managing any kind of external resources, like the Time provider, which has a time_rotating resource. Reading the description, it seems ideal, so let’s try it out (with a very fast rotation, so I don’t spend weeks\u002Fmonths writing this post)","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":236,"end":249,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_20":{"__typename":"Paragraph","id":"d46ec452c2ed_20","name":"15b3","type":"PRE","href":null,"layout":null,"metadata":null,"text":"resource \"time_rotating\" \"rotation-test\" {\n rotation_minutes = 5\n}\nresource \"google_service_account_key\" \"rotation-test\" {\n service_account_id = google_service_account.rotation-test.id\n keepers = {\n rotation = time_rotating.rotation-test.id\n }\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"bash"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_21":{"__typename":"Paragraph","id":"d46ec452c2ed_21","name":"ebd6","type":"P","href":null,"layout":null,"metadata":null,"text":"Applying this will immediately trigger the creation of a new service account key and update the secret with the new value","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_22":{"__typename":"Paragraph","id":"d46ec452c2ed_22","name":"50af","type":"PRE","href":null,"layout":null,"metadata":null,"text":"google_secret_manager_secret_version.rotation-test: Destroying... [id=projects\u002F839233470602\u002Fsecrets\u002Frotation-test-key\u002Fversions\u002F1]\ngoogle_secret_manager_secret_version.rotation-test: Destruction complete after 0s\ngoogle_service_account_key.rotation-test: Destroying... [id=projects\u002Fmixpanel-tools\u002FserviceAccounts\u002Frotation-test@mixpanel-tools.iam.gserviceaccount.com\u002Fkeys\u002F3dd8bd10e9a34ca4b0b115caef84311f5151ba31]\ngoogle_service_account_key.rotation-test: Destruction complete after 0s\ntime_rotating.rotation-test: Creating...\ntime_rotating.rotation-test: Creation complete after 0s [id=2024-07-24T20:12:33Z]\ngoogle_service_account_key.rotation-test: Creating...\ngoogle_service_account_key.rotation-test: Creation complete after 1s [id=projects\u002Fmixpanel-tools\u002FserviceAccounts\u002Frotation-test@mixpanel-tools.iam.gserviceaccount.com\u002Fkeys\u002F03f5bc6e8d62bc30b4739c6016374d0608053bc4]\ngoogle_secret_manager_secret_version.rotation-test: Creating...\ngoogle_secret_manager_secret_version.rotation-test: Creation complete after 0s [id=projects\u002F839233470602\u002Fsecrets\u002Frotation-test-key\u002Fversions\u002F2]","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"bash"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_23":{"__typename":"Paragraph","id":"d46ec452c2ed_23","name":"a24b","type":"P","href":null,"layout":null,"metadata":null,"text":"And then, after a little over 5 minutes we plan and apply again","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_24":{"__typename":"Paragraph","id":"d46ec452c2ed_24","name":"e791","type":"PRE","href":null,"layout":null,"metadata":null,"text":"google_secret_manager_secret_version.rotation-test: Destroying... [id=projects\u002F839233470602\u002Fsecrets\u002Frotation-test-key\u002Fversions\u002F2]\ngoogle_secret_manager_secret_version.rotation-test: Destruction complete after 0s\ngoogle_service_account_key.rotation-test: Destroying... [id=projects\u002Fmixpanel-tools\u002FserviceAccounts\u002Frotation-test@mixpanel-tools.iam.gserviceaccount.com\u002Fkeys\u002F03f5bc6e8d62bc30b4739c6016374d0608053bc4]\ngoogle_service_account_key.rotation-test: Destruction complete after 0s\ntime_rotating.rotation-test: Creating...\ntime_rotating.rotation-test: Creation complete after 0s [id=2024-07-24T20:18:29Z]\ngoogle_service_account_key.rotation-test: Creating...\ngoogle_service_account_key.rotation-test: Creation complete after 1s [id=projects\u002Fmixpanel-tools\u002FserviceAccounts\u002Frotation-test@mixpanel-tools.iam.gserviceaccount.com\u002Fkeys\u002F5d7dee0097010a88a1792f3fb79423ea6a0f0f77]\ngoogle_secret_manager_secret_version.rotation-test: Creating...\ngoogle_secret_manager_secret_version.rotation-test: Creation complete after 0s [id=projects\u002F839233470602\u002Fsecrets\u002Frotation-test-key\u002Fversions\u002F3]","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"bash"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_25":{"__typename":"Paragraph","id":"d46ec452c2ed_25","name":"3b38","type":"P","href":null,"layout":null,"metadata":null,"text":"Success! Terraform is rotating our service account key automatically for us!","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_26":{"__typename":"Paragraph","id":"d46ec452c2ed_26","name":"fae4","type":"H3","href":null,"layout":null,"metadata":null,"text":"Invalidation","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_27":{"__typename":"Paragraph","id":"d46ec452c2ed_27","name":"dfb5","type":"P","href":null,"layout":null,"metadata":null,"text":"Unfortunately, now we run into a rather thorny issue, invalidation. Terraform immediately destroys the old service account key and creates a new one, which means that anything using that secret loses access to our project until it gets the updated credentials. If you are using Kubernetes, pods can take up to a minute to update secrets. External Secrets Operator (which we use) can add up to an hour on top of that. Furthermore, some services might only load the secret on startup. This all boils down to our initial path causing outages every time it rotates the credential.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":338,"end":363,"href":"https:\u002F\u002Fexternal-secrets.io\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_28":{"__typename":"Paragraph","id":"d46ec452c2ed_28","name":"daaf","type":"P","href":null,"layout":null,"metadata":null,"text":"The common fix here is to have 2 (or more) credentials, rotating them in an offset pattern, and using whichever is the newest at all times. That way, when you update, you are invalidating the older key, which is (hopefully) not in use anymore, and creating a new key, which is now passed out to all the services.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_29":{"__typename":"Paragraph","id":"d46ec452c2ed_29","name":"1efe","type":"P","href":null,"layout":null,"metadata":null,"text":"Let’s implement this:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_30":{"__typename":"Paragraph","id":"d46ec452c2ed_30","name":"3ff5","type":"PRE","href":null,"layout":null,"metadata":null,"text":"resource \"time_rotating\" \"rotation-test\" {\n count = 2\n rotation_minutes = 5\n}\nresource \"google_service_account_key\" \"rotation-test\" {\n count = 2\n service_account_id = google_service_account.rotation-test.id\n keepers = {\n rotation = time_rotating.rotation-test[count.index].id\n }\n}\nlocals {\n older = timecmp(time_rotating.rotation-test[0].id, time_rotating.rotation-test[1].id) \u003E 0 ? 1 : 0\n}\nresource \"google_secret_manager_secret_version\" \"rotation-test\" {\n secret = google_secret_manager_secret.rotation-test.id\n secret_data = google_service_account_key.rotation-test[local.older].private_key\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"bash"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_31":{"__typename":"Paragraph","id":"d46ec452c2ed_31","name":"28bd","type":"P","href":null,"layout":null,"metadata":null,"text":"This technically works, though it’s… not fun to set up, as initially on applying, the keys will rotate simultaneously, so you don’t get any benefit. You can do a custom import on the rotating_time objects to get them offset, or just wait half the period and terraform state rm time_rotating.rotation-test[1] to force it to rotate early and thus offset them, but there’s a deeper issue here. The time_rotating resource doesn’t rotate on a fixed schedule, i.e. 1:00:00PM then 1:05:00PM then 1:10:00PM, but instead considers the planning time as the start of a new rotation period. If the first one was at 1:00:00PM, but you don’t plan\u002Fapply again til 1:05:30PM, the next expiration will be 1:10:30PM, not 1:10:00PM. This can compound over time, til you potentially wind up with both keys rotating at the same time again, which then becomes an outage, and a particularly nasty one as you’ve probably got something doing those apply operations automatically (which we do, I’ll circle back to that later)","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":258,"end":307,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":395,"end":408,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_32":{"__typename":"Paragraph","id":"d46ec452c2ed_32","name":"d51e","type":"P","href":null,"layout":null,"metadata":null,"text":"How do we fix this? I did a bunch of research, and… couldn’t find any answers. Plenty of threads about other people running into the same issues, but no solutions in sight. So I did what any sane engineer would do…","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_33":{"__typename":"Paragraph","id":"d46ec452c2ed_33","name":"3cad","type":"H3","href":null,"layout":null,"metadata":null,"text":"We wrote a Terraform provider: multirotate_set","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_34":{"__typename":"Paragraph","id":"d46ec452c2ed_34","name":"6c5a","type":"P","href":null,"layout":null,"metadata":null,"text":"We released a Terraform provider to plug all the aforementioned gaps once and for all:multirotate_set.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":86,"end":101,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":86,"end":101,"href":"https:\u002F\u002Fregistry.terraform.io\u002Fproviders\u002Fmixpanel\u002Fmultirotate\u002Flatest\u002Fdocs\u002Fresources\u002Fset","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_35":{"__typename":"Paragraph","id":"d46ec452c2ed_35","name":"25df","type":"P","href":null,"layout":null,"metadata":null,"text":"Let’s put our new multirotate_set resource into play:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":18,"end":33,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_36":{"__typename":"Paragraph","id":"d46ec452c2ed_36","name":"c295","type":"PRE","href":null,"layout":null,"metadata":null,"text":"resource \"multirotate_set\" \"rotation-test\" {\n rotation_period = \"5m\"\n number = 2\n}\nresource \"google_service_account_key\" \"rotation-test\" {\n count = 2\n service_account_id = google_service_account.rotation-test.id\n keepers = {\n rotation = multirotate_set.rotation-test.rotation_set[count.index].expiration\n }\n}\nresource \"google_secret_manager_secret_version\" \"rotation-test\" {\n secret = google_secret_manager_secret.rotation-test.id\n secret_data = google_service_account_key.rotation-test[multirotate_set.rotation-test.current_rotation].private_key\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"bash"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_37":{"__typename":"Paragraph","id":"d46ec452c2ed_37","name":"7fdc","type":"P","href":null,"layout":null,"metadata":null,"text":"A bit simpler than the time_rotating shenanigans. And after 5 minutes, we get:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":23,"end":36,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_38":{"__typename":"Paragraph","id":"d46ec452c2ed_38","name":"f40a","type":"PRE","href":null,"layout":null,"metadata":null,"text":"# multirotate_set.rotation-test will be updated in-place\n resource \"multirotate_set\" \"rotation-test\" {\n! current_rotation = 1 -\u003E 0\n! last_rotate = \"2024-07-24T20:52:25Z\" -\u003E \"2024-07-24T20:57:25Z\"\n rotation_set = [\n {\n! creation = \"2024-07-24T20:47:25Z\" -\u003E \"2024-07-24T20:52:42Z\"\n! expiration = \"2024-07-24T20:52:25Z\" -\u003E \"2024-07-24T21:02:25Z\"\n # (1 unchanged attribute hidden)\n },\n # (1 unchanged element hidden)\n ]\n # (3 unchanged attributes hidden)\n }","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"diff"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_39":{"__typename":"Paragraph","id":"d46ec452c2ed_39","name":"5ba8","type":"P","href":null,"layout":null,"metadata":null,"text":"along with the service account key being recreated, and the secret value updating. Success! Again!","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_40":{"__typename":"Paragraph","id":"d46ec452c2ed_40","name":"bb9a","type":"H3","href":null,"layout":null,"metadata":null,"text":"Enhancement: Expiration","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_41":{"__typename":"Paragraph","id":"d46ec452c2ed_41","name":"006b","type":"P","href":null,"layout":null,"metadata":null,"text":"One thing that’s missing, in my eyes, is key expiration. This is more of an optional thing, but it does look better on audits and is more of a forcing function to make sure you are rotating keys. This is starting to get into the specifics of GCP + Terraform, but let’s carry on and get it done.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_42":{"__typename":"Paragraph","id":"d46ec452c2ed_42","name":"7f2a","type":"P","href":null,"layout":null,"metadata":null,"text":"First up: GCP won’t create an expiring service account key for you, so you’re stuck doing things manually, but that’s what Terraform is for. Start with a private key.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_43":{"__typename":"Paragraph","id":"d46ec452c2ed_43","name":"43a6","type":"PRE","href":null,"layout":null,"metadata":null,"text":"resource \"tls_private_key\" \"rotation-test\" {\n count = 2\n algorithm = \"RSA\"\n rsa_bits = 2048\n lifecycle {\n replace_triggered_by = [multirotate_set.rotation-test.rotation_set[count.index]]\n }\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"bash"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_44":{"__typename":"Paragraph","id":"d46ec452c2ed_44","name":"2a71","type":"P","href":null,"layout":null,"metadata":null,"text":"The private key triggers the rotation, as we want a brand new key each time. Next up, generate a self-signed cert.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_45":{"__typename":"Paragraph","id":"d46ec452c2ed_45","name":"7446","type":"PRE","href":null,"layout":null,"metadata":null,"text":"resource \"tls_self_signed_cert\" \"rotation-test\" {\n count = 2\n private_key_pem = tls_private_key.rotation-test[count.index].private_key_pem\n subject {\n common_name = \"unused\"\n }\n validity_period_hours = 1\n allowed_uses = [\n \"key_encipherment\",\n ]\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"bash"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_46":{"__typename":"Paragraph","id":"d46ec452c2ed_46","name":"85db","type":"P","href":null,"layout":null,"metadata":null,"text":"Note that you want the validity period to be longer than the rotation period, so the key stays valid. Next up, pass that off to Google.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_47":{"__typename":"Paragraph","id":"d46ec452c2ed_47","name":"c49f","type":"PRE","href":null,"layout":null,"metadata":null,"text":"resource \"google_service_account_key\" \"rotation-test\" {\n count = 2\n service_account_id = google_service_account.rotation-test.id\n public_key_data = base64encode(tls_self_signed_cert.rotation-test[count.index].cert_pem)\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"bash"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_48":{"__typename":"Paragraph","id":"d46ec452c2ed_48","name":"c976","type":"P","href":null,"layout":null,"metadata":null,"text":"And the final step, where it gets a little more complex as Google isn’t doing it for you: Build a credentials file to use, and stick it somewhere. (GCP secrets manager in this case)","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_49":{"__typename":"Paragraph","id":"d46ec452c2ed_49","name":"9ff6","type":"PRE","href":null,"layout":null,"metadata":null,"text":"resource \"google_secret_manager_secret_version\" \"rotation-test\" {\n secret = google_secret_manager_secret.rotation-test.id\n secret_data = jsonencode({\n type : \"service_account\",\n project_id : resource.google_service_account.rotation-test.project,\n \"private_key_id\" : resource.tls_private_key.rotation-test[multirotate_set.rotation-test.current_rotation].id,\n \"private_key\" : resource.tls_private_key.rotation-test[multirotate_set.rotation-test.current_rotation].private_key_pem,\n \"client_email\" : resource.google_service_account.rotation-test.email,\n \"client_id\" : resource.google_service_account.rotation-test.unique_id,\n \"auth_uri\" : \"\u003Chttps:\u002F\u002Faccounts.google.com\u002Fo\u002Foauth2\u002Fauth\u003E\",\n \"token_uri\" : \"\u003Chttps:\u002F\u002Foauth2.googleapis.com\u002Ftoken\u003E\",\n \"auth_provider_x509_cert_url\" : \"\u003Chttps:\u002F\u002Fwww.googleapis.com\u002Foauth2\u002Fv1\u002Fcerts\u003E\",\n \"client_x509_cert_url\" : \"\u003Chttps:\u002F\u002Fwww.googleapis.com\u002Frobot\u002Fv1\u002Fmetadata\u002Fx509\u002F${resource.google_service_account.rotation-test.email}\u003E\"\n })\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"bash"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_50":{"__typename":"Paragraph","id":"d46ec452c2ed_50","name":"39f4","type":"P","href":null,"layout":null,"metadata":null,"text":"And there you go! Rotating, expiring credentials without outages. As long as you keep on top of applying the terraform regularly of course.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_51":{"__typename":"Paragraph","id":"d46ec452c2ed_51","name":"e145","type":"H3","href":null,"layout":null,"metadata":null,"text":"Automation","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_52":{"__typename":"Paragraph","id":"d46ec452c2ed_52","name":"f9c9","type":"P","href":null,"layout":null,"metadata":null,"text":"It is trivial to set up a GitHub Action or some other kind of cron job to automate running terraform apply on a regular schedule. You could definitely stop there and you can consider your problem solved. However, definitely wanted to call out a SaaS tool we use that makes this automation super trival: Terrateam. With Terrateam, all we had to do to start rotating our credentials automatically was flip on drift detection and auto reconciliation, and bing bang boom, our credentials get automatically rotated regularly. No more toil.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":303,"end":312,"href":"https:\u002F\u002Fterrateam.io\u002F","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":407,"end":446,"href":"https:\u002F\u002Fterrateam.io\u002Ffeatures\u002Fdrift","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_53":{"__typename":"Paragraph","id":"d46ec452c2ed_53","name":"bc40","type":"P","href":null,"layout":null,"metadata":null,"text":"Before tackling this credential rotation automation problem, we had already deployed Terrateam to help us scale our Terraform usage to meet the needs of 70+ engineers working in a monorepo. By enabling a gitops style Terraform workflow, we’ve completely sidestepped all the issues that come with multiple devs stepping on each other’s toes trying to make changes to terraform configurations at the same time. Terrateam has been great a great partner in deploying Terraform at scale, I’m always happy to recommend them whenever given the opportunity to do so!","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":85,"end":94,"href":"https:\u002F\u002Fterrateam.io\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d46ec452c2ed_54":{"__typename":"Paragraph","id":"d46ec452c2ed_54","name":"de1d","type":"P","href":null,"layout":null,"metadata":null,"text":"If you enjoy eliminating toil like we did in this blog — Mixpanel engineering is hiring!","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":81,"end":87,"href":"https:\u002F\u002Fmixpanel.com\u002Fjobs\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"CollectionViewerEdge:collectionId:b5de3443ad1f-viewerId:lo_a3f25f83c6fa":{"__typename":"CollectionViewerEdge","id":"collectionId:b5de3443ad1f-viewerId:lo_a3f25f83c6fa","isEditor":false,"isMuting":false},"UserViewerEdge:userId:4f202918f2e7-viewerId:lo_a3f25f83c6fa":{"__typename":"UserViewerEdge","id":"userId:4f202918f2e7-viewerId:lo_a3f25f83c6fa","isMuting":false},"TagViewerEdge:tagSlug:terraform-viewerId:lo_a3f25f83c6fa":{"__typename":"TagViewerEdge","id":"tagSlug:terraform-viewerId:lo_a3f25f83c6fa","isMuting":false,"isFollowing":false},"Tag:terraform":{"__typename":"Tag","viewerEdge":{"__ref":"TagViewerEdge:tagSlug:terraform-viewerId:lo_a3f25f83c6fa"},"id":"terraform","displayTitle":"Terraform","normalizedTagSlug":"terraform"},"TagViewerEdge:tagSlug:automation-viewerId:lo_a3f25f83c6fa":{"__typename":"TagViewerEdge","id":"tagSlug:automation-viewerId:lo_a3f25f83c6fa","isMuting":false,"isFollowing":false},"Tag:automation":{"__typename":"Tag","viewerEdge":{"__ref":"TagViewerEdge:tagSlug:automation-viewerId:lo_a3f25f83c6fa"},"id":"automation","displayTitle":"Automation","normalizedTagSlug":"automation"},"TagViewerEdge:tagSlug:credentials-viewerId:lo_a3f25f83c6fa":{"__typename":"TagViewerEdge","id":"tagSlug:credentials-viewerId:lo_a3f25f83c6fa","isMuting":false,"isFollowing":false},"Tag:credentials":{"__typename":"Tag","viewerEdge":{"__ref":"TagViewerEdge:tagSlug:credentials-viewerId:lo_a3f25f83c6fa"},"id":"credentials","displayTitle":"Credentials","normalizedTagSlug":"credentials"},"TagViewerEdge:tagSlug:security-viewerId:lo_a3f25f83c6fa":{"__typename":"TagViewerEdge","id":"tagSlug:security-viewerId:lo_a3f25f83c6fa","isMuting":false,"isFollowing":false},"Tag:security":{"__typename":"Tag","viewerEdge":{"__ref":"TagViewerEdge:tagSlug:security-viewerId:lo_a3f25f83c6fa"},"id":"security","displayTitle":"Security","normalizedTagSlug":"security"},"PostViewerEdge:postId:b0e7dab4d793-viewerId:lo_a3f25f83c6fa":{"__typename":"PostViewerEdge","hasReposted":false,"id":"postId:b0e7dab4d793-viewerId:lo_a3f25f83c6fa","repostNote":null},"Post:b0e7dab4d793":{"__typename":"Post","id":"b0e7dab4d793","isPublished":true,"allowResponses":true,"isLimitedState":false,"collection":{"__ref":"Collection:b5de3443ad1f"},"content({\"postMeteringOptions\":{\"referrer\":\"\"}})":{"__typename":"PostContent","isLockedPreviewOnly":false,"bodyModel":{"__typename":"RichText","sections":[{"__typename":"Section","name":"e6b9","startIndex":0,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null}],"paragraphs":[{"__ref":"Paragraph:d46ec452c2ed_0"},{"__ref":"Paragraph:d46ec452c2ed_1"},{"__ref":"Paragraph:d46ec452c2ed_2"},{"__ref":"Paragraph:d46ec452c2ed_3"},{"__ref":"Paragraph:d46ec452c2ed_4"},{"__ref":"Paragraph:d46ec452c2ed_5"},{"__ref":"Paragraph:d46ec452c2ed_6"},{"__ref":"Paragraph:d46ec452c2ed_7"},{"__ref":"Paragraph:d46ec452c2ed_8"},{"__ref":"Paragraph:d46ec452c2ed_9"},{"__ref":"Paragraph:d46ec452c2ed_10"},{"__ref":"Paragraph:d46ec452c2ed_11"},{"__ref":"Paragraph:d46ec452c2ed_12"},{"__ref":"Paragraph:d46ec452c2ed_13"},{"__ref":"Paragraph:d46ec452c2ed_14"},{"__ref":"Paragraph:d46ec452c2ed_15"},{"__ref":"Paragraph:d46ec452c2ed_16"},{"__ref":"Paragraph:d46ec452c2ed_17"},{"__ref":"Paragraph:d46ec452c2ed_18"},{"__ref":"Paragraph:d46ec452c2ed_19"},{"__ref":"Paragraph:d46ec452c2ed_20"},{"__ref":"Paragraph:d46ec452c2ed_21"},{"__ref":"Paragraph:d46ec452c2ed_22"},{"__ref":"Paragraph:d46ec452c2ed_23"},{"__ref":"Paragraph:d46ec452c2ed_24"},{"__ref":"Paragraph:d46ec452c2ed_25"},{"__ref":"Paragraph:d46ec452c2ed_26"},{"__ref":"Paragraph:d46ec452c2ed_27"},{"__ref":"Paragraph:d46ec452c2ed_28"},{"__ref":"Paragraph:d46ec452c2ed_29"},{"__ref":"Paragraph:d46ec452c2ed_30"},{"__ref":"Paragraph:d46ec452c2ed_31"},{"__ref":"Paragraph:d46ec452c2ed_32"},{"__ref":"Paragraph:d46ec452c2ed_33"},{"__ref":"Paragraph:d46ec452c2ed_34"},{"__ref":"Paragraph:d46ec452c2ed_35"},{"__ref":"Paragraph:d46ec452c2ed_36"},{"__ref":"Paragraph:d46ec452c2ed_37"},{"__ref":"Paragraph:d46ec452c2ed_38"},{"__ref":"Paragraph:d46ec452c2ed_39"},{"__ref":"Paragraph:d46ec452c2ed_40"},{"__ref":"Paragraph:d46ec452c2ed_41"},{"__ref":"Paragraph:d46ec452c2ed_42"},{"__ref":"Paragraph:d46ec452c2ed_43"},{"__ref":"Paragraph:d46ec452c2ed_44"},{"__ref":"Paragraph:d46ec452c2ed_45"},{"__ref":"Paragraph:d46ec452c2ed_46"},{"__ref":"Paragraph:d46ec452c2ed_47"},{"__ref":"Paragraph:d46ec452c2ed_48"},{"__ref":"Paragraph:d46ec452c2ed_49"},{"__ref":"Paragraph:d46ec452c2ed_50"},{"__ref":"Paragraph:d46ec452c2ed_51"},{"__ref":"Paragraph:d46ec452c2ed_52"},{"__ref":"Paragraph:d46ec452c2ed_53"},{"__ref":"Paragraph:d46ec452c2ed_54"}]},"validatedShareKey":"","shareKeyCreator":null},"creator":{"__ref":"User:4f202918f2e7"},"inResponseToEntityType":null,"isLocked":false,"isMarkedPaywallOnly":false,"lockedSource":"LOCKED_POST_SOURCE_NONE","mediumUrl":"https:\u002F\u002Fmedium.com\u002Fmixpaneleng\u002Fautomate-rotating-credentials-using-terraform-b0e7dab4d793","primaryTopic":null,"topics":[{"__typename":"Topic","slug":"programming"}],"responsesLocked":false,"visibility":"PUBLIC","latestPublishedVersion":"d46ec452c2ed","postResponses":{"__typename":"PostResponses","count":1},"responseDistribution":"NOT_DISTRIBUTED","clapCount":67,"title":"Automate Rotating Credentials using Terraform","isSeries":false,"sequence":null,"uniqueSlug":"automate-rotating-credentials-using-terraform-b0e7dab4d793","tags":[{"__ref":"Tag:terraform"},{"__ref":"Tag:automation"},{"__ref":"Tag:credentials"},{"__ref":"Tag:security"}],"inResponseToPostResult":null,"inResponseToCatalogResult":null,"viewerEdge":{"__ref":"PostViewerEdge:postId:b0e7dab4d793-viewerId:lo_a3f25f83c6fa"},"extendedPreviewContent":{"__typename":"PreviewContent","subtitle":"At Mixpanel, keeping your data secure is of the utmost importance. We strictly adhere to security best practices, including rotating…","isFullContent":false},"previewImage":{"__typename":"ImageMetadata","id":"","focusPercentX":null,"focusPercentY":null,"alt":null,"originalHeight":null,"originalWidth":null},"firstPublishedAt":1722292925186,"latestPublishedAt":1747253919423,"pinnedAt":0,"socialTitle":"","socialDek":"","canonicalUrl":"https:\u002F\u002Fmedium.com\u002Fmixpaneleng\u002Fautomate-rotating-credentials-using-terraform-b0e7dab4d793","metaDescription":"","readingTime":7.449056603773585,"previewContent":{"__typename":"PreviewContent","subtitle":"At Mixpanel, keeping your data secure is of the utmost importance. We strictly adhere to security best practices, including rotating…"},"isShortform":false,"seoMetaTags":{"__typename":"SEOMetaTags","jsonLd":"{\"@context\":\"https:\u002F\u002Fschema.org\",\"@id\":\"https:\u002F\u002Fmedium.com\u002Fmixpaneleng\u002Fautomate-rotating-credentials-using-terraform-b0e7dab4d793\",\"@type\":\"SocialMediaPosting\",\"image\":[\"https:\u002F\u002Fmiro.medium.com\u002F\"],\"url\":\"https:\u002F\u002Fmedium.com\u002Fmixpaneleng\u002Fautomate-rotating-credentials-using-terraform-b0e7dab4d793\",\"dateCreated\":\"2024-07-29T22:42:05Z\",\"datePublished\":\"2024-07-29T22:42:05Z\",\"dateModified\":\"2025-05-14T20:18:39Z\",\"headline\":\"Automate Rotating Credentials using Terraform\",\"name\":\"Automate Rotating Credentials using Terraform\",\"description\":\"Automate Rotating Credentials using Terraform At Mixpanel, keeping your data secure is of the utmost importance. We strictly adhere to security best practices, including rotating credentials often …\",\"identifier\":\"b0e7dab4d793\",\"author\":{\"@context\":\"https:\u002F\u002Fschema.org\",\"@id\":\"https:\u002F\u002Fmedium.com\u002F@andyleap\",\"@type\":\"Person\",\"identifier\":\"andyleap\",\"name\":\"Andy Leap\",\"url\":\"https:\u002F\u002Fmedium.com\u002F@andyleap\"},\"creator\":{\"@context\":\"https:\u002F\u002Fschema.org\",\"@id\":\"https:\u002F\u002Fmedium.com\u002F@andyleap\",\"@type\":\"Person\",\"identifier\":\"andyleap\",\"name\":\"Andy Leap\",\"url\":\"https:\u002F\u002Fmedium.com\u002F@andyleap\"},\"publisher\":{\"@context\":\"https:\u002F\u002Fschema.org\",\"@type\":\"Organization\",\"@id\":\"https:\u002F\u002Fmedium.com\u002Fmixpaneleng\",\"name\":\"Mixpanel Engineering\",\"description\":\"Blog is now hosted at https:\u002F\u002Fmixpanel.substack.com\",\"url\":\"https:\u002F\u002Fmedium.com\u002Fmixpaneleng\",\"sameAs\":[\"https:\u002F\u002Ftwitter.com\u002Fmixpanel\"],\"logo\":{\"@type\":\"ImageObject\",\"width\":280,\"height\":280,\"url\":\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:280\u002F1%2AwdBmRrZ2IldG8fNVhER_xg.png\"}},\"mainEntityOfPage\":\"https:\u002F\u002Fmedium.com\u002Fmixpaneleng\u002Fautomate-rotating-credentials-using-terraform-b0e7dab4d793\",\"isAccessibleForFree\":true}"},"seoDescription":"Automate Rotating Credentials using Terraform At Mixpanel, keeping your data secure is of the utmost importance. We strictly adhere to security best practices, including rotating credentials often …","shortformType":"SHORTFORM_TYPE_LINK","seoTitle":"","isSuspended":false,"license":"ALL_RIGHTS_RESERVED","isFeaturedInPublishedPublication":false,"isNewsletter":false,"statusForCollection":"APPROVED","pendingCollection":null,"detectedLanguage":"en","wordCount":1974}};</script><script>window.__GRAPHQL_URI__ = "\u002F_\u002Fgraphql";</script><script>window.__PRELOADED_STATE__ = {"algolia":{"queries":{}},"cache":{"experimentGroupSet":true,"reason":"","group":"enabled","tags":["group-edgeCachePosts","group-enableDarkModeV0","group-enableStoryPageWriterBio","group-enableUserCustomFooter","post-b0e7dab4d793","user-4f202918f2e7","collection-b5de3443ad1f"],"serverVariantState":"44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a","middlewareEnabled":true,"cacheStatus":"DYNAMIC","shouldUseCache":true,"vary":[],"enableDarkModeV0":false,"storyPageWriterBioEnabled":"experiment","expandedTopicPagesEnabled":"experiment","exposureBatteryX3Enabled":"control","enableUserCustomFooter":false},"client":{"hydrated":false,"isUs":false,"isNativeMedium":false,"isSafariMobile":false,"isSafari":false,"isFirefox":false,"routingEntity":{"type":"DEFAULT","explicit":false},"viewerIsBot":false,"clientScore":87},"debug":{"requestId":"a44bc54a-46f4-46e7-b408-85b9b1dcfea3","requestTag":"","hybridDevServices":[]},"multiVote":{"clapsPerEntity":{}},"navigation":{"hideGoogleOneTap":false,"hasRenderedAlternateUserBanner":null,"currentLocation":"https:\u002F\u002Fmedium.com\u002Fmixpaneleng\u002Fautomate-rotating-credentials-using-terraform-b0e7dab4d793","host":"medium.com","hostname":"medium.com","referrer":"","hasSetReferrer":false,"susiModal":{"step":null,"operation":"register","rememberMe":true},"postRead":false,"paymentFunnel":{},"partnerProgram":{"selectedCountryCode":null},"staticRouterContext":{"route":{"name":"ShowPostUnderCollection"},"statusCode":200},"toastQueue":[],"currentToast":null,"queryString":"","currentHash":""},"config":{"nodeEnv":"production","version":"main-20260911-235047-8654e8124b","target":"production","productName":"Medium","publicUrl":"https:\u002F\u002Fcdn-client.medium.com\u002Flite","authDomain":"medium.com","authGoogleClientId":"216296035834-k1k6qe060s2tp2a2jam4ljdcms00sttg.apps.googleusercontent.com","favicon":"production","iosAppId":"828256236","glyphUrl":"https:\u002F\u002Fglyph.medium.com","branchKey":"key_live_ofxXr2qTrrU9NqURK8ZwEhknBxiI6KBm","algolia":{"appId":"MQ57UUUQZ2","apiKeySearch":"394474ced050e3911ae2249ecc774921","indexPrefix":"medium_","host":"-dsn.algolia.net"},"recaptchaKey":"6Lfc37IUAAAAAKGGtC6rLS13R1Hrw_BqADfS1LRk","recaptcha3Key":"6Lf8R9wUAAAAABMI_85Wb8melS7Zj6ziuf99Yot5","recaptchaEnterpriseKeyId":"6Le-uGgpAAAAAPprRaokM8AKthQ9KNGdoxaGUvVp","datadog":{"applicationId":"6702d87d-a7e0-42fe-bbcb-95b469547ea0","clientToken":"pub853ea8d17ad6821d9f8f11861d23dfed","rumToken":"pubf9cc52896502b9413b68ba36fc0c7162","context":{"deployment":{"target":"production","tag":"main-20260911-235047-8654e8124b","commit":"8654e8124b64da937b7a19894acb51fdc2d0b94d"}},"datacenter":"us"},"googleAdsCode":"AW-17106321204","googleAnalyticsCode":"G-7JY7T788PK","googlePay":{"apiVersion":"2","apiVersionMinor":"0","merchantId":"BCR2DN6TV7EMTGBM","merchantName":"Medium","instanceMerchantId":"13685562959212738550"},"applePay":{"version":3},"signInWallCustomDomainCollectionIds":["3a8144eabfe3","336d898217ee","61061eb0c96b","138adf9c44c","819cc2aaeee0"],"mediumMastodonDomainName":"me.dm","mediumOwnedAndOperatedCollectionIds":["8a9336e5bb4","b7e45b22fec3","193b68bd4fba","8d6b8a439e32","54c98c43354d","3f6ecf56618","d944778ce714","92d2092dc598","ae2a65f35510","1285ba81cada","544c7006046e","fc8964313712","40187e704f1c","88d9857e584e","7b6769f2748b","bcc38c8f6edf","cef6983b292","cb8577c9149e","444d13b52878","713d7dbc99b0","ef8e90590e66","191186aaafa0","55760f21cdc5","9dc80918cc93","bdc4052bbdba","8ccfed20cbb2"],"tierOneDomains":["medium.com","thebolditalic.com","arcdigital.media","towardsdatascience.com","uxdesign.cc","codeburst.io","psiloveyou.xyz","writingcooperative.com","entrepreneurshandbook.co","prototypr.io","betterhumans.coach.me","theascent.pub"],"topicsToFollow":["d61cf867d93f","8a146bc21b28","1eca0103fff3","4d562ee63426","aef1078a3ef5","e15e46793f8d","6158eb913466","55f1c20aba7a","3d18b94f6858","4861fee224fd","63c6f1f93ee","1d98b3a9a871","decb52b64abf","ae5d4995e225","830cded25262"],"topicToTagMappings":{"accessibility":"accessibility","addiction":"addiction","android-development":"android-development","art":"art","artificial-intelligence":"artificial-intelligence","astrology":"astrology","basic-income":"basic-income","beauty":"beauty","biotech":"biotech","blockchain":"blockchain","books":"books","business":"business","cannabis":"cannabis","cities":"cities","climate-change":"climate-change","comics":"comics","coronavirus":"coronavirus","creativity":"creativity","cryptocurrency":"cryptocurrency","culture":"culture","cybersecurity":"cybersecurity","data-science":"data-science","design":"design","digital-life":"digital-life","disability":"disability","economy":"economy","education":"education","equality":"equality","family":"family","feminism":"feminism","fiction":"fiction","film":"film","fitness":"fitness","food":"food","freelancing":"freelancing","future":"future","gadgets":"gadgets","gaming":"gaming","gun-control":"gun-control","health":"health","history":"history","humor":"humor","immigration":"immigration","ios-development":"ios-development","javascript":"javascript","justice":"justice","language":"language","leadership":"leadership","lgbtqia":"lgbtqia","lifestyle":"lifestyle","machine-learning":"machine-learning","makers":"makers","marketing":"marketing","math":"math","media":"media","mental-health":"mental-health","mindfulness":"mindfulness","money":"money","music":"music","neuroscience":"neuroscience","nonfiction":"nonfiction","outdoors":"outdoors","parenting":"parenting","pets":"pets","philosophy":"philosophy","photography":"photography","podcasts":"podcast","poetry":"poetry","politics":"politics","privacy":"privacy","product-management":"product-management","productivity":"productivity","programming":"programming","psychedelics":"psychedelics","psychology":"psychology","race":"race","relationships":"relationships","religion":"religion","remote-work":"remote-work","san-francisco":"san-francisco","science":"science","self":"self","self-driving-cars":"self-driving-cars","sexuality":"sexuality","social-media":"social-media","society":"society","software-engineering":"software-engineering","space":"space","spirituality":"spirituality","sports":"sports","startups":"startup","style":"style","technology":"technology","transportation":"transportation","travel":"travel","true-crime":"true-crime","tv":"tv","ux":"ux","venture-capital":"venture-capital","visual-design":"visual-design","work":"work","world":"world","writing":"writing"},"defaultImages":{"avatar":{"imageId":"1*dmbNkD5D-u45r44go_cf0g.png","height":150,"width":150},"orgLogo":{"imageId":"7*V1_7XP4snlmqrc_0Njontw.png","height":110,"width":500},"postLogo":{"imageId":"167cff2a3d17ac1e64d0762539978f2d54c0058886e8b3c8a03a725a83012ec0","height":630,"width":1200},"postPreviewImage":{"imageId":"bc1f8416df0cad099e43cda2872716e5864f18a73bda2a7547ea082aca9b5632","height":630,"width":1200}},"embeddedPostIds":{"coronavirus":"cd3010f9d81f"},"sharedCdcMessaging":{"COVID_APPLICABLE_TAG_SLUGS":[],"COVID_APPLICABLE_TOPIC_NAMES":[],"COVID_APPLICABLE_TOPIC_NAMES_FOR_TOPIC_PAGE":[],"COVID_MESSAGES":{"tierA":{"text":"For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":66,"end":73,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"tierB":{"text":"Anyone can publish on Medium per our Policies, but we don’t fact-check every story. For more info about the coronavirus, see cdc.gov.","markups":[{"start":37,"end":45,"href":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Fcategories\u002F201931128-Policies-Safety"},{"start":125,"end":132,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"paywall":{"text":"This article has been made free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":56,"end":70,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":138,"end":145,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"unbound":{"text":"This article is free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":45,"end":59,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":127,"end":134,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]}},"COVID_BANNER_POST_ID_OVERRIDE_WHITELIST":["3b31a67bff4a"]},"sharedVoteMessaging":{"TAGS":["politics","election-2020","government","us-politics","election","2020-presidential-race","trump","donald-trump","democrats","republicans","congress","republican-party","democratic-party","biden","joe-biden","maga"],"TOPICS":["politics","election"],"MESSAGE":{"text":"Find out more about the U.S. election results here.","markups":[{"start":46,"end":50,"href":"https:\u002F\u002Fcookpolitical.com\u002F2020-national-popular-vote-tracker"}]},"EXCLUDE_POSTS":["397ef29e3ca5"]},"embedPostRules":[],"recircOptions":{"v1":{"limit":3},"v2":{"limit":8}},"braintreeClientKey":"production_zjkj96jm_m56f8fqpf7ngnrd4","braintree":{"enabled":true,"merchantId":"m56f8fqpf7ngnrd4","merchantAccountId":{"usd":"AMediumCorporation_instant","eur":"amediumcorporation_EUR","cad":"amediumcorporation_CAD"},"publicKey":"ds2nn34bg2z7j5gd","braintreeEnvironment":"production","dashboardUrl":"https:\u002F\u002Fwww.braintreegateway.com\u002Fmerchants","gracePeriodDurationInDays":14,"mediumMembershipPlanId":{"monthly":"ce105f8c57a3","monthlyV2":"e8a5e126-792b-4ee6-8fba-d574c1b02fc5","monthlyWithTrial":"d5ee3dbe3db8","monthlyPremium":"fa741a9b47a2","yearly":"a40ad4a43185","yearlyV2":"3815d7d6-b8ca-4224-9b8c-182f9047866e","yearlyStaff":"d74fb811198a","yearlyWithTrial":"b3bc7350e5c7","yearlyPremium":"e21bd2c12166","monthlyOneYearFree":"e6c0637a-2bad-4171-ab4f-3c268633d83c","monthly25PercentOffFirstYear":"235ecc62-0cdb-49ae-9378-726cd21c504b","monthly20PercentOffFirstYear":"ba518864-9c13-4a99-91ca-411bf0cac756","monthly15PercentOffFirstYear":"594c029b-9f89-43d5-88f8-8173af4e070e","monthly10PercentOffFirstYear":"c6c7bc9a-40f2-4b51-8126-e28511d5bdb0","monthlyForStudents":"629ebe51-da7d-41fd-8293-34cd2f2030a8","yearlyOneYearFree":"78ba7be9-0d9f-4ece-aa3e-b54b826f2bf1","yearly25PercentOffFirstYear":"2dbb010d-bb8f-4eeb-ad5c-a08509f42d34","yearly20PercentOffFirstYear":"47565488-435b-47f8-bf93-40d5fbe0ebc8","yearly15PercentOffFirstYear":"8259809b-0881-47d9-acf7-6c001c7f720f","yearly10PercentOffFirstYear":"9dd694fb-96e1-472c-8d9e-3c868d5c1506","yearlyForStudents":"e29345ef-ab1c-4234-95c5-70e50fe6bc23","monthlyCad":"p52orjkaceei","yearlyCad":"h4q9g2up9ktt"},"braintreeDiscountId":{"oneMonthFree":"MONTHS_FREE_01","threeMonthsFree":"MONTHS_FREE_03","sixMonthsFree":"MONTHS_FREE_06","fiftyPercentOffOneYear":"FIFTY_PERCENT_OFF_ONE_YEAR"},"3DSecureVersion":"2","defaultCurrency":"usd","providerPlanIdCurrency":{"4ycw":"usd","rz3b":"usd","3kqm":"usd","jzw6":"usd","c2q2":"usd","nnsw":"usd","q8qw":"usd","d9y6":"usd","fx7w":"cad","nwf2":"cad"}},"paypalClientId":"AXj1G4fotC2GE8KzWX9mSxCH1wmPE3nJglf4Z2ig_amnhvlMVX87otaq58niAg9iuLktVNF_1WCMnN7v","paypal":{"host":"https:\u002F\u002Fapi.paypal.com:443","clientMode":"production","serverMode":"live","webhookId":"4G466076A0294510S","monthlyPlan":{"planId":"P-9WR0658853113943TMU5FDQA","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlan":{"planId":"P-7N8963881P8875835MU5JOPQ","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oneYearGift":{"name":"Medium Membership (1 Year, Digital Gift Code)","description":"Unlimited access to the best and brightest stories on Medium. Gift codes can be redeemed at medium.com\u002Fredeem.","price":"50.00","currency":"USD","sku":"membership-gift-1-yr"},"oldMonthlyPlan":{"planId":"P-96U02458LM656772MJZUVH2Y","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlan":{"planId":"P-59P80963JF186412JJZU3SMI","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"monthlyPlanWithTrial":{"planId":"P-66C21969LR178604GJPVKUKY","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlanWithTrial":{"planId":"P-6XW32684EX226940VKCT2MFA","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oldMonthlyPlanNoSetupFee":{"planId":"P-4N046520HR188054PCJC7LJI","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlanNoSetupFee":{"planId":"P-7A4913502Y5181304CJEJMXQ","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"sdkUrl":"https:\u002F\u002Fwww.paypal.com\u002Fsdk\u002Fjs"},"stripePublishableKey":"pk_live_7FReX44VnNIInZwrIIx6ghjl","log":{"json":true,"level":"info"},"imageUploadMaxSizeMb":25,"staffPicks":{"title":"Staff Picks","catalogId":"c7bc6e1ee00f"}},"session":{"xsrf":""}};</script><script>window.__BUILD_ID__ = "main-20260911-235047-8654e8124b";</script><script>window.__MIDDLEWARE_STATE__={"session":{"xsrf":""},"cache":{"cacheStatus":"BYPASS"}}</script><script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"0b5f665943484354a59c39c6833f7078","spa":2}' crossorigin="anonymous"></script>
|
||
<script>window.__CF$cv$params={r:'a39cd26aa89c2a89',t:'MTc4OTE5NDE5MA==',u:'01a09448c21772e08df69219c4f7f1ed',ut:'TmcLDwx2miyc3LKc5wGegZ91YSvvQ9Vy1HF9zx9_m_Q-1789194191-1.2.1.1-ARH4edfOYzuimvXX3eE.bvpWsUPWcVYn9tp_QS4AVY8Sc0QDSabGitQbgIZMwY.BtdPsBiV7sY1sPLEwud4OmEEYSZGY90pufMsH4FudE94',i:60};(function(){if(!document.body)return;var s=document.createElement('script');s.src='/cdn-cgi/challenge-platform/scripts/precursor/main.js';document.head.appendChild(s);})();</script></body></html> |