{
    "componentChunkName": "component---src-pages-blog-post-tsx",
    "path": "/blog/2020-07-30/cycling-credentials-without-cycling-containers",
    "result": {"data":{"site":{"siteMetadata":{"siteUrl":"https://www.architect.io"}},"allMdx":{"edges":[{"node":{"body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Cycling credentials without cycling containers\",\n  \"slug\": \"cycling-credentials-without-cycling-containers\",\n  \"date\": \"2020-07-30T00:00:00.000Z\",\n  \"author\": \"David Thor\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"In my prior posts, we've talked about \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"/blog/using-hashicorp-vault-to-enable-credential-cycling\"\n  }, \"how to instrument credential cycling\"), \" and\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"/blog/how-dynamic-credentialing-makes-apps-portable\"\n  }, \"why it's important to enable application portability\"), \". In this post, we'll take\\nthe notion of credential cycling even further and show how secrets can be\\ninjected into volumes mounted to your applications. Injecting secrets into\\nmounted volumes is a great way to securely provide credentials to your\\napplications without forcing all your containers to cycle on every update.\"), mdx(\"h2\", {\n    \"id\": \"why-should-we-avoid-container-cycling\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Why should we avoid container cycling?\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#why-should-we-avoid-container-cycling\",\n    \"aria-label\": \"why should we avoid container cycling permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"In a cloud-native world, we're taught to invest heavily in our DevOps and\\ncontinuous delivery processes to ensure that applications can be deployed\\nautomatically and frequently. This guarantees that new features can be\\nreleased to customers safely and quickly. Still,\\ndeployments remain one of the most risky engineering processes and are all too\\noften the cause for production downtime or outages.\\nEven if we have a reliable release process, it's always best to avoid needless\\nuse when possible. And since changes to application credentials don't change any\\napplication code, updating credentials on the fly represents low-hanging fruit\\nfor reducing the overall number of deployments.\"), mdx(\"p\", null, \"There is another reason to avoid container cycling: deployment speed.\\nShutting down and starting up any single container takes time; multiply\\nthis by the number of replicas you have and suddenly you find\\nyourself monitoring a lengthy and risky process. Having applications\\nread in credentials from the filesystem allows them to more quickly\\nreceive updates without needing to be cycled.\"), mdx(\"h2\", {\n    \"id\": \"reading-secrets-from-the-filesystem\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Reading secrets from the filesystem\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#reading-secrets-from-the-filesystem\",\n    \"aria-label\": \"reading secrets from the filesystem permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"The cornerstone of our approach to dynamic credentialing will be to read\\nsecrets from volume mounts. So the first thing we'll need to do is to tell\\nour apps to read in secrets from the file system instead of from environment\\nvariables.\"), mdx(\"p\", null, \"In this example, we're going to load in credentials to a Postgres instance;\\nwe'll assume that the secret is a JSON encoded string containing a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"user\"), \",\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"password\"), \", and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"database\"), \" field:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"js\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-js\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" fs \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"require\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'fs'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \" Client\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \":\"), \" PostgresClient \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"require\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'pg'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token comment\"\n  }, \"// Configure how much time can pass before the credentials will be\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token comment\"\n  }, \"// considered stale and need to be refreshed\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token constant\"\n  }, \"DB_CREDENTIALS_TTL\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" process\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"env\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token constant\"\n  }, \"DB_CREDENTIALS_TTL\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"||\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token number\"\n  }, \"5\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"*\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token number\"\n  }, \"60\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"*\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token number\"\n  }, \"1000\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"let\"), \" postgres_client\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"let\"), \" client_expires_on\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function-variable function\"\n  }, \"getPostgresClient\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=>\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"if\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"!\"), \"postgres_client \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"||\"), \" client_expires_on \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"<\"), \" Date\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"now\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \"\\n    \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" raw_secret \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" fs\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"readFileSync\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"process\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"env\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token constant\"\n  }, \"DB_CREDENTIALS_FILE\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n    \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \" user\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" password\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" database \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token constant\"\n  }, \"JSON\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"parse\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"raw_secret\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\n    \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" postgres_config \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \"\\n      host\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \":\"), \" process\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"env\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token constant\"\n  }, \"DB_HOST\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"||\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'localhost'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \"\\n      port\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \":\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"Number\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"process\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"env\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token constant\"\n  }, \"DB_PORT\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"||\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token number\"\n  }, \"5432\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \"\\n      user\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \"\\n      password\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \"\\n      database\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \"\\n    \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\n    postgres_client \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"new\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token class-name\"\n  }, \"PostgresClient\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"postgres_config\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n    client_expires_on \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" Date\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"now\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"+\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token constant\"\n  }, \"DB_CREDENTIALS_TTL\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\"), \"\\n\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"return\"), \" postgres_client\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\")))), mdx(\"p\", null, \"In the above snippet, we've created a method called \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"getPostgresClient()\"), \" that\\nwill return a properly configured client for accessing our postgres database.\\nWe've also set it up to cache the client and only generate a new one when the\\nprevious credentials are considered stale. This will allow us to return the\\nclient in a reasonably performant way without needing to read from the file\\nsystem on every request.\"), mdx(\"p\", null, \"Next up we'll want to test out the integration! Let's go ahead and create a\\nsimple method that will create a table, write to the database, read from the\\ndatabase, and then tear it all down again.\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"js\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-js\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function-variable function\"\n  }, \"testDBConnection\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"async\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=>\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" db \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"getPostgresClient\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\n  db\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"connect\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token comment\"\n  }, \"// Create and seed table\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"await\"), \" db\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"query\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"\\n    \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'CREATE TABLE users (id int, last_name varchar(255), first_name varchar(255))'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"await\"), \" db\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"query\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"\\n    \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"\\\"INSERT INTO users (id, last_name, first_name) VALUES (1, 'User', 'Test')\\\"\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token comment\"\n  }, \"// Query seeded content\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" result \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"await\"), \" db\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"query\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'SELECT * FROM users'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n  console\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"log\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"result\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"rows\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token comment\"\n  }, \"// Drop table and kill connection\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"await\"), \" db\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"query\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'DROP TABLE users'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"await\"), \" db\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"end\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"testDBConnection\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\")))), mdx(\"p\", null, \"Great! Let's go ahead and write the two methods above into an \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"index.js\"), \" file and\\ncreate a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dockerfile\"), \" to help us run it in a container. Don't forget to create a\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"package.json\"), \" file for the project and install the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pg\"), \" library too.\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"dockerfile\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-dockerfile\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-dockerfile\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token instruction\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token keyword\"\n  }, \"FROM\"), \" node:13\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token instruction\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token keyword\"\n  }, \"WORKDIR\"), \" /usr/src/app\"), \"\\n\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token instruction\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token keyword\"\n  }, \"COPY\"), \" package*.json ./\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token instruction\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token keyword\"\n  }, \"RUN\"), \" npm install\"), \"\\n\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token instruction\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token keyword\"\n  }, \"COPY\"), \" index.js .\"), \"\\n\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token instruction\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token keyword\"\n  }, \"CMD\"), \" [\", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token string\"\n  }, \"\\\"node\\\"\"), \", \", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token string\"\n  }, \"\\\"index.js\\\"\"), \"]\")))), mdx(\"p\", null, \"Before we can properly run our image, we need to boot up a postgres\\ninstance:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"$ docker run -d -p \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token number\"\n  }, \"5432\"), \":5432 \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"\\\\\"), \"\\n    -e \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token assign-left variable\"\n  }, \"POSTGRES_USER\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \"postgres \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"\\\\\"), \"\\n    -e \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token assign-left variable\"\n  }, \"POSTGRES_PASSWORD\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \"password \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"\\\\\"), \"\\n    -e \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token assign-left variable\"\n  }, \"POSTGRES_DB\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \"architect \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"\\\\\"), \"\\n    postgres:11\"))), mdx(\"p\", null, \"Time to boot up our application and see what happens! Let's build that Docker image and run\\nit locally!\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"$ docker build -t credentials-test:latest \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token builtin class-name\"\n  }, \".\"), \"\\n$ docker run credentials-test:latest\"))), mdx(\"p\", null, \"Whoop! Seems we haven't mounted the secret onto the container yet and we got a\\nnasty error. We'll need to write the credentials to a local file that we can then mount\\nto our application when we run it. Go ahead and copy the json credentials into a\\nfile named, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"database.json\"), \":\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"json\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-json\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-json\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token property\"\n  }, \"\\\"user\\\"\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \":\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"\\\"postgres\\\"\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token property\"\n  }, \"\\\"password\\\"\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \":\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"\\\"password\\\"\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token property\"\n  }, \"\\\"database\\\"\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \":\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"\\\"architect\\\"\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\")))), mdx(\"p\", null, \"Finally, we're ready to run our application! Let's run it with the flags needed\\nto mount our local database credentials to the container:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"$ docker run \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"\\\\\"), \"\\n\\t\\t-v \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token variable\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token variable\"\n  }, \"$(\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token builtin class-name\"\n  }, \"pwd\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token variable\"\n  }, \")\")), \":/usr/src/secrets:ro \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"\\\\\"), \"\\n\\t\\t-e \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'DB_CREDENTIALS_FILE=/usr/src/secrets/database.json'\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"\\\\\"), \"\\n\\t\\t-e \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'DB_HOST=host.docker.internal'\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"\\\\\"), \"\\n\\t\\tcredentials-test:latest\"))), mdx(\"p\", null, \"Great job! You should have seen the container output the test user\\nbefore exiting. You can use this flow with any API server- just call\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"getPostgresClient()\"), \" whenever you need to access the database and\\nyou'll be able to update the contents of your mounted volume whenever you need.\"), mdx(\"hr\", null), mdx(\"p\", null, \"Want to see the whole source? Check it out on GitHub:\"), mdx(\"button-link\", {\n    variant: \"outlined\",\n    color: \"primary\",\n    to: \"//github.com/architect-team/blog-examples/tree/master/mount-secrets-to-volumes\"\n  }, \"View source code\"));\n}\n;\nMDXContent.isMDXComponent = true;","excerpt":"In my prior posts, we've talked about  how to instrument credential cycling  and\n why it's important to enable application portability . In this post, we'll take\nthe notion of credential cycling even…","tableOfContents":{"items":[{"url":"#why-should-we-avoid-container-cycling","title":"Why should we avoid container cycling?"},{"url":"#reading-secrets-from-the-filesystem","title":"Reading secrets from the filesystem"}]},"frontmatter":{"title":"Cycling credentials without cycling containers","description":null,"author":"David Thor","date":"2020-07-30","image":null}},"next":null,"previous":null}]}},"pageContext":{"slug":"cycling-credentials-without-cycling-containers"}},
    "staticQueryHashes": ["764694655"]}