This module makes it easy to deploy an OpenVPN server in an auto-scaling group (size 1) for fault tolerance --along with the all the resources it typically needs:
The Auto-Scaling Group.
An EC2 Instance
An Elastic IP (EIP) address.
IAM Role and IAM instance profile.
Simple Queuing Services (SQS) Queues
An S3 Bucket for certificate backups
Security groups.
How do you use this module?
See the root README for instructions on using Terraform modules.
public_ip: The public IP address of the server (via its EIP)
How do I add custom security group rules?
One of the other important outputs of this module is the security_group_id, which is the id of the server's Security
Group. You can add custom rules to this Security Group using the aws_security_group_rule resource:
This module creates an IAM role for your EC2 instance and exports the id of that role as the output iam_role_id. You
can attach custom policies to this IAM role using the aws_iam_policy_attachment resource:
Build an AMI that has the duo_openvpn plugin installed. You can use install-openvpn to install the plugin
alongside openvpn by passing in the argument --duo-version. For example:
In the user_data script for the server, pass in the duo keys to init-openvpn using the arguments --duo-ikey,
--duo-skey, and --duo-host to configure the integration key, secret key, and API hostname respectively. You can
obtain these by following the Duo setup instructions for OpenVPN.
See the packer-duo and openvpn-host-duo examples for an
example configuration to deploy the OpenVPN server with Duo enabled.
Once the plugin is setup, all authentication for the client will result in a password prompt. To authenticate, you pass
in the MFA token in the password prompt, or push if you have push authentication enabled in duo. Note that in order
for 2FA to work, the certificate username (the value for --username when running openvpn-admin request) should
exactly match the duo username.
Questions? Ask away.
We're here to talk about our services, answer any questions, give advice, or just to chat.
{"treedata":{"name":"root","toggled":true,"children":[{"name":".circleci","children":[{"name":"config.yml","path":".circleci/config.yml","sha":"42f4ab347a72a6e29992a0ddd2b6d875725870d5"}]},{"name":".gitignore","path":".gitignore","sha":"e02f16ef8063fc8d9d24ad92b30536beb06aba44"},{"name":".pre-commit-config.yaml","path":".pre-commit-config.yaml","sha":"54c0821e8bc133285e4b99948cab34ee7088fd5b"},{"name":"CODEOWNERS","path":"CODEOWNERS","sha":"8c24c86ef8447a19436b38826f458c71b4da4f45"},{"name":"LICENSE.txt","path":"LICENSE.txt","sha":"5ae97660cb6e3a07b61c971f1a25edf402e90f53"},{"name":"README.md","path":"README.md","sha":"c52594e5506dad04dc5fc809114cd8daa4ab6c43"},{"name":"examples","children":[{"name":"openvpn-host-duo","children":[{"name":"README.md","path":"examples/openvpn-host-duo/README.md","sha":"1a3065f058745f0f03fd74844ac4e872d52538de"},{"name":"main.tf","path":"examples/openvpn-host-duo/main.tf","sha":"2a1a2329f41dfeddbdfa332aa3c6356d6b0ddf9f"},{"name":"outputs.tf","path":"examples/openvpn-host-duo/outputs.tf","sha":"f527145f657a5a99d32c301c591f461f2230e3b9"},{"name":"user-data","children":[{"name":"user-data.sh","path":"examples/openvpn-host-duo/user-data/user-data.sh","sha":"83cc9cc2145089141c3e7c58b3c930eeeb609c42"}]},{"name":"vars.tf","path":"examples/openvpn-host-duo/vars.tf","sha":"5d9d760ae9700c178ae6898e9e652b50ecfa92cc"}]},{"name":"openvpn-host","children":[{"name":"README.md","path":"examples/openvpn-host/README.md","sha":"debef80eecb3e988d1bee242f41659bb94f63a07"},{"name":"main.tf","path":"examples/openvpn-host/main.tf","sha":"a3fb3afa6cdd79ca9601191c08617fa2a7f85fbd"},{"name":"outputs.tf","path":"examples/openvpn-host/outputs.tf","sha":"f527145f657a5a99d32c301c591f461f2230e3b9"},{"name":"user-data","children":[{"name":"user-data.sh","path":"examples/openvpn-host/user-data/user-data.sh","sha":"04787c97e63d89c1ac32fb1f91f0398800f83074"}]},{"name":"vars.tf","path":"examples/openvpn-host/vars.tf","sha":"377921b5d6fb85a8151889d006fa54f990cfbd7d"}]},{"name":"packer-duo","children":[{"name":"README.md","path":"examples/packer-duo/README.md","sha":"d885b8114f2af50fb01d4707e56bb81ae79da798"},{"name":"build.json","path":"examples/packer-duo/build.json","sha":"f1fd5a46ffe031939dab1fd970f427943b764eee"}]},{"name":"packer","children":[{"name":"README.md","path":"examples/packer/README.md","sha":"de54777e323364919ee79bbf2f2c5d942de9e7dd"},{"name":"build.json","path":"examples/packer/build.json","sha":"b2c44e730438cd63b4597b7042b2cc78cda59c8f"}]}]},{"name":"modules","children":[{"name":"backup-openvpn-pki","children":[{"name":"README.md","path":"modules/backup-openvpn-pki/README.md","sha":"c853b20534e6e86c36074f55e1a29b98d9379800"},{"name":"bin","children":[{"name":"backup-openvpn-pki","path":"modules/backup-openvpn-pki/bin/backup-openvpn-pki","sha":"ac4b49684ea0dc776449f786473975fc98db79b5"}]},{"name":"install.sh","path":"modules/backup-openvpn-pki/install.sh","sha":"af225b1dcd43eaab802a9e8040b3d39e25dd46a0"}]},{"name":"init-openvpn","children":[{"name":"README.md","path":"modules/init-openvpn/README.md","sha":"5da988bb51256e80eed3a73208f21b0735e49dd5"},{"name":"bin","children":[{"name":"init-openvpn","path":"modules/init-openvpn/bin/init-openvpn","sha":"b89aec62eb75f4e7abdac7d5e50216ac696983d4"}]},{"name":"install.sh","path":"modules/init-openvpn/install.sh","sha":"9a41f990f62b2a9b526edfa813075cff277e1312"}]},{"name":"install-openvpn","children":[{"name":"README.md","path":"modules/install-openvpn/README.md","sha":"a1e6139f1a8d8fc12aafe41a348b258668010c91"},{"name":"bin","children":[{"name":"install-openvpn","path":"modules/install-openvpn/bin/install-openvpn","sha":"21816693acc9c1d2d0024c0845629421afe8b780"}]},{"name":"files","children":[{"name":"before.rules","path":"modules/install-openvpn/files/before.rules","sha":"e9f11106dda0d258910a36d88b3cac05c0d85146"},{"name":"openvpn-client.ovpn","path":"modules/install-openvpn/files/openvpn-client.ovpn","sha":"3fe8af5d74c724399d2b2acaaac3e5d07889912f"},{"name":"ufw-default","path":"modules/install-openvpn/files/ufw-default","sha":"ff5e7f69b1f65a2760579d4aa7575b278273e56b"},{"name":"vars.local","path":"modules/install-openvpn/files/vars.local","sha":"b19ce7da2758a7792a05d7563201127f8b1542c9"}]},{"name":"install.sh","path":"modules/install-openvpn/install.sh","sha":"65c8ed227131e94e7db76f47093f05b953950d07"},{"name":"scripts","children":[{"name":"generate-wrapper.sh","path":"modules/install-openvpn/scripts/generate-wrapper.sh","sha":"34d49724be9c3555a886d3cf00cf9cdbcb2a43bf"},{"name":"revoke-wrapper.sh","path":"modules/install-openvpn/scripts/revoke-wrapper.sh","sha":"d158a871cdd70cfed92418b6618d81c6bef08bd7"}]}]},{"name":"openvpn-admin","children":[{"name":".dockerignore","path":"modules/openvpn-admin/.dockerignore","sha":"a725465aee245635a2bd129af54858ed32c84cb8"},{"name":"Dockerfile","path":"modules/openvpn-admin/Dockerfile","sha":"e55bdd58b77185ca43d18487c5a0f55f0e7c8c4d"},{"name":"README.md","path":"modules/openvpn-admin/README.md","sha":"fc80a5b697339ea185030c46ac5916601b1dae1a"},{"name":"_ci","children":[{"name":"build-and-test.sh","path":"modules/openvpn-admin/_ci/build-and-test.sh","sha":"7b57f49d2a5cbce5f3e833c6e3dac767a90a92fa"},{"name":"test.sh","path":"modules/openvpn-admin/_ci/test.sh","sha":"ba48b9b10f31ca3f2e41ee3ce85e04d6ae289657"}]},{"name":"docker-compose.yml","path":"modules/openvpn-admin/docker-compose.yml","sha":"6c025d5d3a2b74cfb8f64bd822af25f7d5b1ddce"},{"name":"go.mod","path":"modules/openvpn-admin/go.mod","sha":"2beebe549f0709db70e4055469a537dbb704f8de"},{"name":"go.sum","path":"modules/openvpn-admin/go.sum","sha":"bccd39c716b788f56cfca70bb3e74a6e5f532678"},{"name":"openvpn-request-flow-diagram.svg","path":"modules/openvpn-admin/openvpn-request-flow-diagram.svg","sha":"4c170df3fd6cf76d4c8e0bed7e1f2dbd98c08942"},{"name":"openvpn-revoke-flow-diagram.svg","path":"modules/openvpn-admin/openvpn-revoke-flow-diagram.svg","sha":"488101bcb015fee6de88b69ad8291b8a8daaf2d4"},{"name":"scripts","children":[{"name":"build-linux-binary.sh","path":"modules/openvpn-admin/scripts/build-linux-binary.sh","sha":"3dfe844499b28878ebbb177453887bc786aec4de"},{"name":"run.sh","path":"modules/openvpn-admin/scripts/run.sh","sha":"bbcb7f9bdf8578561226954669cdb3e886093fcb"}]},{"name":"src","children":[{"name":"app","children":[{"name":"app.go","path":"modules/openvpn-admin/src/app/app.go","sha":"8accfb5682d91790c232b4383c1996cbbf377fe8"},{"name":"cert_helpers.go","path":"modules/openvpn-admin/src/app/cert_helpers.go","sha":"de91f4d887b08a1b2d1b3e0769c7ea43ccca796d"},{"name":"cmd_process_certificate_requests.go","path":"modules/openvpn-admin/src/app/cmd_process_certificate_requests.go","sha":"200937a37f7fdd6b0650a600d4264b294c24ecc1"},{"name":"cmd_process_certificate_revocation_requests.go","path":"modules/openvpn-admin/src/app/cmd_process_certificate_revocation_requests.go","sha":"28969a1664113f2d9b8e4c22fedac3c60b4c9fb1"},{"name":"cmd_request_new_certificate.go","path":"modules/openvpn-admin/src/app/cmd_request_new_certificate.go","sha":"d21a31e6e299c544f08799cb78c788ba14530fd3"},{"name":"cmd_revoke_certificate.go","path":"modules/openvpn-admin/src/app/cmd_revoke_certificate.go","sha":"fb1b44c449b9dc4b875d5ed72109f227cbca7071"},{"name":"common.go","path":"modules/openvpn-admin/src/app/common.go","sha":"e2bdf9b9b4338ae7764d986b39b7c2a26f811a30"},{"name":"flags.go","path":"modules/openvpn-admin/src/app/flags.go","sha":"e70ac21a257bdcd443d3e6020e796973553a36eb"}]},{"name":"aws_helpers","children":[{"name":"iam.go","path":"modules/openvpn-admin/src/aws_helpers/iam.go","sha":"b8977018784245fa75010b36cc5fa732c1768969"},{"name":"sqs.go","path":"modules/openvpn-admin/src/aws_helpers/sqs.go","sha":"4e5e86bdbdeaad3fbacf774cff5d52d74f4410ff"}]},{"name":"main.go","path":"modules/openvpn-admin/src/main.go","sha":"09f1ad6fc7b388e1d42fc4152b8dd840f6c05357"}]}]},{"name":"openvpn-server","children":[{"name":"README.md","path":"modules/openvpn-server/README.md","sha":"5059439e763295779f0ece5bbe8afaa52d533367","toggled":true},{"name":"main.tf","path":"modules/openvpn-server/main.tf","sha":"ec5313d533e5179707675c06cd4a0813ffbd9aee"},{"name":"outputs.tf","path":"modules/openvpn-server/outputs.tf","sha":"01795f8945ae5141df3b1ea54f79b4f22ae36a68"},{"name":"vars.tf","path":"modules/openvpn-server/vars.tf","sha":"dfdf42eefbd9ef702e06ad38a0287e0ac6809dc7"}],"toggled":true},{"name":"start-openvpn-admin","children":[{"name":"README.md","path":"modules/start-openvpn-admin/README.md","sha":"0c9902a49939a60e80a57fa0f39bfbb50eafd40a"},{"name":"bin","children":[{"name":"run-process-requests","path":"modules/start-openvpn-admin/bin/run-process-requests","sha":"6c8c52b3a6b6d58fd9cedfa40212071a27cc703c"},{"name":"run-process-revokes","path":"modules/start-openvpn-admin/bin/run-process-revokes","sha":"cffcbe2dcc9f16dd6989a68153e81edede8c0cb2"}]},{"name":"install.sh","path":"modules/start-openvpn-admin/install.sh","sha":"2af5af7f24c40136b22d50cb8cec47f7a9d2b2ac"}]}],"toggled":true},{"name":"test","children":[{"name":"README.md","path":"test/README.md","sha":"6c2e79488468f407d805afb5c83a41b523a16195"},{"name":"go.mod","path":"test/go.mod","sha":"76f9a862c7a47e5863026e6ea1a17cd095339896"},{"name":"go.sum","path":"test/go.sum","sha":"7ac28b8916052fca9d5254640ea7c5a8d0a0790e"},{"name":"local-test","children":[{"name":"docker-compose.yml","path":"test/local-test/docker-compose.yml","sha":"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"}]},{"name":"openvpn_test.go","path":"test/openvpn_test.go","sha":"105a43192e750fdacf16d8927fb08eda4ba87b41"}]}]},"detailsContent":"<h1 class=\"preview__body--title\" id=\"open-vpn-server-module\">OpenVPN Server Module</h1><div class=\"preview__body--border\"></div><p>This module makes it easy to deploy an OpenVPN server in an auto-scaling group (size 1) for fault tolerance --along with the all the resources it typically needs:</p>\n<ol>\n<li>The Auto-Scaling Group.</li>\n<li>An EC2 Instance</li>\n<li>An Elastic IP (EIP) address.</li>\n<li>IAM Role and IAM instance profile.</li>\n<li>Simple Queuing Services (SQS) Queues</li>\n<li>An S3 Bucket for certificate backups</li>\n<li>Security groups.</li>\n</ol>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-you-use-this-module\">How do you use this module?</h2>\n<ul>\n<li>See the <a href=\"/repos/v0.12.0/package-openvpn/README.md\" class=\"preview__body--description--blue\">root README</a> for instructions on using Terraform modules.</li>\n<li>See the <a href=\"/repos/v0.12.0/package-openvpn/examples\" class=\"preview__body--description--blue\">examples</a> folder for example usage.</li>\n<li>See <a href=\"/repos/v0.12.0/package-openvpn/modules/openvpn-server/vars.tf\" class=\"preview__body--description--blue\">vars.tf</a> for all the variables you can set on this module.</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-i-access-the-server\">How do I access the server?</h2>\n<p>This module include several <a href=\"https://www.terraform.io/intro/getting-started/outputs.html\" class=\"preview__body--description--blue\" target=\"_blank\">Terraform outputs</a>,\nincluding:</p>\n<ol>\n<li><code>public_ip</code>: The public IP address of the server (via its EIP)</li>\n</ol>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-i-add-custom-security-group-rules\">How do I add custom security group rules?</h2>\n<p>One of the other important outputs of this module is the <code>security_group_id</code>, which is the id of the server's Security\nGroup. You can add custom rules to this Security Group using the <code>aws_security_group_rule</code> resource:</p>\n<pre><span class=\"hljs-keyword\">module</span> <span class=\"hljs-string\">\"openvpn\"</span> {\n source = <span class=\"hljs-string\">\"git::git@github.com:gruntwork-io/package-openvpn.git//modules/openvpn-server?ref=v0.0.40\"</span>\n\n <span class=\"hljs-comment\"># (... options omitted...)</span>\n}\n\n<span class=\"hljs-comment\"># Custom rule to allow inbound HTTPS traffic from anywhere</span>\n<span class=\"hljs-keyword\">resource</span> <span class=\"hljs-string\">\"aws_security_group_rule\"</span> <span class=\"hljs-string\">\"allow_inbound_https_all\"</span> {\n type = <span class=\"hljs-string\">\"ingress\"</span>\n from_port = <span class=\"hljs-number\">443</span>\n to_port = <span class=\"hljs-number\">443</span>\n protocol = <span class=\"hljs-string\">\"tcp\"</span>\n cidr_blocks = [<span class=\"hljs-string\">\"0.0.0.0/0\"</span>]\n security_group_id = <span class=\"hljs-string\">\"<span class=\"hljs-variable\">${module.openvpn.security_group_id}</span>\"</span>\n}\n</pre>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-i-add-a-custom-iam-policy\">How do I add a custom IAM policy?</h2>\n<p>This module creates an IAM role for your EC2 instance and exports the id of that role as the output <code>iam_role_id</code>. You\ncan attach custom policies to this IAM role using the <code>aws_iam_policy_attachment</code> resource:</p>\n<pre>module <span class=\"hljs-string\">\"openvpn\"</span> {\n source = <span class=\"hljs-string\">\"git::git@github.com:gruntwork-io/package-openvpn.git//modules/openvpn-server?ref=v0.0.40\"</span>\n\n # (<span class=\"hljs-built_in\">..</span>. options omitted<span class=\"hljs-built_in\">..</span>.)\n}\n<span class=\"hljs-built_in\">\nresource </span><span class=\"hljs-string\">\"aws_iam_policy\"</span> <span class=\"hljs-string\">\"my_custom_policy\"</span> {\n name = <span class=\"hljs-string\">\"my-custom-policy\"</span>\n <span class=\"hljs-built_in\"> policy </span>= <span class=\"hljs-string\">\" (... omitted ...) \"</span>\n}\n<span class=\"hljs-built_in\">\nresource </span><span class=\"hljs-string\">\"aws_iam_policy_attachment\"</span> <span class=\"hljs-string\">\"attachment\"</span> {\n name = <span class=\"hljs-string\">\"example-attachment\"</span>\n roles = [<span class=\"hljs-string\">\"<span class=\"hljs-variable\">${module.openvpn.iam_role_id}</span>\"</span>]\n policy_arn = <span class=\"hljs-string\">\"<span class=\"hljs-variable\">${aws_iam_policy.my_custom_policy.arn}</span>\"</span>\n}\n</pre>\n<h2 class=\"preview__body--subtitle\" id=\"what-if-i-want-to-enable-mfa\">What if I want to enable MFA?</h2>\n<p>The scripts <a href=\"/repos/v0.12.0/package-openvpn/modules/init-openvpn\" class=\"preview__body--description--blue\">init-openvpn</a> and <a href=\"/repos/v0.12.0/package-openvpn/modules/install-openvpn\" class=\"preview__body--description--blue\">install-openvpn</a> support setting up the\n<a href=\"https://github.com/duosecurity/duo_openvpn\" class=\"preview__body--description--blue\" target=\"_blank\">duo_openvpn</a> plugin for 2FA authentication. To enable the duo plugin, you\nneed to:</p>\n<ol>\n<li>\n<p>Build an AMI that has the <code>duo_openvpn</code> plugin installed. You can use <code>install-openvpn</code> to install the plugin\nalongside openvpn by passing in the argument <code>--duo-version</code>. For example:</p>\n<p>sudo /usr/local/bin/install-openvpn --duo-version 2.2</p>\n</li>\n<li>\n<p>In the <code>user_data</code> script for the server, pass in the duo keys to <code>init-openvpn</code> using the arguments <code>--duo-ikey</code>,\n<code>--duo-skey</code>, and <code>--duo-host</code> to configure the integration key, secret key, and API hostname respectively. You can\nobtain these by following <a href=\"https://duo.com/docs/openvpn\" class=\"preview__body--description--blue\" target=\"_blank\">the Duo setup instructions for OpenVPN</a>.</p>\n</li>\n</ol>\n<p>See the <a href=\"/repos/v0.12.0/package-openvpn/modules/examples/packer-duo\" class=\"preview__body--description--blue\">packer-duo</a> and <a href=\"/repos/v0.12.0/package-openvpn/modules/examples/openvpn-host-duo\" class=\"preview__body--description--blue\">openvpn-host-duo</a> examples for an\nexample configuration to deploy the OpenVPN server with Duo enabled.</p>\n<p>Once the plugin is setup, all authentication for the client will result in a password prompt. To authenticate, you pass\nin the MFA token in the password prompt, or <code>push</code> if you have push authentication enabled in duo. Note that in order\nfor 2FA to work, the certificate username (the value for <code>--username</code> when running <code>openvpn-admin request</code>) should\nexactly match the duo username.</p>\n","repoName":"package-openvpn","repoRef":"v0.12.1","serviceDescriptor":{"serviceName":"OpenVPN","serviceRepoName":"package-openvpn","serviceRepoOrg":"gruntwork-io","cloudProviders":["aws"],"description":"Deploy an OpenVPN server. Supports auto healing, public key infrastructure (PKI), cert backup, and managing user accounts using IAM groups.","imageUrl":"openvpn.png","licenseType":"subscriber","technologies":["Terraform","Bash","Go"],"compliance":[],"tags":[""]},"serviceCategoryName":"Client VPN access","fileName":"README.md","filePath":"/modules/openvpn-server","title":"Repo Browser: OpenVPN","description":"Browse the repos in the Gruntwork Infrastructure as Code Library."}