{"action":"created","comment":{"url":"https://api.github.com/repos/codurance/site/pulls/comments/45368444","id":45368444,"diff_hunk":"@@ -0,0 +1,61 @@\n+---\n+layout: post\n+name: configuring-an-enterprise-app-sucks\n+title: 'Configuring an enterprise app sucks'\n+date: 2015-11-19 09:00:00 +00:00\n+author: David Hatanian\n+canonical:\n+    name: my personal blog\n+    href: https://david-codes.hatanian.com/post/2015/11/19/configuring-an-enterprise-app-sucks\n+image:\n+    src: /assets/img/custom/blog/2015-11-19-configuring-an-enterprise-app-sucks/asterix-and-obelix-passierschein38.jpg\n+---\n+\n+There has been quite a lot of discussion over the last years about how configuration should be managed as code, be it software settings or infrastructure configuration :\n+\n+ * For infrastructure, all the cool kids now use Docker, Vagrant or some other tool that allows you to store your infra's configuration as text files. You can find more on [this Thoughworks article](https://www.thoughtworks.com/insights/blog/infrastructure-code-reason-smile)\n+ * For software settings, it is now commonly accepted that anything that is not specific to the environment (secrets, IP addresses, ports) should be stored along with the code in the source code repository. Some teams even store environment-specific settings in the same repository.\n+\n+But when one configures an enterprise application, be it an open-source one or something purchased from a vendor, or even a Software As A Service solution, one is guaranteed to end up with all those levers, buttons and knobs to adjust and fiddle with. But that makes sense, enterprise applications need to be tweaked according to each company's specificities. So the best option is to shove all the configuration possibilities in an maze of screens, tabs, checkboxes and helpful tooltips, right ?\n+\n+I think that is wrong. This way of configuring software is a guarantee that something bad will happen at some point. Even collaboration tools such as Google Apps, who thrive on usability, provide administrators with overly complex settings options hidden deep withing a web interface. Identity and Access management tools such as OpenAM, IBM Tivoli Identity Manager and others suffer from the same plague.\n+\n+Here's what the advanced configuration screen for Google Apps looks like. All those tabs and options are only for the GMail section, which gives you an idea of the overall complexity :\n+\n+![Google Apps configuration screen](/assets/img/custom/blog/2015-11-19-configuring-an-enterprise-app-sucks/gmail.png \"Google Apps configuration screen\")\n+\n+And this how you configure a token-based authentication on OpenAM. An admin needs to go through dozens of those screens filled with fields and not make a single mistake. We are talking about an application that centralizes authentication, mistakes can make all the applications in your information system inaccessible :\n+\n+![OpenAM OATH configuration](/assets/img/custom/blog/2015-11-19-configuring-an-enterprise-app-sucks/openam.png \"OpenAM OATH configuration\")\n+\n+Those configuration screens are wrong on a lot of levels :\n+\n+ * **It is hard to look for a specific setting**. You often have to search several screens and sections, each of those potentially relevant to your subject. Some configuration interfaces provide a search tool to allow you to find the screen where you can configure a given setting, which gives you an idea of how hard it can be to navigate the interface in the first place.\n+ * **Keeping track of the changes performed on the configuration is complicated**. Any serious enterprise application will provide an audit track, unfortunately the track is usually a log of atomic events such as \"Administrator Michael changed setting X to value A\". There rarely is a way to have an overview of the complete configuration at the moment of this change. Did this change make sense at the time ? If some setting Y was dependent on the setting X, was Y also correctly set ?","path":"_posts/2015-11-19-configuring-an-enterprise-app-sucks.md","position":34,"original_position":34,"commit_id":"4bcc27b42b4440a19568ebdd5632496e483bb089","original_commit_id":"4bcc27b42b4440a19568ebdd5632496e483bb089","user":{"login":"franziskas","id":5154737,"avatar_url":"https://avatars.githubusercontent.com/u/5154737?v=3","gravatar_id":"","url":"https://api.github.com/users/franziskas","html_url":"https://github.com/franziskas","followers_url":"https://api.github.com/users/franziskas/followers","following_url":"https://api.github.com/users/franziskas/following{/other_user}","gists_url":"https://api.github.com/users/franziskas/gists{/gist_id}","starred_url":"https://api.github.com/users/franziskas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/franziskas/subscriptions","organizations_url":"https://api.github.com/users/franziskas/orgs","repos_url":"https://api.github.com/users/franziskas/repos","events_url":"https://api.github.com/users/franziskas/events{/privacy}","received_events_url":"https://api.github.com/users/franziskas/received_events","type":"User","site_admin":false},"body":"another plenk: ```time ?```","created_at":"2015-11-19T17:01:04Z","updated_at":"2015-11-19T17:01:04Z","html_url":"https://github.com/codurance/site/pull/74#discussion_r45368444","pull_request_url":"https://api.github.com/repos/codurance/site/pulls/74","_links":{"self":{"href":"https://api.github.com/repos/codurance/site/pulls/comments/45368444"},"html":{"href":"https://github.com/codurance/site/pull/74#discussion_r45368444"},"pull_request":{"href":"https://api.github.com/repos/codurance/site/pulls/74"}}},"pull_request":{"url":"https://api.github.com/repos/codurance/site/pulls/74","id":51246829,"html_url":"https://github.com/codurance/site/pull/74","diff_url":"https://github.com/codurance/site/pull/74.diff","patch_url":"https://github.com/codurance/site/pull/74.patch","issue_url":"https://api.github.com/repos/codurance/site/issues/74","number":74,"state":"open","locked":false,"title":"Configuring an enterprise app sucks","user":{"login":"dhatanian","id":1684420,"avatar_url":"https://avatars.githubusercontent.com/u/1684420?v=3","gravatar_id":"","url":"https://api.github.com/users/dhatanian","html_url":"https://github.com/dhatanian","followers_url":"https://api.github.com/users/dhatanian/followers","following_url":"https://api.github.com/users/dhatanian/following{/other_user}","gists_url":"https://api.github.com/users/dhatanian/gists{/gist_id}","starred_url":"https://api.github.com/users/dhatanian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dhatanian/subscriptions","organizations_url":"https://api.github.com/users/dhatanian/orgs","repos_url":"https://api.github.com/users/dhatanian/repos","events_url":"https://api.github.com/users/dhatanian/events{/privacy}","received_events_url":"https://api.github.com/users/dhatanian/received_events","type":"User","site_admin":false},"body":"This is a rant about how enterprise software vendors build complicated configuration interface and how tools such as source control can help improve it.","created_at":"2015-11-19T16:37:04Z","updated_at":"2015-11-19T17:01:04Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fdb2970809231e44cc18fe69175e80e83cbe9ea7","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/codurance/site/pulls/74/commits","review_comments_url":"https://api.github.com/repos/codurance/site/pulls/74/comments","review_comment_url":"https://api.github.com/repos/codurance/site/pulls/comments{/number}","comments_url":"https://api.github.com/repos/codurance/site/issues/74/comments","statuses_url":"https://api.github.com/repos/codurance/site/statuses/4bcc27b42b4440a19568ebdd5632496e483bb089","head":{"label":"codurance:configuration-as-code-in-saas-apps","ref":"configuration-as-code-in-saas-apps","sha":"4bcc27b42b4440a19568ebdd5632496e483bb089","user":{"login":"codurance","id":5751452,"avatar_url":"https://avatars.githubusercontent.com/u/5751452?v=3","gravatar_id":"","url":"https://api.github.com/users/codurance","html_url":"https://github.com/codurance","followers_url":"https://api.github.com/users/codurance/followers","following_url":"https://api.github.com/users/codurance/following{/other_user}","gists_url":"https://api.github.com/users/codurance/gists{/gist_id}","starred_url":"https://api.github.com/users/codurance/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codurance/subscriptions","organizations_url":"https://api.github.com/users/codurance/orgs","repos_url":"https://api.github.com/users/codurance/repos","events_url":"https://api.github.com/users/codurance/events{/privacy}","received_events_url":"https://api.github.com/users/codurance/received_events","type":"Organization","site_admin":false},"repo":{"id":38424930,"name":"site","full_name":"codurance/site","owner":{"login":"codurance","id":5751452,"avatar_url":"https://avatars.githubusercontent.com/u/5751452?v=3","gravatar_id":"","url":"https://api.github.com/users/codurance","html_url":"https://github.com/codurance","followers_url":"https://api.github.com/users/codurance/followers","following_url":"https://api.github.com/users/codurance/following{/other_user}","gists_url":"https://api.github.com/users/codurance/gists{/gist_id}","starred_url":"https://api.github.com/users/codurance/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codurance/subscriptions","organizations_url":"https://api.github.com/users/codurance/orgs","repos_url":"https://api.github.com/users/codurance/repos","events_url":"https://api.github.com/users/codurance/events{/privacy}","received_events_url":"https://api.github.com/users/codurance/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codurance/site","description":"","fork":false,"url":"https://api.github.com/repos/codurance/site","forks_url":"https://api.github.com/repos/codurance/site/forks","keys_url":"https://api.github.com/repos/codurance/site/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codurance/site/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codurance/site/teams","hooks_url":"https://api.github.com/repos/codurance/site/hooks","issue_events_url":"https://api.github.com/repos/codurance/site/issues/events{/number}","events_url":"https://api.github.com/repos/codurance/site/events","assignees_url":"https://api.github.com/repos/codurance/site/assignees{/user}","branches_url":"https://api.github.com/repos/codurance/site/branches{/branch}","tags_url":"https://api.github.com/repos/codurance/site/tags","blobs_url":"https://api.github.com/repos/codurance/site/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codurance/site/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codurance/site/git/refs{/sha}","trees_url":"https://api.github.com/repos/codurance/site/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codurance/site/statuses/{sha}","languages_url":"https://api.github.com/repos/codurance/site/languages","stargazers_url":"https://api.github.com/repos/codurance/site/stargazers","contributors_url":"https://api.github.com/repos/codurance/site/contributors","subscribers_url":"https://api.github.com/repos/codurance/site/subscribers","subscription_url":"https://api.github.com/repos/codurance/site/subscription","commits_url":"https://api.github.com/repos/codurance/site/commits{/sha}","git_commits_url":"https://api.github.com/repos/codurance/site/git/commits{/sha}","comments_url":"https://api.github.com/repos/codurance/site/comments{/number}","issue_comment_url":"https://api.github.com/repos/codurance/site/issues/comments{/number}","contents_url":"https://api.github.com/repos/codurance/site/contents/{+path}","compare_url":"https://api.github.com/repos/codurance/site/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codurance/site/merges","archive_url":"https://api.github.com/repos/codurance/site/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codurance/site/downloads","issues_url":"https://api.github.com/repos/codurance/site/issues{/number}","pulls_url":"https://api.github.com/repos/codurance/site/pulls{/number}","milestones_url":"https://api.github.com/repos/codurance/site/milestones{/number}","notifications_url":"https://api.github.com/repos/codurance/site/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codurance/site/labels{/name}","releases_url":"https://api.github.com/repos/codurance/site/releases{/id}","created_at":"2015-07-02T09:54:02Z","updated_at":"2015-07-02T09:55:20Z","pushed_at":"2015-11-19T16:55:57Z","git_url":"git://github.com/codurance/site.git","ssh_url":"git@github.com:codurance/site.git","clone_url":"https://github.com/codurance/site.git","svn_url":"https://github.com/codurance/site","homepage":null,"size":125587,"stargazers_count":0,"watchers_count":0,"language":"CSS","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2,"mirror_url":null,"open_issues_count":3,"forks":2,"open_issues":3,"watchers":0,"default_branch":"master"}},"base":{"label":"codurance:master","ref":"master","sha":"c563108fad6744c949dd71effb15b4d5cdfe703a","user":{"login":"codurance","id":5751452,"avatar_url":"https://avatars.githubusercontent.com/u/5751452?v=3","gravatar_id":"","url":"https://api.github.com/users/codurance","html_url":"https://github.com/codurance","followers_url":"https://api.github.com/users/codurance/followers","following_url":"https://api.github.com/users/codurance/following{/other_user}","gists_url":"https://api.github.com/users/codurance/gists{/gist_id}","starred_url":"https://api.github.com/users/codurance/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codurance/subscriptions","organizations_url":"https://api.github.com/users/codurance/orgs","repos_url":"https://api.github.com/users/codurance/repos","events_url":"https://api.github.com/users/codurance/events{/privacy}","received_events_url":"https://api.github.com/users/codurance/received_events","type":"Organization","site_admin":false},"repo":{"id":38424930,"name":"site","full_name":"codurance/site","owner":{"login":"codurance","id":5751452,"avatar_url":"https://avatars.githubusercontent.com/u/5751452?v=3","gravatar_id":"","url":"https://api.github.com/users/codurance","html_url":"https://github.com/codurance","followers_url":"https://api.github.com/users/codurance/followers","following_url":"https://api.github.com/users/codurance/following{/other_user}","gists_url":"https://api.github.com/users/codurance/gists{/gist_id}","starred_url":"https://api.github.com/users/codurance/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codurance/subscriptions","organizations_url":"https://api.github.com/users/codurance/orgs","repos_url":"https://api.github.com/users/codurance/repos","events_url":"https://api.github.com/users/codurance/events{/privacy}","received_events_url":"https://api.github.com/users/codurance/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codurance/site","description":"","fork":false,"url":"https://api.github.com/repos/codurance/site","forks_url":"https://api.github.com/repos/codurance/site/forks","keys_url":"https://api.github.com/repos/codurance/site/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codurance/site/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codurance/site/teams","hooks_url":"https://api.github.com/repos/codurance/site/hooks","issue_events_url":"https://api.github.com/repos/codurance/site/issues/events{/number}","events_url":"https://api.github.com/repos/codurance/site/events","assignees_url":"https://api.github.com/repos/codurance/site/assignees{/user}","branches_url":"https://api.github.com/repos/codurance/site/branches{/branch}","tags_url":"https://api.github.com/repos/codurance/site/tags","blobs_url":"https://api.github.com/repos/codurance/site/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codurance/site/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codurance/site/git/refs{/sha}","trees_url":"https://api.github.com/repos/codurance/site/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codurance/site/statuses/{sha}","languages_url":"https://api.github.com/repos/codurance/site/languages","stargazers_url":"https://api.github.com/repos/codurance/site/stargazers","contributors_url":"https://api.github.com/repos/codurance/site/contributors","subscribers_url":"https://api.github.com/repos/codurance/site/subscribers","subscription_url":"https://api.github.com/repos/codurance/site/subscription","commits_url":"https://api.github.com/repos/codurance/site/commits{/sha}","git_commits_url":"https://api.github.com/repos/codurance/site/git/commits{/sha}","comments_url":"https://api.github.com/repos/codurance/site/comments{/number}","issue_comment_url":"https://api.github.com/repos/codurance/site/issues/comments{/number}","contents_url":"https://api.github.com/repos/codurance/site/contents/{+path}","compare_url":"https://api.github.com/repos/codurance/site/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codurance/site/merges","archive_url":"https://api.github.com/repos/codurance/site/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codurance/site/downloads","issues_url":"https://api.github.com/repos/codurance/site/issues{/number}","pulls_url":"https://api.github.com/repos/codurance/site/pulls{/number}","milestones_url":"https://api.github.com/repos/codurance/site/milestones{/number}","notifications_url":"https://api.github.com/repos/codurance/site/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codurance/site/labels{/name}","releases_url":"https://api.github.com/repos/codurance/site/releases{/id}","created_at":"2015-07-02T09:54:02Z","updated_at":"2015-07-02T09:55:20Z","pushed_at":"2015-11-19T16:55:57Z","git_url":"git://github.com/codurance/site.git","ssh_url":"git@github.com:codurance/site.git","clone_url":"https://github.com/codurance/site.git","svn_url":"https://github.com/codurance/site","homepage":null,"size":125587,"stargazers_count":0,"watchers_count":0,"language":"CSS","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2,"mirror_url":null,"open_issues_count":3,"forks":2,"open_issues":3,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/codurance/site/pulls/74"},"html":{"href":"https://github.com/codurance/site/pull/74"},"issue":{"href":"https://api.github.com/repos/codurance/site/issues/74"},"comments":{"href":"https://api.github.com/repos/codurance/site/issues/74/comments"},"review_comments":{"href":"https://api.github.com/repos/codurance/site/pulls/74/comments"},"review_comment":{"href":"https://api.github.com/repos/codurance/site/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/codurance/site/pulls/74/commits"},"statuses":{"href":"https://api.github.com/repos/codurance/site/statuses/4bcc27b42b4440a19568ebdd5632496e483bb089"}}}}