├── .travis.yml ├── ECS_autoscaling_cluster.aws ├── LICENSE ├── README.md ├── README_TEMPLATE.md ├── awless_readonly_group.aws ├── awless_readonly_policies.aws ├── awless_readwrite_group.aws ├── classic_load_balancer.aws ├── cockroach_insecure_cluster_with_haproxy.draft ├── cockroachdb ├── README.md ├── cockroach_insecure_cluster.aws ├── cockroachdb-dashboard.png └── userdata │ ├── cockroach_insecure_node.sh │ └── joining_cockroach_insecure_node.sh ├── db_postgres.aws ├── dynamic_autoscaling_watching_CPU.aws ├── generate.go ├── highly_available_wordpress_infra.aws ├── install_awless_scheduler.aws ├── instance_ssh.aws ├── instance_with_awless.aws ├── instance_with_awless_scheduler.aws ├── instance_with_tags_and_publicip.aws ├── kafka_infra.aws ├── linux_bastion.aws ├── manifest.json ├── new_dbsubnetgroup.aws ├── policies_on_group.aws ├── public_subnet.aws ├── role_for_resource.aws ├── role_for_user.aws ├── s3website.aws ├── simple_wordpress_infra.aws ├── upload_image.aws ├── user.aws ├── userdata ├── install_awless.yml ├── install_awless_suite.yml ├── prepare_bastion.yml ├── redhat │ ├── kafka.sh │ └── zookeeper.sh ├── ubuntu │ ├── cockroach_haproxy.sh │ └── install_awless_scheduler.sh ├── wordpress-with-S3-plugin.sh └── wordpress.sh ├── verifyall_test.go ├── vpc.aws ├── vpc_with_subnets.aws ├── vuln_scanners ├── README.md ├── futurearchitect_vuls.aws └── userdata │ └── vuls_install.sh └── wordpress_ha.aws /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | install: 4 | go get github.com/wallix/awless 5 | 6 | go: 7 | - 1.8 8 | -------------------------------------------------------------------------------- /ECS_autoscaling_cluster.aws: -------------------------------------------------------------------------------- 1 | # Title: ECS Autoscaling Cluster 2 | # Tags: autoscaling, container, infra 3 | # Description: Note that the AMI in this template is working only in eu-west-1 region 4 | # MinimalVersion: v0.1.3 5 | 6 | # First, create the ECS cluster with `awless create containercluster name={cluster.name}`. 7 | 8 | 9 | # Then, create a policy to allow to connect to ECS 10 | policy = create policy name=AWSEC2ContainerServiceforEC2Role effect=Allow resource="*" description="Access for ECS containers" action=[ecs:DeregisterContainerInstance,ecs:DiscoverPollEndpoint,ecs:Poll,ecs:RegisterContainerInstance,ecs:StartTelemetrySession,ecs:Submit*,ecr:GetAuthorizationToken,ecr:BatchCheckLayerAvailability,ecr:GetDownloadUrlForLayer,ecr:BatchGetImage,logs:CreateLogStream,logs:PutLogEvent] 11 | 12 | # Set role name variable 13 | roleName = AWSEC2ContainerServiceRole 14 | 15 | # Create a AWS role that applies on a resource 16 | create role name=$roleName principal-service="ec2.amazonaws.com" sleep-after=15 17 | 18 | # Attach the policy to the role 19 | attach policy arn=$policy role=$roleName 20 | 21 | # Create the ECS instances launch configuration. 22 | # The instances must be launched with a userdata file containing: 23 | # ```sh 24 | # #!/bin/bash 25 | # echo ECS_CLUSTER=ecs-cluster-name >> /etc/ecs/ecs.config 26 | # ``` 27 | launchconfig = create launchconfiguration image=ami-95f8d2f3 keypair={instance.keypair} name=ECSClusterLaunchconfig type={instance.type} userdata={instance.userdata} role=$roleName 28 | 29 | # Create the scalinggroup 30 | create scalinggroup desired-capacity={scalinggroup.desired-capacity} launchconfiguration=$launchconfig max-size={scalinggroup.desired-capacity} min-size={scalinggroup.desired-capacity} name=ecsClusterScalingGroup subnets={instance.subnets} 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://api.travis-ci.org/wallix/awless-templates.svg?branch=master)](https://travis-ci.org/wallix/awless-templates) 2 | 3 | [Twitter](http://twitter.com/awlessCLI) | [Wiki](https://github.com/wallix/awless/wiki) | [Changelog](https://github.com/wallix/awless/blob/master/CHANGELOG.md#readme) 4 | 5 | # awless templates 6 | 7 | Repository to collect official, verified and runnable templates for the [awless CLI](https://github.com/wallix/awless) 8 | 9 | **You need at least awless version v0.1.3 to run those examples** 10 | 11 | Here are some non exhaustive [Examples](https://github.com/wallix/awless/wiki/Examples) of what you can do with templates. You can also read more about [awless templates](https://github.com/wallix/awless/wiki/Templates) 12 | 13 | ## Continuous Integration 14 | 15 | On each change all templates are verified & compiled against the latest version of `awless`. 16 | 17 | You can run the verification locally with: 18 | 19 | go get github.com/wallix/awless # if needed 20 | go test -v 21 | 22 | # Examples 23 | 24 | 25 | * [ECS Autoscaling Cluster](#ecs-autoscaling-cluster) 26 | * [Awless readonly group](#awless-readonly-group) 27 | * [Pre-defined policies for awless users](#pre-defined-policies-for-awless-users) 28 | * [Awless readwrite group](#awless-readwrite-group) 29 | * [Create a postgres instance](#create-a-postgres-instance) 30 | * [Group of instances scaling with CPU consumption](#group-of-instances-scaling-with-cpu-consumption) 31 | * [Highly-available wordpress infrastructure](#highly-available-wordpress-infrastructure) 32 | * [Install awless scheduler](#install-awless-scheduler) 33 | * [Create an instance accessible with ssh with a new keypair](#create-an-instance-accessible-with-ssh-with-a-new-keypair) 34 | * [Create an instance with preinstalled awless with completion](#create-an-instance-with-preinstalled-awless-with-completion) 35 | * [Create an instance with preconfigured awless and awless-scheduler](#create-an-instance-with-preconfigured-awless-and-awless-scheduler) 36 | * [Create an instance with tags and public IP](#create-an-instance-with-tags-and-public-ip) 37 | * [Create a classic Kafka infra](#create-a-classic-kafka-infra) 38 | * [Create VPC with a Linux host bastion](#create-vpc-with-a-linux-host-bastion) 39 | * [Create a dbsubnetgroups](#create-a-dbsubnetgroups) 40 | * [Attach usual readonly AWS policies (set of permissions) on group](#attach-usual-readonly-aws-policies-(set-of-permissions)-on-group) 41 | * [Create a public network enabling routing from the Internet](#create-a-public-network-enabling-routing-from-the-internet) 42 | * [Create a AWS role with usual readonly policies that applies on a resource](#create-a-aws-role-with-usual-readonly-policies-that-applies-on-a-resource) 43 | * [Create a AWS role with usual readonly policies that applies on a user](#create-a-aws-role-with-usual-readonly-policies-that-applies-on-a-user) 44 | * [Create a static website on S3](#create-a-static-website-on-s3) 45 | * [Simple wordpress deployment](#simple-wordpress-deployment) 46 | * [Upload Image from local file](#upload-image-from-local-file) 47 | * [Create a user with its SDK/Shell access key and console password](#create-a-user-with-its-sdk/shell-access-key-and-console-password) 48 | * [Create a VPC with its internet routing gateway](#create-a-vpc-with-its-internet-routing-gateway) 49 | * [Create a VPC with 3 internal subnets](#create-a-vpc-with-3-internal-subnets) 50 | * [Highly-available wordpress behind a loadbalancer, with a RDS database](#highly-available-wordpress-behind-a-loadbalancer,-with-a-rds-database) 51 | 52 | 53 | ### ECS Autoscaling Cluster 54 | 55 | 56 | **-> Minimal awless version required: v0.1.3** 57 | 58 | 59 | 60 | *Note that the AMI in this template is working only in eu-west-1 region* 61 | 62 | 63 | 64 | **tags**: 65 | autoscaling, container, infra 66 | 67 | 68 | (run it locally with: `awless run repo:ECS_autoscaling_cluster -v`) 69 | 70 | 71 | 72 | **STEPS** 73 | 74 | First, create the ECS cluster with `awless create containercluster name={cluster.name}`. 75 | Then, create a policy to allow to connect to ECS 76 | 77 | ```sh 78 | policy = create policy name=AWSEC2ContainerServiceforEC2Role effect=Allow resource="*" description="Access for ECS containers" action=[ecs:DeregisterContainerInstance,ecs:DiscoverPollEndpoint,ecs:Poll,ecs:RegisterContainerInstance,ecs:StartTelemetrySession,ecs:Submit*,ecr:GetAuthorizationToken,ecr:BatchCheckLayerAvailability,ecr:GetDownloadUrlForLayer,ecr:BatchGetImage,logs:CreateLogStream,logs:PutLogEvent] 79 | 80 | ``` 81 | Set role name variable 82 | 83 | ```sh 84 | roleName = AWSEC2ContainerServiceRole 85 | 86 | ``` 87 | Create a AWS role that applies on a resource 88 | 89 | ```sh 90 | create role name=$roleName principal-service="ec2.amazonaws.com" sleep-after=15 91 | 92 | ``` 93 | Attach the policy to the role 94 | 95 | ```sh 96 | attach policy arn=$policy role=$roleName 97 | 98 | ``` 99 | Create the ECS instances launch configuration. 100 | The instances must be launched with a userdata file containing: 101 | ```sh 102 | !/bin/bash 103 | echo ECS_CLUSTER=ecs-cluster-name >> /etc/ecs/ecs.config 104 | ``` 105 | 106 | ```sh 107 | launchconfig = create launchconfiguration image=ami-95f8d2f3 keypair={instance.keypair} name=ECSClusterLaunchconfig type={instance.type} userdata={instance.userdata} role=$roleName 108 | 109 | ``` 110 | Create the scalinggroup 111 | 112 | ```sh 113 | create scalinggroup desired-capacity={scalinggroup.desired-capacity} launchconfiguration=$launchconfig max-size={scalinggroup.desired-capacity} min-size={scalinggroup.desired-capacity} name=ecsClusterScalingGroup subnets={instance.subnets} 114 | ``` 115 | 116 | 117 | 118 | ### Awless readonly group 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | (run it locally with: `awless run repo:awless_readonly_group -v`) 127 | 128 | 129 | 130 | **STEPS** 131 | 132 | Here we define a group that allow users in that group 133 | to use the `awless` CLI in a readonly mode (i.e. sync, listing). 134 | 135 | Create group name variable: 136 | 137 | ```sh 138 | groupName = AwlessReadOnlyPermissionsGroup 139 | 140 | ``` 141 | Create the group: 142 | 143 | ```sh 144 | create group name=$groupName 145 | 146 | ``` 147 | Attach corresponding readonly AWS policies (set of permissions) on group related to the `awless` services: 148 | 149 | ```sh 150 | attach policy arn=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess group=$groupName 151 | attach policy arn=arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess group=$groupName 152 | attach policy arn=arn:aws:iam::aws:policy/AmazonSNSReadOnlyAccess group=$groupName 153 | attach policy arn=arn:aws:iam::aws:policy/AmazonSQSReadOnlyAccess group=$groupName 154 | attach policy arn=arn:aws:iam::aws:policy/AmazonVPCReadOnlyAccess group=$groupName 155 | attach policy arn=arn:aws:iam::aws:policy/AutoScalingReadOnlyAccess group=$groupName 156 | attach policy arn=arn:aws:iam::aws:policy/IAMReadOnlyAccess group=$groupName 157 | attach policy arn=arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess group=$groupName 158 | attach policy arn=arn:aws:iam::aws:policy/AmazonRoute53ReadOnlyAccess group=$groupName 159 | attach policy arn=arn:aws:iam::aws:policy/AWSLambdaReadOnlyAccess group=$groupName 160 | ``` 161 | 162 | 163 | 164 | ### Pre-defined policies for awless users 165 | 166 | 167 | **-> Minimal awless version required: v0.1.3** 168 | 169 | 170 | 171 | *Useful pre-defined readonly & readwrite policies for awless users* 172 | 173 | 174 | 175 | 176 | (run it locally with: `awless run repo:awless_readonly_policies -v`) 177 | 178 | 179 | 180 | **STEPS** 181 | 182 | Infra resources 183 | 184 | ```sh 185 | create policy name=AwlessInfraReadonlyPolicy effect=Allow resource="*" description="Readonly access to infra resources" action=[ec2:Describe*,autoscaling:Describe*,elasticloadbalancing:Describe*] 186 | 187 | ``` 188 | Access resources 189 | 190 | ```sh 191 | create policy name=AwlessAccessReadonlyPolicy effect=Allow resource="*" description="Readonly access to access resources" action=[iam:GenerateCredentialReport,iam:GenerateServiceLastAccessedDetails,iam:Get*,iam:List*,sts:Get*] 192 | 193 | ``` 194 | Storage resources 195 | 196 | ```sh 197 | create policy name=AwlessStorageReadonlyPolicy effect=Allow resource="*" description="Readonly access to storage resources" action=[s3:Get*,s3:List*] 198 | 199 | ``` 200 | Messaging resources 201 | 202 | ```sh 203 | create policy name=AwlessMessagingReadonlyPolicy effect=Allow resource="*" description="Readonly access to notification and queueing for messaging resources" action=[sns:GetTopicAttributes,sns:List*,sqs:GetQueueAttributes,sqs:ListQueues] 204 | 205 | ``` 206 | Lambda resources 207 | 208 | ```sh 209 | create policy name=AwlessLambdaReadonlyPolicy effect=Allow resource="*" description="Readonly access to lambda resources" action=[cloudwatch:Describe*,cloudwatch:Get*,cloudwatch:List*,cognito-identity:ListIdentityPools,cognito-sync:GetCognitoEvents,dynamodb:BatchGetItem,dynamodb:DescribeStream,dynamodb:DescribeTable,dynamodb:GetItem,dynamodb:ListStreams,dynamodb:ListTables,dynamodb:Query,dynamodb:Scan,events:List*,events:Describe*,iam:ListRoles,kinesis:DescribeStream,kinesis:ListStreams,lambda:List*,lambda:Get*,logs:DescribeMetricFilters,logs:GetLogEvents,logs:DescribeLogGroups,logs:DescribeLogStreams,s3:Get*,s3:List*,sns:ListTopics,sns:ListSubscriptions,sns:ListSubscriptionsByTopic,sqs:ListQueues,tag:GetResources,kms:ListAliases,ec2:DescribeVpcs,ec2:DescribeSubnets,ec2:DescribeSecurityGroups,iot:GetTopicRules,iot:ListTopicRules,iot:ListPolicies,iot:ListThings,iot:DescribeEndpoint] 210 | 211 | ``` 212 | DNS resources 213 | 214 | ```sh 215 | create policy name=AwlessDNSReadonlyPolicy effect=Allow resource="*" description="Readonly access to DNS resources" action=[route53:Get*,route53:List*,route53:TestDNSAnswer,route53domains:Get*,route53domains:List*] 216 | 217 | ``` 218 | Monitoring resources 219 | 220 | ```sh 221 | create policy name=AwlessMonitoringReadonlyPolicy effect=Allow resource="*" description="Readonly access to monitoring resources" action=[autoscaling:Describe*,cloudwatch:Describe*,cloudwatch:Get*,cloudwatch:List*,logs:Get*,logs:Describe*,logs:TestMetricFilter,sns:Get*,sns:List*] 222 | 223 | ``` 224 | CDN resources 225 | 226 | ```sh 227 | create policy name=AwlessCDNReadonlyPolicy effect=Allow resource="*" description="Readonly access to CDN resources" action=[acm:ListCertificates,cloudfront:Get*,cloudfront:List*,iam:ListServerCertificates,route53:List*,waf:ListWebACLs,waf:GetWebACL] 228 | 229 | ``` 230 | Cloud formation resources 231 | 232 | ```sh 233 | create policy name=AwlessCloudFormationReadonlyPolicy effect=Allow resource="*" description="Readonly access to CloudFormation resources" action=[cloudformation:DescribeStacks,cloudformation:DescribeStackEvents,cloudformation:DescribeStackResource,cloudformation:DescribeStackResources,cloudformation:GetTemplate,cloudformation:List*] 234 | ``` 235 | 236 | 237 | 238 | ### Awless readwrite group 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | (run it locally with: `awless run repo:awless_readwrite_group -v`) 247 | 248 | 249 | 250 | **STEPS** 251 | 252 | Here we define a group that allow users in that group to use the `awless` CLI in write mode. 253 | 254 | Create group name variable: 255 | 256 | ```sh 257 | groupName = AwlessReadWritePermissionsGroup 258 | 259 | ``` 260 | Create the group: 261 | 262 | ```sh 263 | create group name=$groupName 264 | 265 | ``` 266 | Attach corresponding AWS policies (set of permissions) on group related to the `awless` services: 267 | 268 | ```sh 269 | attach policy arn=arn:aws:iam::aws:policy/AmazonEC2FullAccess group=$groupName 270 | attach policy arn=arn:aws:iam::aws:policy/AmazonS3FullAccess group=$groupName 271 | attach policy arn=arn:aws:iam::aws:policy/AmazonSNSFullAccess group=$groupName 272 | attach policy arn=arn:aws:iam::aws:policy/AmazonSQSFullAccess group=$groupName 273 | attach policy arn=arn:aws:iam::aws:policy/AmazonVPCFullAccess group=$groupName 274 | attach policy arn=arn:aws:iam::aws:policy/AutoScalingFullAccess group=$groupName 275 | attach policy arn=arn:aws:iam::aws:policy/AmazonRDSFullAccess group=$groupName 276 | attach policy arn=arn:aws:iam::aws:policy/AmazonRoute53FullAccess group=$groupName 277 | attach policy arn=arn:aws:iam::aws:policy/AWSLambdaFullAccess group=$groupName 278 | 279 | ``` 280 | Note that we keep the IAM access readonly 281 | 282 | ```sh 283 | attach policy arn=arn:aws:iam::aws:policy/IAMReadOnlyAccess group=$groupName 284 | ``` 285 | 286 | 287 | 288 | ### Create a postgres instance 289 | 290 | 291 | **-> Minimal awless version required: v0.1.7** 292 | 293 | 294 | 295 | *Create a private basic postgres instance with firewall. As an example, instance has only basic required properties filled in* 296 | 297 | 298 | 299 | 300 | (run it locally with: `awless run repo:db_postgres -v`) 301 | 302 | 303 | 304 | **STEPS** 305 | 306 | Create a new VPC open to Internet to host the subnets 307 | 308 | ```sh 309 | vpc = create vpc cidr=10.0.0.0/16 name=postgres-vpc 310 | gateway = create internetgateway 311 | attach internetgateway id=$gateway vpc=$vpc 312 | 313 | ``` 314 | Create a route table for this network 315 | 316 | ```sh 317 | rtable = create routetable vpc=$vpc 318 | 319 | ``` 320 | Enable routing from the Internet 321 | 322 | ```sh 323 | create route cidr=0.0.0.0/0 gateway=$gateway table=$rtable 324 | 325 | ``` 326 | One public subnet to later deploy or host public applications or a bastion to access your private DBs 327 | 328 | ```sh 329 | pubsubnet = create subnet cidr=10.0.128.0/20 vpc=$vpc name=public-subnet 330 | update subnet id=$pubsubnet public=true 331 | 332 | ``` 333 | Make the public subnet open to the Internet (through vpc that has an internetgateway) 334 | 335 | ```sh 336 | attach routetable id=$rtable subnet=$pubsubnet 337 | 338 | ``` 339 | Two private subnet to constitute the dbsubnetgroup hosting the DB 340 | 341 | ```sh 342 | privsubnet1 = create subnet cidr=10.0.0.0/19 vpc=$vpc name=postgres-priv-subnet1 availabilityzone={availabilityzone.1} 343 | privsubnet2 = create subnet cidr=10.0.32.0/19 vpc=$vpc name=postgres-priv-subnet2 availabilityzone={availabilityzone.2} 344 | subnetgroup = create dbsubnetgroup subnets=[$privsubnet1, $privsubnet2] name=PostgresDBSubnetGroup description="DB subnet group hosting postgres instances" 345 | 346 | ``` 347 | Firewall for the postgres instance 348 | 349 | ```sh 350 | postgres_sg = create securitygroup name=postgres description='Postgres firewall access' vpc=$vpc 351 | update securitygroup id=$postgres_sg inbound=authorize protocol=tcp portrange=5432 cidr=10.0.0.0/16 352 | 353 | ``` 354 | Create the database and connect to it through: `psql --host=? --port=5432 --username=? --password --dbname=?` 355 | 356 | ```sh 357 | create database engine=postgres id={database.identifier} subnetgroup=$subnetgroup password={password.minimum8chars} dbname={database.name} size=5 type=db.t2.small username={database.username} vpcsecuritygroups=$postgres_sg 358 | 359 | ``` 360 | Create a small jump instance in your public subnet to run command on your postgres DB 361 | and give SSH access to this instance with a SSH security group 362 | Run the CLI with: awless .... office.ip=$(awless whoami --ip-only) 363 | 364 | ```sh 365 | sshsecgroup = create securitygroup vpc=$vpc description="SSH access from office IP only" name=ssh-from-office 366 | update securitygroup id=$sshsecgroup inbound=authorize protocol=tcp cidr={office.ip}/32 portrange=22 367 | create instance distro=debian keypair={my.keypair} name=jump subnet=$pubsubnet securitygroup=$sshsecgroup type=t2.micro 368 | 369 | ``` 370 | Then to administrate your DB you can do: 371 | $ HOST=$(awless show production --values-for PublicDNS --local) 372 | $ awless ssh jump 373 | $ sudo apt-get update; sudo apt-get install -y postgresql-client-9.4 374 | $ psql --host={VALUE FROM HOST ABOVE} --port=5432 --username=... --password --dbname=... 375 | 376 | 377 | 378 | ### Group of instances scaling with CPU consumption 379 | 380 | 381 | 382 | 383 | *Create an autoscaling group of instances and watch their CPU to dynamically allocate/delete instances when needed.* 384 | 385 | 386 | 387 | **tags**: 388 | infra, autoscaling 389 | 390 | 391 | (run it locally with: `awless run repo:dynamic_autoscaling_watching_CPU -v`) 392 | 393 | 394 | 395 | **STEPS** 396 | 397 | Create the instances launch configuration 398 | 399 | ```sh 400 | launchconfig = create launchconfiguration image={instance.image} keypair={instance.keypair} name=scalingLaunchConf type={instance.type} 401 | 402 | ``` 403 | Create the scalinggroup 404 | 405 | ```sh 406 | create scalinggroup desired-capacity=2 launchconfiguration=$launchconfig max-size={instance.max-number} min-size={instance.min-number} name=instancesScalingGroup subnets={instance.subnets} 407 | 408 | ``` 409 | Create a scaling policy to add instances (scale-in) and a scaling policy to remove instances (scale-out) 410 | 411 | ```sh 412 | adjustmentType = ChangeInCapacity 413 | scalein = create scalingpolicy adjustment-scaling=1 adjustment-type=$adjustmentType name=policy-scaling-in scalinggroup=instancesScalingGroup 414 | scaleout = create scalingpolicy adjustment-scaling=-1 adjustment-type=$adjustmentType name=policy-step-scaling-2 scalinggroup=instancesScalingGroup 415 | 416 | ``` 417 | metrics statistic functions 418 | 419 | ```sh 420 | statFunction = Average 421 | alarmThreshold = 75 422 | monitoredMetric = CPUUtilization 423 | 424 | ``` 425 | Add a monitoring alarm to enable scalein when CPU load is above 75% during 2 * 5 min 426 | 427 | ```sh 428 | create alarm namespace=AWS/EC2 dimensions=AutoScalingGroupName:instancesScalingGroup evaluation-periods=2 metric=$monitoredMetric name=scaleinAlarm operator=GreaterThanOrEqualToThreshold period=300 statistic-function=$statFunction threshold=$alarmThreshold 429 | attach alarm name=scaleinAlarm action-arn=$scalein 430 | 431 | ``` 432 | Add a monitoring alarm to enable scaleout when CPU load is below 75% during 2 * 5 min 433 | 434 | ```sh 435 | create alarm namespace=AWS/EC2 dimensions=AutoScalingGroupName:instancesScalingGroup evaluation-periods=2 metric=$monitoredMetric name=scaleoutAlarm operator=LessThanOrEqualToThreshold period=300 statistic-function=$statFunction threshold=$alarmThreshold 436 | attach alarm name=scaleoutAlarm action-arn=$scaleout 437 | ``` 438 | 439 | 440 | 441 | ### Highly-available wordpress infrastructure 442 | 443 | 444 | **-> Minimal awless version required: v0.1.7** 445 | 446 | 447 | 448 | 449 | 450 | **tags**: 451 | infra 452 | 453 | 454 | (run it locally with: `awless run repo:highly_available_wordpress_infra -v`) 455 | 456 | 457 | 458 | **STEPS** 459 | 460 | 1. Basic networking 461 | VPC and its Internet gateway 462 | 463 | ```sh 464 | vpc = create vpc cidr=10.0.0.0/16 name=wordpress-ha-vpc 465 | igw = create internetgateway 466 | attach internetgateway id=$igw vpc=$vpc 467 | pubSub1 = create subnet cidr=10.0.100.0/24 vpc=$vpc name=wordpress-ha-public-subnet-1 availabilityzone={availabilityzone.1} 468 | update subnet id=$pubSub1 public=true 469 | pubSub2 = create subnet cidr=10.0.101.0/24 vpc=$vpc name=wordpress-ha-public-subnet-2 availabilityzone={availabilityzone.2} 470 | update subnet id=$pubSub2 public=true 471 | rt = create routetable vpc=$vpc 472 | create route table=$rt cidr=0.0.0.0/0 gateway=$igw 473 | attach routetable id=$rt subnet=$pubSub1 474 | attach routetable id=$rt subnet=$pubSub2 475 | 476 | ``` 477 | 2 private subnets in different AZs 478 | 479 | ```sh 480 | privSub1 = create subnet cidr=10.0.10.0/24 vpc=$vpc name=wordpress-ha-private-subnet-1 availabilityzone={availabilityzone.1} 481 | privSub2 = create subnet cidr=10.0.11.0/24 vpc=$vpc name=wordpress-ha-private-subnet-2 availabilityzone={availabilityzone.2} 482 | 483 | ``` 484 | NAT Gateway in public subnet with a fixed IP 485 | 486 | ```sh 487 | ip = create elasticip 488 | natgw = create natgateway elasticip-id=$ip subnet=$pubSub1 489 | check natgateway id=$natgw state=available timeout=180 490 | 491 | ``` 492 | Routing between private subnets and NAT gateway 493 | 494 | ```sh 495 | natgw_rtable = create routetable vpc=$vpc 496 | attach routetable id=$natgw_rtable subnet=$privSub1 497 | attach routetable id=$natgw_rtable subnet=$privSub2 498 | create route cidr=0.0.0.0/0 gateway=$natgw table=$natgw_rtable 499 | 500 | ``` 501 | 2. Provision loadbalancer 502 | Create the load balancer security group 503 | 504 | ```sh 505 | lbsecgroup = create securitygroup vpc=$vpc description="authorize HTTP from the internet" name=wordpress-ha-lb-securitygroup 506 | update securitygroup id=$lbsecgroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=80 507 | 508 | ``` 509 | Provision the load balancer listening in the public subnets, with its target group and HTTP listener 510 | 511 | ```sh 512 | tg = create targetgroup name=wordpress-ha-workers port=80 protocol=HTTP vpc=$vpc 513 | update targetgroup id=$tg stickiness=true 514 | lb = create loadbalancer name=wordpress-ha-loadbalancer subnets=[$pubSub1,$pubSub2] securitygroups=$lbsecgroup 515 | create listener actiontype=forward loadbalancer=$lb port=80 protocol=HTTP targetgroup=$tg 516 | 517 | ``` 518 | 3. Provision instances 519 | Create keypair and instance 520 | 521 | ```sh 522 | keypair = create keypair name={keypair.name} 523 | instSecGroup = create securitygroup vpc=$vpc description="HTTP + SSH within VPC" name=wordpress-ha-private-secgroup 524 | update securitygroup id=$instSecGroup inbound=authorize cidr=10.0.0.0/16 portrange=22 525 | update securitygroup id=$instSecGroup inbound=authorize cidr=10.0.0.0/16 portrange=80 526 | launchconf = create launchconfiguration distro=amazonlinux keypair=$keypair name=wordpress-ha-launch-configuration type={instance.type} userdata=https://raw.githubusercontent.com/zn3zman/AWS-WordPress-Creation/master/WP-Setup.sh securitygroups=$instSecGroup 527 | create scalinggroup desired-capacity=2 launchconfiguration=$launchconf max-size=2 min-size=2 name=wordpress-scalinggroup subnets=[$privSub1, $privSub2] targetgroups=$tg 528 | ``` 529 | 530 | 531 | 532 | ### Install awless scheduler 533 | 534 | 535 | **-> Minimal awless version required: v0.1.7** 536 | 537 | 538 | 539 | 540 | 541 | 542 | (run it locally with: `awless run repo:install_awless_scheduler -v`) 543 | 544 | 545 | *Full CLI example:* 546 | ```sh 547 | awless run repo:install_awless_scheduler 548 | ``` 549 | 550 | 551 | **STEPS** 552 | 553 | Launch new instance running remote user data script installing awless 554 | 555 | ```sh 556 | create instance name={instance.name} distro=canonical:ubuntu type=t2.nano keypair={ssh.keypair} userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/ubuntu/install_awless_scheduler.sh role={role.name} 557 | ``` 558 | 559 | 560 | 561 | ### Create an instance accessible with ssh with a new keypair 562 | 563 | 564 | 565 | 566 | 567 | 568 | **tags**: 569 | infra, ssh 570 | 571 | 572 | (run it locally with: `awless run repo:instance_ssh -v`) 573 | 574 | 575 | 576 | **STEPS** 577 | 578 | Create a new security group for this instance 579 | 580 | ```sh 581 | securitygroup = create securitygroup vpc={instance.vpc} description={securitygroup.description} name=ssh-from-internet 582 | 583 | ``` 584 | Authorize access on port 22 to instances in this security group 585 | 586 | ```sh 587 | update securitygroup id=$securitygroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=22 588 | 589 | ``` 590 | Create a new keypair 591 | 592 | ```sh 593 | keypair = create keypair name={keypair.name} 594 | 595 | ``` 596 | Create an instance in this security group accessible with the new keypair 597 | 598 | ```sh 599 | create instance subnet={instance.subnet} image={instance.image} type={instance.type} keypair=$keypair name={instance.name} count=1 securitygroup=$securitygroup 600 | ``` 601 | 602 | 603 | 604 | ### Create an instance with preinstalled awless with completion 605 | 606 | 607 | 608 | 609 | 610 | 611 | **tags**: 612 | infra, awless 613 | 614 | 615 | (run it locally with: `awless run repo:instance_with_awless -v`) 616 | 617 | 618 | 619 | **STEPS** 620 | 621 | role name variable 622 | 623 | ```sh 624 | roleName = {awless.role-name} 625 | 626 | ``` 627 | Create a AWS role that applies on a resource 628 | 629 | ```sh 630 | create role name=$roleName principal-service="ec2.amazonaws.com" sleep-after=10 631 | 632 | ``` 633 | Attach typical necessary awless readonly permissions to the role 634 | 635 | ```sh 636 | attach policy role=$roleName service=ec2 access=readonly 637 | attach policy role=$roleName service=s3 access=readonly 638 | attach policy role=$roleName service=sns access=readonly 639 | attach policy role=$roleName service=sqs access=readonly 640 | attach policy role=$roleName service=vpc access=readonly 641 | attach policy role=$roleName service=autoscaling access=readonly 642 | attach policy role=$roleName service=iam access=readonly 643 | attach policy role=$roleName service=rds access=readonly 644 | attach policy role=$roleName service=route53 access=readonly 645 | attach policy role=$roleName service=lambda access=readonly 646 | 647 | ``` 648 | Launch new instance running remote user data script installing awless 649 | 650 | ```sh 651 | create instance name=awless-commander type=t2.nano keypair={ssh.keypair} userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/install_awless.yml role=$roleName 652 | ``` 653 | 654 | 655 | 656 | ### Create an instance with preconfigured awless and awless-scheduler 657 | 658 | 659 | 660 | 661 | 662 | 663 | **tags**: 664 | infra, awless, awless-scheduler 665 | 666 | 667 | (run it locally with: `awless run repo:instance_with_awless_scheduler -v`) 668 | 669 | 670 | 671 | **STEPS** 672 | 673 | Awless scheduler role variable 674 | 675 | ```sh 676 | roleName = {awless-scheduler.role-name} 677 | 678 | ``` 679 | First we define a role that an EC2 instance can assume to use awless/awless-scheduler (write mode) 680 | 681 | ```sh 682 | create role name=$roleName principal-service="ec2.amazonaws.com" sleep-after=10 683 | 684 | ``` 685 | Attach typical necessary awless permissions to the role 686 | 687 | ```sh 688 | attach policy role=$roleName service=ec2 access=full 689 | attach policy role=$roleName service=s3 access=full 690 | attach policy role=$roleName service=sns access=full 691 | attach policy role=$roleName service=sqs access=full 692 | attach policy role=$roleName service=vpc access=full 693 | attach policy role=$roleName service=autoscaling access=full 694 | attach policy role=$roleName service=rds access=full 695 | attach policy role=$roleName service=route53 access=full 696 | attach policy role=$roleName service=lambda access=full 697 | 698 | ``` 699 | We keep IAM on read only mode 700 | 701 | ```sh 702 | attach policy role=$roleName service=iam access=readonly 703 | 704 | ``` 705 | Launch new instance running remote user data script installing awless 706 | 707 | ```sh 708 | create instance name=AwlessWithScheduler type=t2.nano keypair={ssh.keypair} userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/install_awless_suite.yml role=$roleName 709 | ``` 710 | 711 | 712 | 713 | ### Create an instance with tags and public IP 714 | 715 | 716 | 717 | 718 | *Create an instance with mulitple tags and attach to it an elastic IP* 719 | 720 | 721 | 722 | 723 | (run it locally with: `awless run repo:instance_with_tags_and_publicip -v`) 724 | 725 | 726 | 727 | **STEPS** 728 | 729 | 730 | ```sh 731 | inst = create instance subnet={instance.subnet} image={instance.image} type={instance.type} keypair={instance.keypair} name={instance.name} securitygroup={instance.securitygroup} 732 | 733 | ``` 734 | Putting a tag on the instance 735 | 736 | ```sh 737 | create tag resource=$inst key={instance.tagkey} value={instance.tagvalue} 738 | 739 | ``` 740 | Creating a elastic IP 741 | 742 | ```sh 743 | pubip = create elasticip domain=vpc 744 | 745 | ``` 746 | Attaching the IP onto the instance 747 | 748 | ```sh 749 | attach elasticip id=$pubip instance=$inst 750 | ``` 751 | 752 | 753 | 754 | ### Create a classic Kafka infra 755 | 756 | 757 | **-> Minimal awless version required: v0.1.7** 758 | 759 | 760 | 761 | *Create a classic Kafka infra: brokers, 1 zookeeper instance* 762 | 763 | 764 | 765 | 766 | (run it locally with: `awless run repo:kafka_infra -v`) 767 | 768 | 769 | *Full CLI example:* 770 | ```sh 771 | awless run repo:kafka_infra remote-access.cidr=$(awless whoami --ip-only)/32 broker.instance.type=t2.medium zookeeper.instance.type=t2.medium 772 | ``` 773 | 774 | 775 | **STEPS** 776 | 777 | Create the VPC and its internet gateway 778 | 779 | ```sh 780 | vpc = create vpc cidr=10.0.0.0/16 name=kafka-vpc 781 | igw = create internetgateway 782 | attach internetgateway id=$igw vpc=$vpc 783 | 784 | ``` 785 | Create a public subnet 786 | 787 | ```sh 788 | subnet_cidr = 10.0.0.0/24 789 | subnet = create subnet cidr=$subnet_cidr vpc=$vpc name=kafka-subnet 790 | update subnet id=$subnet public=true 791 | routetable = create routetable vpc=$vpc 792 | attach routetable subnet=$subnet id=$routetable 793 | create route cidr=0.0.0.0/0 gateway=$igw table=$routetable 794 | 795 | ``` 796 | Create securitygroup for SSH: opening port 22 for all IPs 797 | 798 | ```sh 799 | sshsecgroup = create securitygroup vpc=$vpc description=SSHSecurityGroup name=SSHSecurityGroup 800 | update securitygroup id=$sshsecgroup inbound=authorize protocol=tcp cidr={remote-access.cidr} portrange=22 801 | 802 | ``` 803 | Create securitygroup for Kafka instances (brokers & zookeeper) 804 | 805 | ```sh 806 | kafkasecgroup = create securitygroup vpc=$vpc description=KafkaSecurityGroup name=KafkaSecurityGroup 807 | update securitygroup id=$kafkasecgroup inbound=authorize protocol=tcp cidr=$subnet_cidr portrange=0-65535 808 | 809 | ``` 810 | Create a role with policy for ec2 resources so that an instance can list other instances using a local `awless` 811 | 812 | ```sh 813 | create role name=EC2ReadonlyRole principal-service="ec2.amazonaws.com" sleep-after=20 814 | attach policy role=EC2ReadonlyRole service=ec2 access=readonly 815 | 816 | ``` 817 | Create Zookeeper instance with security groups attached 818 | 819 | ```sh 820 | zookeeper = create instance name=zookeeper distro=redhat type={zookeeper.instance.type} keypair={keypair.name} subnet=$subnet securitygroup=[$sshsecgroup,$kafkasecgroup] userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/redhat/zookeeper.sh 821 | 822 | ``` 823 | Wait the Zookeeper instance is up and running 824 | 825 | ```sh 826 | check instance id=$zookeeper state=running timeout=180 827 | 828 | ``` 829 | Create Kafka broker instances with role created above and security groups attached 830 | 831 | ```sh 832 | broker_1 = create instance name=broker_1 distro=redhat type={broker.instance.type} keypair={keypair.name} subnet=$subnet role=EC2ReadonlyRole securitygroup=[$sshsecgroup,$kafkasecgroup] userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/redhat/kafka.sh 833 | broker_2 = create instance name=broker_2 distro=redhat type={broker.instance.type} keypair={keypair.name} subnet=$subnet role=EC2ReadonlyRole securitygroup=[$sshsecgroup,$kafkasecgroup] userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/redhat/kafka.sh 834 | broker_3 = create instance name=broker_3 distro=redhat type={broker.instance.type} keypair={keypair.name} subnet=$subnet role=EC2ReadonlyRole securitygroup=[$sshsecgroup,$kafkasecgroup] userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/redhat/kafka.sh 835 | ``` 836 | 837 | 838 | 839 | ### Create VPC with a Linux host bastion 840 | 841 | 842 | **-> Minimal awless version required: v0.1.3** 843 | 844 | 845 | 846 | *This template build this typical Linux bastion [architecture](http://docs.aws.amazon.com/quickstart/latest/linux-bastion/architecture.html) except it only deploys one host bastion on one public subnet* 847 | 848 | 849 | 850 | **tags**: 851 | infra 852 | 853 | 854 | (run it locally with: `awless run repo:linux_bastion -v`) 855 | 856 | 857 | 858 | **STEPS** 859 | 860 | Create a new VPC and make it public with an internet gateway 861 | 862 | ```sh 863 | vpc = create vpc cidr=10.0.0.0/16 name=BastionVpc 864 | gateway = create internetgateway 865 | attach internetgateway id=$gateway vpc=$vpc 866 | 867 | ``` 868 | Create 2 private subnets each on a different availability zone 869 | That is where you will deploy resources only accessible through the bastion 870 | 871 | ```sh 872 | create subnet cidr=10.0.0.0/19 name=PrivSubnet1 vpc=$vpc availabilityzone={availabilityzone.1} 873 | create subnet cidr=10.0.32.0/19 name=PrivSubnet2 vpc=$vpc availabilityzone={availabilityzone.2} 874 | 875 | ``` 876 | Create the the public subnet hosting the bastion 877 | 878 | ```sh 879 | pubSubnet = create subnet cidr=10.0.128.0/20 name=PubSubnet1 vpc=$vpc availabilityzone={availabilityzone.1} 880 | update subnet id=$pubSubnet public=true 881 | 882 | ``` 883 | Create a route table (with routing only allowed within VPC by default) 884 | 885 | ```sh 886 | rtable = create routetable vpc=$vpc 887 | 888 | ``` 889 | Make the public subnet use the route table 890 | 891 | ```sh 892 | attach routetable id=$rtable subnet=$pubSubnet 893 | create route cidr=0.0.0.0/0 gateway=$gateway table=$rtable 894 | 895 | ``` 896 | Create the firewall with the remote access CIDR applied on each bastion host 897 | 898 | ```sh 899 | bastionSecGroup = create securitygroup vpc=$vpc description=BastionSecGroup name=bastion-secgroup 900 | update securitygroup id=$bastionSecGroup inbound=authorize protocol=tcp cidr={remoteaccess-cidr} portrange=22 901 | update securitygroup id=$bastionSecGroup inbound=authorize protocol=icmp cidr={remoteaccess-cidr} portrange=any 902 | 903 | ``` 904 | Allow only a set of permitted actions for the 2 host bastions 905 | 906 | ```sh 907 | create role name=BastionHostRole principal-service=ec2.amazonaws.com sleep-after=30 908 | bastionEc2Policy = create policy name=BastionEc2Permissions action=[ec2:DescribeAddresses,ec2:AssociateAddress] resource="*" effect=Allow 909 | attach policy role=BastionHostRole arn=$bastionEc2Policy 910 | 911 | ``` 912 | Create one elastic IPs for that will be dynamically aasigned to the host bastion by the bootstrap script 913 | 914 | ```sh 915 | create elasticip domain=vpc 916 | 917 | ``` 918 | Create the autoscaling group 919 | 920 | ```sh 921 | launchConfig = create launchconfiguration image={instance.image} keypair={keypair.name} securitygroups=$bastionSecGroup name=BastionHostsLaunchConfig type=t2.micro role=BastionHostRole userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/prepare_bastion.yml 922 | create scalinggroup desired-capacity=1 launchconfiguration=$launchConfig max-size=1 min-size=1 name=autoscaling-instances-group subnets=$pubSubnet 923 | ``` 924 | 925 | 926 | 927 | ### Create a dbsubnetgroups 928 | 929 | 930 | 931 | 932 | *Create 2 subnets on different availability zones to later on constitute the dbsubnet group* 933 | 934 | 935 | 936 | 937 | (run it locally with: `awless run repo:new_dbsubnetgroup -v`) 938 | 939 | 940 | *Full CLI example:* 941 | ```sh 942 | run repo:new_dbsubnetgroup.draft first.subnet.cidr=10.0.0.0/25 first.subnet.availabilityzone=us-west-1a second.subnet.cidr=10.0.0.128/25 second.subnet.availabilityzone=us-west-1c vpc.cidr=10.0.0.0/24 vpc.name=myvpc 943 | ``` 944 | 945 | 946 | **STEPS** 947 | 948 | Create a new VPC open to Internet to host the subnets 949 | 950 | ```sh 951 | vpc = create vpc cidr={vpc.cidr} name={vpc.name} 952 | gateway = create internetgateway 953 | attach internetgateway id=$gateway vpc=$vpc 954 | firstsubnet = create subnet cidr={first.subnet.cidr} vpc=$vpc name={first.subnet.name} availabilityzone={first.subnet.availabilityzone} 955 | update subnet id=$firstsubnet public=true 956 | secondsubnet = create subnet cidr={second.subnet.cidr} vpc=$vpc name={second.subnet.name} availabilityzone={second.subnet.availabilityzone} 957 | update subnet id=$secondsubnet public=true 958 | 959 | ``` 960 | Create a route table for this network 961 | 962 | ```sh 963 | rtable = create routetable vpc=$vpc 964 | 965 | ``` 966 | Make the subnets open to the Internet (through vpc that has an internetgateway) 967 | 968 | ```sh 969 | attach routetable id=$rtable subnet=$firstsubnet 970 | attach routetable id=$rtable subnet=$secondsubnet 971 | create dbsubnetgroup name={dbsubnetgroup.name} description={dbsubnetgroup.description} subnets=[$firstsubnet, $secondsubnet] 972 | ``` 973 | 974 | 975 | 976 | ### Attach usual readonly AWS policies (set of permissions) on group 977 | 978 | 979 | 980 | 981 | *When you want your users to have a set of permissions, instead of attaching permissions directly on users it is a good practice and simpler to define a group having those permissions and then adding/removing as needed users from those groups.* 982 | 983 | 984 | 985 | **tags**: 986 | access, policy, role 987 | 988 | 989 | (run it locally with: `awless run repo:policies_on_group -v`) 990 | 991 | 992 | 993 | **STEPS** 994 | 995 | 996 | ```sh 997 | attach policy service=ec2 access=readonly group={group-name} 998 | attach policy service=s3 access=readonly group={group-name} 999 | attach policy service=sns access=readonly group={group-name} 1000 | attach policy service=sqs access=readonly group={group-name} 1001 | attach policy service=vpc access=readonly group={group-name} 1002 | attach policy service=autoscaling access=readonly group={group-name} 1003 | attach policy service=iam access=readonly group={group-name} 1004 | attach policy service=rds access=readonly group={group-name} 1005 | attach policy service=route53 access=readonly group={group-name} 1006 | ``` 1007 | 1008 | 1009 | 1010 | ### Create a public network enabling routing from the Internet 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | **tags**: 1018 | infra 1019 | 1020 | 1021 | (run it locally with: `awless run repo:public_subnet -v`) 1022 | 1023 | 1024 | 1025 | **STEPS** 1026 | 1027 | Create the subnet 1028 | 1029 | ```sh 1030 | subnet = create subnet cidr={subnet.cidr} vpc={subnet.vpc} name={subnet.name} 1031 | 1032 | ``` 1033 | Allow instances in this network to have public IP addresses 1034 | 1035 | ```sh 1036 | update subnet id=$subnet public=true 1037 | 1038 | ``` 1039 | Create a route table for this network 1040 | 1041 | ```sh 1042 | rtable = create routetable vpc={subnet.vpc} 1043 | attach routetable id=$rtable subnet=$subnet 1044 | 1045 | ``` 1046 | Enable routing from the Internet to this subnet 1047 | 1048 | ```sh 1049 | create route cidr=0.0.0.0/0 gateway={vpc.internetgateway} table=$rtable 1050 | ``` 1051 | 1052 | 1053 | 1054 | ### Create a AWS role with usual readonly policies that applies on a resource 1055 | 1056 | 1057 | 1058 | 1059 | *Create a AWS role that applies on a resource (retrieve the account id with `awless whoami`)* 1060 | 1061 | 1062 | 1063 | **tags**: 1064 | access, policy, role 1065 | 1066 | 1067 | (run it locally with: `awless run repo:role_for_resource -v`) 1068 | 1069 | 1070 | 1071 | **STEPS** 1072 | 1073 | 1074 | ```sh 1075 | roleName = {role-name} 1076 | create role name=$roleName principal-service={aws-service} 1077 | 1078 | ``` 1079 | Attach policy (set of permissions) to the created role 1080 | 1081 | ```sh 1082 | attach policy role=$roleName service=ec2 access=readonly 1083 | attach policy role=$roleName service=s3 access=readonly 1084 | attach policy role=$roleName service=sns access=readonly 1085 | attach policy role=$roleName service=sqs access=readonly 1086 | attach policy role=$roleName service=vpc access=readonly 1087 | attach policy role=$roleName service=autoscaling access=readonly 1088 | attach policy role=$roleName service=iam access=readonly 1089 | attach policy role=$roleName service=rds access=readonly 1090 | attach policy role=$roleName service=route53 access=readonly 1091 | ``` 1092 | 1093 | 1094 | 1095 | ### Create a AWS role with usual readonly policies that applies on a user 1096 | 1097 | 1098 | 1099 | 1100 | *Create a AWS role that applies on a user (retrieve the id with `awless whoami`)* 1101 | 1102 | 1103 | 1104 | **tags**: 1105 | access, policy, user 1106 | 1107 | 1108 | (run it locally with: `awless run repo:role_for_user -v`) 1109 | 1110 | 1111 | 1112 | **STEPS** 1113 | 1114 | 1115 | ```sh 1116 | newRole = create role name={role-name} principal-account={aws-account-id} 1117 | 1118 | ``` 1119 | Attach policy (set of permissions) to the created role 1120 | 1121 | ```sh 1122 | attach policy role={role-name} service=ec2 access=readonly 1123 | attach policy role={role-name} service=s3 access=readonly 1124 | attach policy role={role-name} service=sns access=readonly 1125 | attach policy role={role-name} service=sqs access=readonly 1126 | attach policy role={role-name} service=vpc access=readonly 1127 | attach policy role={role-name} service=autoscaling access=readonly 1128 | attach policy role={role-name} service=iam access=readonly 1129 | attach policy role={role-name} service=rds access=readonly 1130 | attach policy role={role-name} service=route53 access=readonly 1131 | 1132 | ``` 1133 | Create a policy to allow user with this policy to assume only this role 1134 | You can then attach this policy to a user via `awless attach policy arn=... user=jsmith` 1135 | 1136 | ```sh 1137 | create policy name={assume-policy-name} effect=Allow action=sts:AssumeRole resource=$newRole 1138 | ``` 1139 | 1140 | 1141 | 1142 | ### Create a static website on S3 1143 | 1144 | 1145 | 1146 | 1147 | 1148 | 1149 | **tags**: 1150 | s3 1151 | 1152 | 1153 | (run it locally with: `awless run repo:s3website -v`) 1154 | 1155 | 1156 | 1157 | **STEPS** 1158 | 1159 | Create the bucket where files will be stored 1160 | 1161 | ```sh 1162 | create bucket name={domain.name} acl=public-read 1163 | 1164 | ``` 1165 | Publish this s3bucket as a website 1166 | 1167 | ```sh 1168 | update bucket name={domain.name} public-website=true redirect-hostname={domain.name} 1169 | 1170 | ``` 1171 | Add files to the bucket with 1172 | awless create s3object bucket={domain.name} file={input-file-path} acl=public-read 1173 | 1174 | 1175 | 1176 | ### Simple wordpress deployment 1177 | 1178 | 1179 | 1180 | 1181 | 1182 | 1183 | **tags**: 1184 | infra 1185 | 1186 | 1187 | (run it locally with: `awless run repo:simple_wordpress_infra -v`) 1188 | 1189 | 1190 | 1191 | **STEPS** 1192 | 1193 | VPC and its Internet gateway 1194 | 1195 | ```sh 1196 | vpc = create vpc cidr=10.0.0.0/16 name=wordpress-vpc 1197 | igw = create internetgateway 1198 | attach internetgateway id=$igw vpc=$vpc 1199 | 1200 | ``` 1201 | Subnet and its route table 1202 | 1203 | ```sh 1204 | subnet = create subnet cidr=10.0.0.0/24 vpc=$vpc name=wordpress-subnet 1205 | update subnet id=$subnet public=true 1206 | routetable = create routetable vpc=$vpc 1207 | attach routetable subnet=$subnet id=$routetable 1208 | create route cidr=0.0.0.0/0 gateway=$igw table=$routetable 1209 | 1210 | ``` 1211 | Create a security group and authorize accesses from the Internet for port 22 and 80 1212 | 1213 | ```sh 1214 | secgroup = create securitygroup vpc=$vpc description="authorize ssh and http from internet" name=wordpress-secgroup 1215 | update securitygroup id=$secgroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=22 1216 | update securitygroup id=$secgroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=80 1217 | 1218 | ``` 1219 | Create keypair and instance 1220 | 1221 | ```sh 1222 | keypair = create keypair name={keypair.name} 1223 | create instance name=wordpress-instance subnet=$subnet keypair=$keypair securitygroup=$secgroup userdata=https://raw.githubusercontent.com/zn3zman/AWS-WordPress-Creation/master/WP-Setup.sh 1224 | ``` 1225 | 1226 | 1227 | 1228 | ### Upload Image from local file 1229 | 1230 | 1231 | 1232 | 1233 | *This template uploads on s3 a local VM file (VHD, OVA, VMDK). Then it creates an AMI from the S3 object.* 1234 | 1235 | 1236 | 1237 | **tags**: 1238 | infra, s3 1239 | 1240 | 1241 | (run it locally with: `awless run repo:upload_image -v`) 1242 | 1243 | 1244 | 1245 | **STEPS** 1246 | 1247 | Upload the image on s3 1248 | 1249 | ```sh 1250 | bucket = {image.bucket} 1251 | imageObject = create s3object bucket=$bucket file={image.filepath} 1252 | 1253 | ``` 1254 | Create the AMI from the object on S3 1255 | 1256 | ```sh 1257 | import image description={image.description} bucket=$bucket s3object=$imageObject 1258 | ``` 1259 | 1260 | 1261 | 1262 | ### Create a user with its SDK/Shell access key and console password 1263 | 1264 | 1265 | 1266 | 1267 | 1268 | 1269 | **tags**: 1270 | access, user 1271 | 1272 | 1273 | (run it locally with: `awless run repo:user -v`) 1274 | 1275 | 1276 | 1277 | **STEPS** 1278 | 1279 | 1280 | ```sh 1281 | username = {user.name} 1282 | 1283 | ``` 1284 | Create user 1285 | 1286 | ```sh 1287 | create user name=$username 1288 | 1289 | ``` 1290 | Create AWS Console password 1291 | 1292 | ```sh 1293 | create loginprofile username=$username password={user.console-password} 1294 | 1295 | ``` 1296 | Create SDK/shell access key 1297 | 1298 | ```sh 1299 | create accesskey user=$username 1300 | ``` 1301 | 1302 | 1303 | 1304 | ### Create a VPC with its internet routing gateway 1305 | 1306 | 1307 | 1308 | 1309 | 1310 | 1311 | **tags**: 1312 | infra, VPC 1313 | 1314 | 1315 | (run it locally with: `awless run repo:vpc -v`) 1316 | 1317 | 1318 | 1319 | **STEPS** 1320 | 1321 | 1322 | ```sh 1323 | vpc = create vpc cidr={vpc.cidr} name={vpc.name} 1324 | gateway = create internetgateway 1325 | attach internetgateway id=$gateway vpc=$vpc 1326 | ``` 1327 | 1328 | 1329 | 1330 | ### Create a VPC with 3 internal subnets 1331 | 1332 | 1333 | 1334 | 1335 | 1336 | 1337 | 1338 | (run it locally with: `awless run repo:vpc_with_subnets -v`) 1339 | 1340 | 1341 | 1342 | **STEPS** 1343 | 1344 | Create a new VPC with private subnets (no internet gateway) 1345 | 1346 | ```sh 1347 | vpc = create vpc cidr=10.0.0.0/16 name=vpc_10.0.0.0_16 1348 | create subnet cidr=10.0.0.0/24 vpc=$vpc name=sub_10.0.0.0_24 availabilityzone={subnet1.zone} 1349 | create subnet cidr=10.0.1.0/24 vpc=$vpc name=sub_10.0.1.0_24 availabilityzone={subnet2.zone} 1350 | ``` 1351 | 1352 | 1353 | 1354 | ### Highly-available wordpress behind a loadbalancer, with a RDS database 1355 | 1356 | 1357 | **-> Minimal awless version required: v0.1.1** 1358 | 1359 | 1360 | 1361 | 1362 | 1363 | **tags**: 1364 | infra, rds, autoscaling 1365 | 1366 | 1367 | (run it locally with: `awless run repo:wordpress_ha -v`) 1368 | 1369 | 1370 | 1371 | **STEPS** 1372 | 1373 | 1374 | ```sh 1375 | dbname={dbname} 1376 | dbhost={dbhost} 1377 | dbuser={dbuser} 1378 | dbpassword={dbpassword} 1379 | 1380 | ``` 1381 | Create the load balancer with its security group, target group and listener 1382 | 1383 | ```sh 1384 | lbsecgroup = create securitygroup vpc={wordpress.vpc} description="authorize HTTP from the Internet" name=wordpress-lb-securitygroup 1385 | update securitygroup id=$lbsecgroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=80 1386 | tg = create targetgroup name=wordpress-workers port=80 protocol=HTTP vpc={wordpress.vpc} 1387 | lb = create loadbalancer name=wordpress-loadbalancer subnets={wordpress.subnets} securitygroups=$lbsecgroup 1388 | create listener actiontype=forward loadbalancer=$lb port=80 protocol=HTTP targetgroup=$tg 1389 | 1390 | ``` 1391 | Create the launch configuration for the instances and start it in a scaling group, to ensure having always 2 instances running 1392 | 1393 | ```sh 1394 | launchconf = create launchconfiguration image={instance.image} keypair={wordpress.keypair} name=wordpress-launch-configuration type=t2.micro userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/wordpress.sh securitygroups={instances.securitygroup} 1395 | create scalinggroup desired-capacity=2 launchconfiguration=$launchconf max-size=2 min-size=2 name=wordpress-scalinggroup subnets={wordpress.subnets} targetgroups=$tg 1396 | ``` 1397 | 1398 | 1399 | -------------------------------------------------------------------------------- /README_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://api.travis-ci.org/wallix/awless-templates.svg?branch=master)](https://travis-ci.org/wallix/awless-templates) 2 | 3 | [Twitter](http://twitter.com/awlessCLI) | [Wiki](https://github.com/wallix/awless/wiki) | [Changelog](https://github.com/wallix/awless/blob/master/CHANGELOG.md#readme) 4 | 5 | # awless templates 6 | 7 | Repository to collect official, verified and runnable templates for the [awless CLI](https://github.com/wallix/awless) 8 | 9 | **You need at least awless version v0.1.3 to run those examples** 10 | 11 | Here are some non exhaustive [Examples](https://github.com/wallix/awless/wiki/Examples) of what you can do with templates. You can also read more about [awless templates](https://github.com/wallix/awless/wiki/Templates) 12 | 13 | ## Continuous Integration 14 | 15 | On each change all templates are verified & compiled against the latest version of `awless`. 16 | 17 | You can run the verification locally with: 18 | 19 | go get github.com/wallix/awless # if needed 20 | go test -v 21 | 22 | # Examples 23 | 24 | {{range $index, $example := .}} 25 | * [{{$example.Title}}](#{{ MarkdownTitleLink $example.Title }}){{end}} 26 | 27 | {{range $index, $example := .}} 28 | ### {{$example.Title}} 29 | 30 | {{if $example.MinimalVersion }} 31 | **-> Minimal awless version required: {{ $example.MinimalVersion }}** 32 | {{ end }} 33 | 34 | {{if $example.Description }} 35 | *{{ $example.Description }}* 36 | {{ end }} 37 | 38 | {{if $example.Tags }} 39 | **tags**: 40 | {{ Join $example.Tags ", " }} 41 | {{ end }} 42 | 43 | (run it locally with: `awless run repo:{{$example.Name}} -v`) 44 | 45 | {{if $example.CLIExample }} 46 | *Full CLI example:* 47 | ```sh 48 | {{ $example.CLIExample }} 49 | ``` 50 | {{ end }} 51 | 52 | **STEPS** 53 | 54 | {{$example.Documentation}} 55 | 56 | {{end}} -------------------------------------------------------------------------------- /awless_readonly_group.aws: -------------------------------------------------------------------------------- 1 | # Here we define a group that allow users in that group 2 | # to use the `awless` CLI in a readonly mode (i.e. sync, listing). 3 | # 4 | 5 | # Create group name variable: 6 | groupName = AwlessReadOnlyPermissionsGroup 7 | 8 | # Create the group: 9 | create group name=$groupName 10 | 11 | # Attach corresponding readonly AWS policies (set of permissions) on group related to the `awless` services: 12 | attach policy arn=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess group=$groupName 13 | attach policy arn=arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess group=$groupName 14 | attach policy arn=arn:aws:iam::aws:policy/AmazonSNSReadOnlyAccess group=$groupName 15 | attach policy arn=arn:aws:iam::aws:policy/AmazonSQSReadOnlyAccess group=$groupName 16 | attach policy arn=arn:aws:iam::aws:policy/AmazonVPCReadOnlyAccess group=$groupName 17 | attach policy arn=arn:aws:iam::aws:policy/AutoScalingReadOnlyAccess group=$groupName 18 | attach policy arn=arn:aws:iam::aws:policy/IAMReadOnlyAccess group=$groupName 19 | attach policy arn=arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess group=$groupName 20 | attach policy arn=arn:aws:iam::aws:policy/AmazonRoute53ReadOnlyAccess group=$groupName 21 | attach policy arn=arn:aws:iam::aws:policy/AWSLambdaReadOnlyAccess group=$groupName 22 | -------------------------------------------------------------------------------- /awless_readonly_policies.aws: -------------------------------------------------------------------------------- 1 | # Title: Pre-defined policies for awless users 2 | # MinimalVersion: v0.1.3 3 | # Description: Useful pre-defined readonly & readwrite policies for awless users 4 | 5 | # Infra resources 6 | create policy name=AwlessInfraReadonlyPolicy effect=Allow resource="*" description="Readonly access to infra resources" action=[ec2:Describe*,autoscaling:Describe*,elasticloadbalancing:Describe*] 7 | 8 | # Access resources 9 | create policy name=AwlessAccessReadonlyPolicy effect=Allow resource="*" description="Readonly access to access resources" action=[iam:GenerateCredentialReport,iam:GenerateServiceLastAccessedDetails,iam:Get*,iam:List*,sts:Get*] 10 | 11 | # Storage resources 12 | create policy name=AwlessStorageReadonlyPolicy effect=Allow resource="*" description="Readonly access to storage resources" action=[s3:Get*,s3:List*] 13 | 14 | # Messaging resources 15 | create policy name=AwlessMessagingReadonlyPolicy effect=Allow resource="*" description="Readonly access to notification and queueing for messaging resources" action=[sns:GetTopicAttributes,sns:List*,sqs:GetQueueAttributes,sqs:ListQueues] 16 | 17 | # Lambda resources 18 | create policy name=AwlessLambdaReadonlyPolicy effect=Allow resource="*" description="Readonly access to lambda resources" action=[cloudwatch:Describe*,cloudwatch:Get*,cloudwatch:List*,cognito-identity:ListIdentityPools,cognito-sync:GetCognitoEvents,dynamodb:BatchGetItem,dynamodb:DescribeStream,dynamodb:DescribeTable,dynamodb:GetItem,dynamodb:ListStreams,dynamodb:ListTables,dynamodb:Query,dynamodb:Scan,events:List*,events:Describe*,iam:ListRoles,kinesis:DescribeStream,kinesis:ListStreams,lambda:List*,lambda:Get*,logs:DescribeMetricFilters,logs:GetLogEvents,logs:DescribeLogGroups,logs:DescribeLogStreams,s3:Get*,s3:List*,sns:ListTopics,sns:ListSubscriptions,sns:ListSubscriptionsByTopic,sqs:ListQueues,tag:GetResources,kms:ListAliases,ec2:DescribeVpcs,ec2:DescribeSubnets,ec2:DescribeSecurityGroups,iot:GetTopicRules,iot:ListTopicRules,iot:ListPolicies,iot:ListThings,iot:DescribeEndpoint] 19 | 20 | # DNS resources 21 | create policy name=AwlessDNSReadonlyPolicy effect=Allow resource="*" description="Readonly access to DNS resources" action=[route53:Get*,route53:List*,route53:TestDNSAnswer,route53domains:Get*,route53domains:List*] 22 | 23 | # Monitoring resources 24 | create policy name=AwlessMonitoringReadonlyPolicy effect=Allow resource="*" description="Readonly access to monitoring resources" action=[autoscaling:Describe*,cloudwatch:Describe*,cloudwatch:Get*,cloudwatch:List*,logs:Get*,logs:Describe*,logs:TestMetricFilter,sns:Get*,sns:List*] 25 | 26 | # CDN resources 27 | create policy name=AwlessCDNReadonlyPolicy effect=Allow resource="*" description="Readonly access to CDN resources" action=[acm:ListCertificates,cloudfront:Get*,cloudfront:List*,iam:ListServerCertificates,route53:List*,waf:ListWebACLs,waf:GetWebACL] 28 | 29 | # Cloud formation resources 30 | create policy name=AwlessCloudFormationReadonlyPolicy effect=Allow resource="*" description="Readonly access to CloudFormation resources" action=[cloudformation:DescribeStacks,cloudformation:DescribeStackEvents,cloudformation:DescribeStackResource,cloudformation:DescribeStackResources,cloudformation:GetTemplate,cloudformation:List*] 31 | -------------------------------------------------------------------------------- /awless_readwrite_group.aws: -------------------------------------------------------------------------------- 1 | # Here we define a group that allow users in that group to use the `awless` CLI in write mode. 2 | # 3 | 4 | # Create group name variable: 5 | groupName = AwlessReadWritePermissionsGroup 6 | 7 | # Create the group: 8 | create group name=$groupName 9 | 10 | # Attach corresponding AWS policies (set of permissions) on group related to the `awless` services: 11 | attach policy arn=arn:aws:iam::aws:policy/AmazonEC2FullAccess group=$groupName 12 | attach policy arn=arn:aws:iam::aws:policy/AmazonS3FullAccess group=$groupName 13 | attach policy arn=arn:aws:iam::aws:policy/AmazonSNSFullAccess group=$groupName 14 | attach policy arn=arn:aws:iam::aws:policy/AmazonSQSFullAccess group=$groupName 15 | attach policy arn=arn:aws:iam::aws:policy/AmazonVPCFullAccess group=$groupName 16 | attach policy arn=arn:aws:iam::aws:policy/AutoScalingFullAccess group=$groupName 17 | attach policy arn=arn:aws:iam::aws:policy/AmazonRDSFullAccess group=$groupName 18 | attach policy arn=arn:aws:iam::aws:policy/AmazonRoute53FullAccess group=$groupName 19 | attach policy arn=arn:aws:iam::aws:policy/AWSLambdaFullAccess group=$groupName 20 | 21 | # Note that we keep the IAM access readonly 22 | attach policy arn=arn:aws:iam::aws:policy/IAMReadOnlyAccess group=$groupName -------------------------------------------------------------------------------- /classic_load_balancer.aws: -------------------------------------------------------------------------------- 1 | vpc = {main.vpc} 2 | 3 | # Loadb sec group 4 | loadb-secgroup = create securitygroup vpc=$vpc description="Incoming traffic to classic loadb" name=classicloadb-traffic 5 | # Authorize incoming traffic on port 80 6 | update securitygroup id=$loadb-secgroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=80 7 | 8 | subnet = {main.subnet} 9 | 10 | loadb = create classicloadbalancer name={loadbalancer.name} subnets=[$subnet] listeners=TCP:80:TCP:8080 tags=Env:Test,Created:Awless securitygroups=$loadb-secgroup 11 | 12 | # Instances sec group 13 | inst-secgroup = create securitygroup vpc=$vpc description="Incoming traffic to classic loadb" name=loadb-instances-traffic 14 | # Authorize incoming traffic on port 8080 and SSH 15 | update securitygroup id=$inst-secgroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=8080 16 | update securitygroup id=$inst-secgroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=22 17 | 18 | # Create instances with a simple netcat responding on 8080 19 | inst_1 = create instance name={instance.1.name} securitygroup=$inst-secgroup subnet=$subnet distro=canonical:ubuntu type=t2.micro keypair={ssh.keypair} userdata="#!/bin/bash\nwhile true; do nc -l 8080; done" 20 | inst_2 = create instance name={instance.2.name} securitygroup=$inst-secgroup subnet=$subnet distro=canonical:ubuntu type=t2.micro keypair={ssh.keypair} userdata="#!/bin/bash\nwhile true; do nc -l 8080; done" 21 | 22 | check instance id=$inst_1 state=running timeout=180 23 | check instance id=$inst_2 state=running timeout=180 24 | 25 | attach classicloadbalancer name=$loadb instance=$inst_1 26 | attach classicloadbalancer name=$loadb instance=$inst_2 -------------------------------------------------------------------------------- /cockroach_insecure_cluster_with_haproxy.draft: -------------------------------------------------------------------------------- 1 | # Title: Create a simple (insecure) CockroachDB cluster 2 | # Description: Deploying an insecure multi-node CockroachDB cluster with HAProxy to distribute client traffic. See https://www.cockroachlabs.com/docs/manual-deployment-insecure.html 3 | # CLIExample: awless run repo:cockroach_insecure_cluster_with_haproxy ssh.keypair=my-ssh-keyname 4 | # MinimalVersion: v0.1.7 5 | 6 | # Create a new VPC with 3 private subnets and a public one (i.e. with internet gateway) 7 | vpc = create vpc cidr=10.0.0.0/16 name=vpc_10.0.0.0_16 8 | gateway = create internetgateway 9 | attach internetgateway id=$gateway vpc=$vpc 10 | 11 | # Private subnets in multi AZ for cockroachdb cluster 12 | subnet_1 = create subnet cidr=10.0.0.0/24 vpc=$vpc name=sub_10.0.0.0_24 availabilityzone={zone1} 13 | subnet_2 = create subnet cidr=10.0.1.0/24 vpc=$vpc name=sub_10.0.1.0_24 availabilityzone={zone2} 14 | subnet_3 = create subnet cidr=10.0.2.0/24 vpc=$vpc name=sub_10.0.2.0_24 availabilityzone={zone3} 15 | 16 | # Public subnet that will hosts the HAproxy 17 | subnet_4 = create subnet cidr=10.0.3.0/24 vpc=$vpc name=sub_10.0.3.0_24 availabilityzone={zone1} 18 | update subnet id=$subnet_4 public=true 19 | 20 | # Routing to attach internet gateway to public subnet 21 | igw_rtable = create routetable vpc=$vpc 22 | attach routetable id=$igw_rtable subnet=$subnet_4 23 | create route cidr=0.0.0.0/0 gateway=$gateway table=$igw_rtable 24 | 25 | # Public IP for a NAT Gateway 26 | pubip = create elasticip domain=vpc 27 | 28 | # Add a NAT Gateway to the public subnet 29 | natgw = create natgateway elasticip-id=$pubip subnet=$subnet_4 30 | # Wait for the NAT Gateway 31 | check natgateway id=$natgw state=available timeout=180 32 | 33 | # Routing to attach nat gateway to private subnets 34 | natgw_rtable = create routetable vpc=$vpc 35 | attach routetable id=$natgw_rtable subnet=$subnet_1 36 | attach routetable id=$natgw_rtable subnet=$subnet_2 37 | attach routetable id=$natgw_rtable subnet=$subnet_3 38 | create route cidr=0.0.0.0/0 gateway=$natgw table=$natgw_rtable 39 | 40 | # Create firewall for SSH access 41 | sshfirewall = create securitygroup vpc=$vpc description=ssh-access name=AccessSSH 42 | update securitygroup id=$sshfirewall inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=22 43 | 44 | # Create firewall for cockroachdb node TCP access 45 | nodefirewall = create securitygroup vpc=$vpc description=cockroachdb-node-access name=CockroachDBAccess 46 | update securitygroup id=$nodefirewall inbound=authorize protocol=tcp cidr=10.0.0.0/16 portrange=26257 47 | 48 | # Create firewall for UI HTTP access 49 | uifirewall = create securitygroup vpc=$vpc description=cockroachdb-ui-access name=CockroachUIAccess 50 | update securitygroup id=$uifirewall inbound=authorize protocol=tcp cidr=10.0.0.0/16 portrange=8080 51 | 52 | # Create firewall for HTTP access 53 | proxyfirewall = create securitygroup vpc=$vpc description=proxy-http-access name=ProxyAccess 54 | update securitygroup id=$proxyfirewall inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=80 55 | update securitygroup id=$proxyfirewall inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=443 56 | 57 | # Create a role with policy for ec2 resources so that an instance can list other instances using a local `awless` 58 | create role name=DiscoverCockroachNodeRole principal-service="ec2.amazonaws.com" sleep-after=20 59 | attach policy role=DiscoverCockroachNodeRole arn=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess 60 | 61 | ## Create the cockroachdb nodes 62 | node_1 = create instance subnet=$subnet_1 keypair={ssh.keypair} distro=canonical:ubuntu type=t2.medium count=1 role=DiscoverCockroachNodeRole name=cockroachdb-node-1 securitygroup=$sshfirewall userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/ubuntu/cockroach_insecure_node.sh 63 | check instance id=$node_1 state=running timeout=180 64 | 65 | node_2 = create instance subnet=$subnet_2 keypair={ssh.keypair} distro=canonical:ubuntu type=t2.medium count=1 role=DiscoverCockroachNodeRole name=cockroachdb-node-2 securitygroup=$sshfirewall userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/ubuntu/joining_cockroach_insecure_node.sh 66 | check instance id=$node_2 state=running timeout=180 67 | 68 | node_3 = create instance subnet=$subnet_3 keypair={ssh.keypair} distro=canonical:ubuntu type=t2.medium count=1 role=DiscoverCockroachNodeRole name=cockroachdb-node-3 securitygroup=$sshfirewall userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/ubuntu/joining_cockroach_insecure_node.sh 69 | check instance id=$node_3 state=running timeout=180 70 | 71 | haproxy = create instance subnet=$subnet_4 keypair={ssh.keypair} distro=canonical:ubuntu type=t2.micro count=1 role=DiscoverCockroachNodeRole name=cockroachdb-haproxy securitygroup=$sshfirewall userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/ubuntu/cockroach_haproxy.sh 72 | 73 | # Update instances with firewall definitions 74 | attach securitygroup id=$proxyfirewall instance=$haproxy 75 | attach securitygroup id=$nodefirewall instance=$haproxy 76 | 77 | attach securitygroup id=$nodefirewall instance=$node_1 78 | attach securitygroup id=$nodefirewall instance=$node_2 79 | attach securitygroup id=$nodefirewall instance=$node_3 80 | 81 | attach securitygroup id=$uifirewall instance=$node_1 82 | attach securitygroup id=$uifirewall instance=$node_2 83 | attach securitygroup id=$uifirewall instance=$node_3 -------------------------------------------------------------------------------- /cockroachdb/README.md: -------------------------------------------------------------------------------- 1 | # Multi-AZ CockroachDB insecure cluster 2 | 3 | Create and take down a multi-AZ CockroachDB (2.0.x) 3 nodes cluster with both AWS TCP & HTTP load balancing. 4 | 5 | (The template follows the recommended official deployment at https://www.cockroachlabs.com/docs/stable/deploy-cockroachdb-on-aws-insecure.html) 6 | 7 | You will be able to access the web UI, the SQL cluster and each private cluster nodes through a jump server. 8 | 9 | ![Cockroach Dashboard](cockroachdb-dashboard.png) 10 | 11 | ## Steps 12 | 13 | #### Pre-requisites 14 | 15 | Install [awless](https://github.com/wallix/awless#why-awless) 16 | 17 | Get the CockroachDB template directory (i.e. awless template + corresponding userdata) locally by cloning this repository: 18 | 19 | cd ~/tmp 20 | git clone https://github.com/wallix/awless-templates 21 | 22 | #### Run 23 | 24 | Go into the CockroachDB template directory: 25 | 26 | cd awless-templates/cockroachdb 27 | 28 | Verify where `awless` will deploy your infrastructure by displaying you current AWS region/profile with: 29 | 30 | awless switch 31 | 32 | Run the template with `awless`: 33 | 34 | awless run cockroach_insecure_cluster.aws 35 | 36 | Note that you will be prompted with _smart completion_ for any missing info. You will have time to review and confirm the template before running it. 37 | 38 | Get an overview of the infrastructure you created: 39 | 40 | awless show cockroachdb-vpc --local 41 | 42 | (Note the `--local` flag allows to look up cloud data synchronized locally by `awless` instead of fetching everything again remotely) 43 | 44 | #### Play 45 | 46 | You can now interact with the deployed infrastructure. For instance: 47 | 48 | 1. SSH connect to any of the cluster private nodes with `awless ssh` going through the proxy created as part of the template earlier: 49 | 50 | `awless list instances` 51 | `awless ssh cockroachdb-node-1 --through jump-server` 52 | 53 | 2. Retrieve the loadbalancer public DNS and connect to the cluster UI in a browser with http://{PUBLIC_DNS}:8080 . You can use `awless show cockroachdb-cluster --local` to get the value of the public DNS 54 | 55 | 3. Connect using sql to the cluster with (with a pre-installed cockroach binary) `cockroach sql --insecure --host {TCP_PUBLIC_DNS}`. Get the TCP load balancer public DNS with `awless show cockroachdb-cluster-tcp --local`. 56 | 57 | #### Tear down ... and stop paying! 58 | 59 | When done, tear down the infrastructure completely with: 60 | 61 | awless log # to find the id of the previous awless run command 62 | awless revert {id} -------------------------------------------------------------------------------- /cockroachdb/cockroach_insecure_cluster.aws: -------------------------------------------------------------------------------- 1 | # Create a new VPC open to Internet to host the subnets 2 | vpc = create vpc cidr=10.0.0.0/16 name=cockroachdb-vpc 3 | gateway = create internetgateway 4 | attach internetgateway id=$gateway vpc=$vpc 5 | 6 | # Create a route table for this network and enabling routing from the Internet 7 | rtable = create routetable vpc=$vpc 8 | create route cidr=0.0.0.0/0 gateway=$gateway table=$rtable 9 | 10 | # Create 3 public subnets (multi AZ) 11 | pubsubnet1 = create subnet cidr=10.0.128.0/20 vpc=$vpc name=cockroachdb-pubsubnet-1 availabilityzone={availabilityzone.1} 12 | update subnet id=$pubsubnet1 public=true 13 | 14 | pubsubnet2 = create subnet cidr=10.0.144.0/20 vpc=$vpc name=cockroachdb-pubsubnet-2 availabilityzone={availabilityzone.2} 15 | update subnet id=$pubsubnet2 public=true 16 | 17 | pubsubnet3 = create subnet cidr=10.0.160.0/20 vpc=$vpc name=cockroachdb-pubsubnet-3 availabilityzone={availabilityzone.3} 18 | update subnet id=$pubsubnet3 public=true 19 | 20 | # Make the public subnets open to the Internet 21 | attach routetable id=$rtable subnet=$pubsubnet1 22 | attach routetable id=$rtable subnet=$pubsubnet2 23 | attach routetable id=$rtable subnet=$pubsubnet3 24 | 25 | # Create 3 private subnets (multi AZ) 26 | privsubnet1 = create subnet cidr=10.0.0.0/19 vpc=$vpc name=cockroachdb-privsubnet-1 availabilityzone={availabilityzone.1} 27 | privsubnet2 = create subnet cidr=10.0.32.0/19 vpc=$vpc name=cockroachdb-privsubnet-2 availabilityzone={availabilityzone.2} 28 | privsubnet3 = create subnet cidr=10.0.64.0/19 vpc=$vpc name=cockroachdb-privsubnet-3 availabilityzone={availabilityzone.3} 29 | 30 | # Add a NAT Gateway used by nodes to provision themselves with user data accessing Internet 31 | pubip = create elasticip domain=vpc 32 | natgw = create natgateway elasticip-id=$pubip subnet=$pubsubnet1 33 | # Wait for the NAT Gateway 34 | check natgateway id=$natgw state=available timeout=180 35 | 36 | # Routing to attach nat gateway to private subnets 37 | natgw_rtable = create routetable vpc=$vpc 38 | attach routetable id=$natgw_rtable subnet=$privsubnet1 39 | attach routetable id=$natgw_rtable subnet=$privsubnet2 40 | attach routetable id=$natgw_rtable subnet=$privsubnet3 41 | create route cidr=0.0.0.0/0 gateway=$natgw table=$natgw_rtable 42 | 43 | ## Create the firewalls for HTTP UI 44 | loadb-uifirewall = create securitygroup vpc=$vpc description=cockroachdb-loadb-ui-securitygroup name=CockroachUIAccess 45 | update securitygroup id=$loadb-uifirewall inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=8080 46 | 47 | ## Create the HTTP load balancer 48 | tgroup_ui = create targetgroup name=cockroachdb-ui port=8080 protocol=HTTP vpc=$vpc healthcheckpath="/health" 49 | lb = create loadbalancer name=cockroachdb-cluster subnets=[$pubsubnet1, $pubsubnet2, $pubsubnet3] securitygroups=$loadb-uifirewall 50 | create listener actiontype=forward loadbalancer=$lb port=8080 protocol=HTTP targetgroup=$tgroup_ui 51 | 52 | ## Create the TCP load balancer 53 | tgroup_node = create targetgroup name=cockroachdb-nodes port=26257 protocol=TCP vpc=$vpc 54 | tcplb = create loadbalancer name=cockroachdb-cluster-tcp type=network subnets=[$pubsubnet1, $pubsubnet2, $pubsubnet3] 55 | create listener actiontype=forward loadbalancer=$tcplb port=26257 protocol=TCP targetgroup=$tgroup_node 56 | 57 | # Create firewall for general SSH access 58 | sshfirewall = create securitygroup vpc=$vpc description=ssh-access name=AccessSSH 59 | update securitygroup id=$sshfirewall inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=22 60 | 61 | # Create nodes firewall to let: inter nodes TCP traffic, TCP traffic from loadb; UI HTTP traffic from loadb 62 | nodefirewall = create securitygroup vpc=$vpc description=cockroachdb-node-access name=CockroachNodesAccess 63 | update securitygroup id=$nodefirewall inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=26257 64 | update securitygroup id=$nodefirewall inbound=authorize protocol=tcp securitygroup=$loadb-uifirewall portrange=8080 65 | 66 | # Create a role with policy so that cockroach node instances (ec2 resources) can list other nodes using a local `awless` 67 | create role name=DiscoverCockroachNodeRole principal-service="ec2.amazonaws.com" sleep-after=20 68 | attach policy role=DiscoverCockroachNodeRole service=ec2 access=readonly 69 | 70 | ## Create the cockroachdb nodes 71 | node1 = create instance distro=canonical:ubuntu subnet=$privsubnet1 securitygroup=[$sshfirewall,$nodefirewall] keypair={my.ssh.keypair} type={instance.type} role=DiscoverCockroachNodeRole type=t2.medium count=1 name=cockroachdb-node-1 userdata=./userdata/cockroach_insecure_node.sh 72 | check instance id=$node1 state=running timeout=180 73 | 74 | node2 = create instance distro=canonical:ubuntu subnet=$privsubnet2 securitygroup=[$sshfirewall,$nodefirewall] keypair={my.ssh.keypair} type={instance.type} role=DiscoverCockroachNodeRole type=t2.medium count=1 name=cockroachdb-node-2 userdata=./userdata/joining_cockroach_insecure_node.sh 75 | check instance id=$node2 state=running timeout=180 76 | 77 | node3 = create instance distro=canonical:ubuntu subnet=$privsubnet3 securitygroup=[$sshfirewall,$nodefirewall] keypair={my.ssh.keypair} type={instance.type} role=DiscoverCockroachNodeRole type=t2.medium count=1 name=cockroachdb-node-3 userdata=./userdata/joining_cockroach_insecure_node.sh 78 | check instance id=$node3 state=running timeout=180 79 | 80 | # Put instances in the necessary target groups 81 | attach instance id=$node1 targetgroup=$tgroup_node 82 | attach instance id=$node2 targetgroup=$tgroup_node 83 | attach instance id=$node3 targetgroup=$tgroup_node 84 | 85 | attach instance id=$node1 targetgroup=$tgroup_ui 86 | attach instance id=$node2 targetgroup=$tgroup_ui 87 | attach instance id=$node3 targetgroup=$tgroup_ui 88 | 89 | # Create a small jump instance in your public subnet to run command on your nodes 90 | create instance distro=canonical:ubuntu keypair={my.ssh.keypair} name=jump-server subnet=$pubsubnet1 securitygroup=$sshfirewall type=t2.micro 91 | 92 | # Retrieve the loadbalancer public DNS with `awless show cockroachdb-cluster --local` 93 | # Then to connect to the cluster UI in a browser with http://{PUBLIC_DNS}:8080 94 | # 95 | # Retrieve the TCP loadbalancer public DNS with `awless show cockroachdb-cluster-tcp --local` 96 | # Then sql connect to the cluster with `cockroach sql --insecure --host {TCP_PUBLIC_DNS}` 97 | # 98 | # Also use awless and the jump server to go to specific nodes: 99 | # awless ssh cockroachdb-node-1 --through jump-server 100 | -------------------------------------------------------------------------------- /cockroachdb/cockroachdb-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wallix/awless-templates/14f84630e438ce0f9cab49157b8d8b1c342edc25/cockroachdb/cockroachdb-dashboard.png -------------------------------------------------------------------------------- /cockroachdb/userdata/cockroach_insecure_node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | apt-get -y install ntp 4 | 5 | PACKAGE=cockroach-v2.0.1.linux-amd64 6 | 7 | curl -O https://binaries.cockroachdb.com/$PACKAGE.tgz 8 | 9 | tar -xf $PACKAGE.tgz --strip=1 $PACKAGE/cockroach 10 | 11 | mv cockroach /usr/bin 12 | 13 | INSTANCE_IP=$(curl http://169.254.169.254/latest/meta-data/local-ipv4) 14 | 15 | cockroach start --insecure --background --advertise-host=$INSTANCE_IP --http-host=$INSTANCE_IP --host=$INSTANCE_IP -------------------------------------------------------------------------------- /cockroachdb/userdata/joining_cockroach_insecure_node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | apt-get -y install ntp 4 | 5 | curl https://raw.githubusercontent.com/wallix/awless/master/getawless.sh | bash 6 | 7 | FIRST_NODE_IP=$(./awless ls instances --filter name=cockroachdb-node-1 --filter state=running --format tsv --no-headers | cut -f7) 8 | 9 | rm awless 10 | 11 | PACKAGE=cockroach-v2.0.1.linux-amd64 12 | 13 | curl -O https://binaries.cockroachdb.com/$PACKAGE.tgz 14 | 15 | tar -xf $PACKAGE.tgz --strip=1 $PACKAGE/cockroach 16 | 17 | mv cockroach /usr/bin 18 | 19 | INSTANCE_IP=$(curl http://169.254.169.254/latest/meta-data/local-ipv4) 20 | 21 | cockroach start --insecure --background --join=$FIRST_NODE_IP:26257 --advertise-host=$INSTANCE_IP --http-host=$INSTANCE_IP --host=$INSTANCE_IP -------------------------------------------------------------------------------- /db_postgres.aws: -------------------------------------------------------------------------------- 1 | # Title: Create a postgres instance 2 | # Description: Create a private basic postgres instance with firewall. As an example, instance has only basic required properties filled in 3 | # MinimalVersion: v0.1.7 4 | 5 | # Create a new VPC open to Internet to host the subnets 6 | vpc = create vpc cidr=10.0.0.0/16 name=postgres-vpc 7 | gateway = create internetgateway 8 | attach internetgateway id=$gateway vpc=$vpc 9 | 10 | # Create a route table for this network 11 | rtable = create routetable vpc=$vpc 12 | 13 | # Enable routing from the Internet 14 | create route cidr=0.0.0.0/0 gateway=$gateway table=$rtable 15 | 16 | # One public subnet to later deploy or host public applications or a bastion to access your private DBs 17 | pubsubnet = create subnet cidr=10.0.128.0/20 vpc=$vpc name=public-subnet 18 | update subnet id=$pubsubnet public=true 19 | 20 | # Make the public subnet open to the Internet (through vpc that has an internetgateway) 21 | attach routetable id=$rtable subnet=$pubsubnet 22 | 23 | # Two private subnet to constitute the dbsubnetgroup hosting the DB 24 | privsubnet1 = create subnet cidr=10.0.0.0/19 vpc=$vpc name=postgres-priv-subnet1 availabilityzone={availabilityzone.1} 25 | privsubnet2 = create subnet cidr=10.0.32.0/19 vpc=$vpc name=postgres-priv-subnet2 availabilityzone={availabilityzone.2} 26 | 27 | subnetgroup = create dbsubnetgroup subnets=[$privsubnet1, $privsubnet2] name=PostgresDBSubnetGroup description="DB subnet group hosting postgres instances" 28 | 29 | # Firewall for the postgres instance 30 | postgres_sg = create securitygroup name=postgres description='Postgres firewall access' vpc=$vpc 31 | update securitygroup id=$postgres_sg inbound=authorize protocol=tcp portrange=5432 cidr=10.0.0.0/16 32 | 33 | # Create the database and connect to it through: `psql --host=? --port=5432 --username=? --password --dbname=?` 34 | create database engine=postgres id={database.identifier} subnetgroup=$subnetgroup password={password.minimum8chars} dbname={database.name} size=5 type=db.t2.small username={database.username} vpcsecuritygroups=$postgres_sg 35 | 36 | # Create a small jump instance in your public subnet to run command on your postgres DB 37 | # and give SSH access to this instance with a SSH security group 38 | # Run the CLI with: awless .... office.ip=$(awless whoami --ip-only) 39 | sshsecgroup = create securitygroup vpc=$vpc description="SSH access from office IP only" name=ssh-from-office 40 | update securitygroup id=$sshsecgroup inbound=authorize protocol=tcp cidr={office.ip}/32 portrange=22 41 | create instance distro=debian keypair={my.keypair} name=jump subnet=$pubsubnet securitygroup=$sshsecgroup type=t2.micro 42 | 43 | # Then to administrate your DB you can do: 44 | # $ HOST=$(awless show production --values-for PublicDNS --local) 45 | # $ awless ssh jump 46 | # $ sudo apt-get update; sudo apt-get install -y postgresql-client-9.4 47 | # $ psql --host={VALUE FROM HOST ABOVE} --port=5432 --username=... --password --dbname=... -------------------------------------------------------------------------------- /dynamic_autoscaling_watching_CPU.aws: -------------------------------------------------------------------------------- 1 | # Title: Group of instances scaling with CPU consumption 2 | # Tags: infra, autoscaling 3 | # Description: Create an autoscaling group of instances and watch their CPU to dynamically allocate/delete instances when needed. 4 | 5 | # Create the instances launch configuration 6 | launchconfig = create launchconfiguration image={instance.image} keypair={instance.keypair} name=scalingLaunchConf type={instance.type} 7 | 8 | # Create the scalinggroup 9 | create scalinggroup desired-capacity=2 launchconfiguration=$launchconfig max-size={instance.max-number} min-size={instance.min-number} name=instancesScalingGroup subnets={instance.subnets} 10 | 11 | # Create a scaling policy to add instances (scale-in) and a scaling policy to remove instances (scale-out) 12 | adjustmentType = ChangeInCapacity 13 | scalein = create scalingpolicy adjustment-scaling=1 adjustment-type=$adjustmentType name=policy-scaling-in scalinggroup=instancesScalingGroup 14 | scaleout = create scalingpolicy adjustment-scaling=-1 adjustment-type=$adjustmentType name=policy-step-scaling-2 scalinggroup=instancesScalingGroup 15 | 16 | # metrics statistic functions 17 | statFunction = Average 18 | alarmThreshold = 75 19 | monitoredMetric = CPUUtilization 20 | 21 | # Add a monitoring alarm to enable scalein when CPU load is above 75% during 2 * 5 min 22 | create alarm namespace=AWS/EC2 dimensions=AutoScalingGroupName:instancesScalingGroup evaluation-periods=2 metric=$monitoredMetric name=scaleinAlarm operator=GreaterThanOrEqualToThreshold period=300 statistic-function=$statFunction threshold=$alarmThreshold 23 | 24 | attach alarm name=scaleinAlarm action-arn=$scalein 25 | 26 | # Add a monitoring alarm to enable scaleout when CPU load is below 75% during 2 * 5 min 27 | create alarm namespace=AWS/EC2 dimensions=AutoScalingGroupName:instancesScalingGroup evaluation-periods=2 metric=$monitoredMetric name=scaleoutAlarm operator=LessThanOrEqualToThreshold period=300 statistic-function=$statFunction threshold=$alarmThreshold 28 | 29 | attach alarm name=scaleoutAlarm action-arn=$scaleout -------------------------------------------------------------------------------- /generate.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "encoding/json" 7 | "fmt" 8 | "io/ioutil" 9 | "log" 10 | "path/filepath" 11 | "regexp" 12 | "strings" 13 | "text/template" 14 | ) 15 | 16 | var ( 17 | metadataTypes = []string{"Title", "Tags", "Description", "CLIExample", "MinimalVersion"} 18 | metadataRegex = regexp.MustCompile(fmt.Sprintf("#\\s*(%s):\\s*(.+)\\s*", strings.Join(metadataTypes, "|"))) 19 | ) 20 | 21 | func main() { 22 | log.SetFlags(0) 23 | 24 | t, err := template.New("README_TEMPLATE.md").Funcs(template.FuncMap{ 25 | "Join": strings.Join, 26 | "MarkdownTitleLink": markdownTitleLink, 27 | }).ParseFiles("./README_TEMPLATE.md") 28 | if err != nil { 29 | log.Fatal(err) 30 | } 31 | 32 | examples, err := buildExamples() 33 | if err != nil { 34 | log.Fatal(err) 35 | } 36 | 37 | var buff bytes.Buffer 38 | if err := t.Execute(&buff, examples); err != nil { 39 | log.Fatal(err) 40 | } 41 | 42 | if err := ioutil.WriteFile("./README.md", buff.Bytes(), 0666); err != nil { 43 | log.Fatal(err) 44 | } 45 | 46 | if err := writeManifest(examples); err != nil { 47 | log.Fatal(err) 48 | } 49 | } 50 | 51 | type Metadata struct { 52 | Title, CLIExample string `json:",omitempty"` 53 | Description, MinimalVersion string `json:",omitempty"` 54 | Tags []string `json:",omitempty"` 55 | } 56 | 57 | type Example struct { 58 | *Metadata 59 | Name, Link string `json:",omitempty"` 60 | Documentation string `json:"-"` 61 | } 62 | 63 | func buildExamples() ([]*Example, error) { 64 | var examples []*Example 65 | 66 | path := filepath.Join(".", "*.aws") 67 | files, err := filepath.Glob(path) 68 | if err != nil { 69 | return examples, err 70 | } 71 | 72 | for _, filename := range files { 73 | ex, err := buildExample(filename) 74 | if err != nil { 75 | return examples, nil 76 | } 77 | examples = append(examples, ex) 78 | } 79 | 80 | return examples, nil 81 | } 82 | 83 | func buildExample(filename string) (*Example, error) { 84 | content, err := ioutil.ReadFile(filename) 85 | if err != nil { 86 | return nil, err 87 | } 88 | doc, err := buildTemplateDoc(content) 89 | if err != nil { 90 | return nil, err 91 | } 92 | meta, err := parseTemplateMetadata(content) 93 | if err != nil { 94 | return nil, err 95 | } 96 | 97 | name := strings.TrimSuffix(filename, filepath.Ext(filename)) 98 | link := fmt.Sprintf("https://raw.githubusercontent.com/wallix/awless-templates/master/%s.aws", name) 99 | if strings.TrimSpace(meta.Title) == "" { 100 | meta.Title = fmt.Sprintf("%s", humanize(name)) 101 | } 102 | var tags []string 103 | for _, raw := range meta.Tags { 104 | tags = append(tags, strings.TrimSpace(raw)) 105 | } 106 | 107 | return &Example{Metadata: meta, Link: link, Name: name, Documentation: doc}, nil 108 | } 109 | 110 | func parseTemplateMetadata(content []byte) (*Metadata, error) { 111 | metadata := make(map[string]interface{}) 112 | scanner := bufio.NewScanner(bytes.NewReader(content)) 113 | for scanner.Scan() { 114 | match := metadataRegex.FindStringSubmatch(scanner.Text()) 115 | if len(match) > 0 { 116 | if directive := strings.TrimSpace(match[1]); directive == "Tags" { 117 | metadata[directive] = splitTrim(match[2]) 118 | } else { 119 | metadata[match[1]] = match[2] 120 | } 121 | } 122 | } 123 | 124 | b, err := json.Marshal(metadata) 125 | if err != nil { 126 | return nil, err 127 | } 128 | 129 | out := new(Metadata) 130 | if err := json.Unmarshal(b, out); err != nil { 131 | return nil, err 132 | } 133 | 134 | return out, nil 135 | } 136 | 137 | func buildTemplateDoc(content []byte) (string, error) { 138 | var buff bytes.Buffer 139 | var openCodeSection bool 140 | 141 | scanner := bufio.NewScanner(bytes.NewReader(content)) 142 | for scanner.Scan() { 143 | text := strings.TrimSpace(scanner.Text()) 144 | 145 | if text == "" || metadataRegex.MatchString(text) { 146 | continue 147 | } 148 | 149 | if strings.HasPrefix(text, "#") { 150 | if openCodeSection { 151 | buff.WriteString("\n```\n") 152 | openCodeSection = false 153 | } 154 | clean := strings.Replace(text, "#", "", -1) 155 | buff.WriteString(clean) 156 | buff.WriteString("\n") 157 | } else { 158 | if !openCodeSection { 159 | buff.WriteString("\n```sh\n") 160 | openCodeSection = true 161 | } 162 | buff.WriteString(text) 163 | buff.WriteString("\n") 164 | } 165 | } 166 | 167 | if openCodeSection { 168 | buff.WriteString("```\n") 169 | } 170 | 171 | return buff.String(), nil 172 | } 173 | 174 | func writeManifest(ex []*Example) error { 175 | b, err := json.MarshalIndent(ex, "", " ") 176 | if err != nil { 177 | return err 178 | } 179 | return ioutil.WriteFile("manifest.json", b, 0644) 180 | } 181 | 182 | func humanize(s string) string { 183 | out := strings.Replace(s, "_", " ", -1) 184 | if len(s) > 0 { 185 | return strings.ToUpper(string(out[0])) + out[1:] 186 | } 187 | return out 188 | } 189 | 190 | func markdownTitleLink(s string) string { 191 | return strings.ToLower(strings.Replace(s, " ", "-", -1)) 192 | } 193 | 194 | func splitTrim(s string) (out []string) { 195 | for _, e := range strings.Split(s, ",") { 196 | out = append(out, strings.TrimSpace(e)) 197 | } 198 | return 199 | } 200 | -------------------------------------------------------------------------------- /highly_available_wordpress_infra.aws: -------------------------------------------------------------------------------- 1 | # Title: Highly-available wordpress infrastructure 2 | # Tags: infra 3 | # MinimalVersion: v0.1.7 4 | 5 | # 1. Basic networking 6 | 7 | # VPC and its Internet gateway 8 | vpc = create vpc cidr=10.0.0.0/16 name=wordpress-ha-vpc 9 | igw = create internetgateway 10 | attach internetgateway id=$igw vpc=$vpc 11 | 12 | pubSub1 = create subnet cidr=10.0.100.0/24 vpc=$vpc name=wordpress-ha-public-subnet-1 availabilityzone={availabilityzone.1} 13 | update subnet id=$pubSub1 public=true 14 | pubSub2 = create subnet cidr=10.0.101.0/24 vpc=$vpc name=wordpress-ha-public-subnet-2 availabilityzone={availabilityzone.2} 15 | update subnet id=$pubSub2 public=true 16 | 17 | rt = create routetable vpc=$vpc 18 | create route table=$rt cidr=0.0.0.0/0 gateway=$igw 19 | attach routetable id=$rt subnet=$pubSub1 20 | attach routetable id=$rt subnet=$pubSub2 21 | 22 | # 2 private subnets in different AZs 23 | privSub1 = create subnet cidr=10.0.10.0/24 vpc=$vpc name=wordpress-ha-private-subnet-1 availabilityzone={availabilityzone.1} 24 | privSub2 = create subnet cidr=10.0.11.0/24 vpc=$vpc name=wordpress-ha-private-subnet-2 availabilityzone={availabilityzone.2} 25 | 26 | # NAT Gateway in public subnet with a fixed IP 27 | ip = create elasticip 28 | natgw = create natgateway elasticip-id=$ip subnet=$pubSub1 29 | check natgateway id=$natgw state=available timeout=180 30 | 31 | # Routing between private subnets and NAT gateway 32 | natgw_rtable = create routetable vpc=$vpc 33 | attach routetable id=$natgw_rtable subnet=$privSub1 34 | attach routetable id=$natgw_rtable subnet=$privSub2 35 | create route cidr=0.0.0.0/0 gateway=$natgw table=$natgw_rtable 36 | 37 | # 2. Provision loadbalancer 38 | 39 | # Create the load balancer security group 40 | lbsecgroup = create securitygroup vpc=$vpc description="authorize HTTP from the internet" name=wordpress-ha-lb-securitygroup 41 | update securitygroup id=$lbsecgroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=80 42 | 43 | # Provision the load balancer listening in the public subnets, with its target group and HTTP listener 44 | tg = create targetgroup name=wordpress-ha-workers port=80 protocol=HTTP vpc=$vpc 45 | update targetgroup id=$tg stickiness=true 46 | lb = create loadbalancer name=wordpress-ha-loadbalancer subnets=[$pubSub1,$pubSub2] securitygroups=$lbsecgroup 47 | create listener actiontype=forward loadbalancer=$lb port=80 protocol=HTTP targetgroup=$tg 48 | 49 | # 3. Provision instances 50 | 51 | # Create keypair and instance 52 | keypair = create keypair name={keypair.name} 53 | 54 | instSecGroup = create securitygroup vpc=$vpc description="HTTP + SSH within VPC" name=wordpress-ha-private-secgroup 55 | update securitygroup id=$instSecGroup inbound=authorize cidr=10.0.0.0/16 portrange=22 56 | update securitygroup id=$instSecGroup inbound=authorize cidr=10.0.0.0/16 portrange=80 57 | 58 | launchconf = create launchconfiguration distro=amazonlinux keypair=$keypair name=wordpress-ha-launch-configuration type={instance.type} userdata=https://raw.githubusercontent.com/zn3zman/AWS-WordPress-Creation/master/WP-Setup.sh securitygroups=$instSecGroup 59 | create scalinggroup desired-capacity=2 launchconfiguration=$launchconf max-size=2 min-size=2 name=wordpress-scalinggroup subnets=[$privSub1, $privSub2] targetgroups=$tg 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /install_awless_scheduler.aws: -------------------------------------------------------------------------------- 1 | # Launch new instance running remote user data script installing awless 2 | # CLIExample: awless run repo:install_awless_scheduler 3 | # MinimalVersion: v0.1.7 4 | 5 | create instance name={instance.name} distro=canonical:ubuntu type=t2.nano keypair={ssh.keypair} userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/ubuntu/install_awless_scheduler.sh role={role.name} -------------------------------------------------------------------------------- /instance_ssh.aws: -------------------------------------------------------------------------------- 1 | # Title: Create an instance accessible with ssh with a new keypair 2 | # Tags: infra, ssh 3 | 4 | # Create a new security group for this instance 5 | securitygroup = create securitygroup vpc={instance.vpc} description={securitygroup.description} name=ssh-from-internet 6 | # Authorize access on port 22 to instances in this security group 7 | update securitygroup id=$securitygroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=22 8 | 9 | # Create a new keypair 10 | keypair = create keypair name={keypair.name} 11 | 12 | # Create an instance in this security group accessible with the new keypair 13 | create instance subnet={instance.subnet} image={instance.image} type={instance.type} keypair=$keypair name={instance.name} count=1 securitygroup=$securitygroup 14 | -------------------------------------------------------------------------------- /instance_with_awless.aws: -------------------------------------------------------------------------------- 1 | # Title: Create an instance with preinstalled awless with completion 2 | # Tags: infra, awless 3 | 4 | # role name variable 5 | roleName = {awless.role-name} 6 | 7 | # Create a AWS role that applies on a resource 8 | create role name=$roleName principal-service="ec2.amazonaws.com" sleep-after=10 9 | 10 | # Attach typical necessary awless readonly permissions to the role 11 | attach policy role=$roleName service=ec2 access=readonly 12 | attach policy role=$roleName service=s3 access=readonly 13 | attach policy role=$roleName service=sns access=readonly 14 | attach policy role=$roleName service=sqs access=readonly 15 | attach policy role=$roleName service=vpc access=readonly 16 | attach policy role=$roleName service=autoscaling access=readonly 17 | attach policy role=$roleName service=iam access=readonly 18 | attach policy role=$roleName service=rds access=readonly 19 | attach policy role=$roleName service=route53 access=readonly 20 | attach policy role=$roleName service=lambda access=readonly 21 | 22 | # Launch new instance running remote user data script installing awless 23 | create instance name=awless-commander type=t2.nano keypair={ssh.keypair} userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/install_awless.yml role=$roleName -------------------------------------------------------------------------------- /instance_with_awless_scheduler.aws: -------------------------------------------------------------------------------- 1 | # Title: Create an instance with preconfigured awless and awless-scheduler 2 | # Tags: infra, awless, awless-scheduler 3 | 4 | # Awless scheduler role variable 5 | roleName = {awless-scheduler.role-name} 6 | 7 | # First we define a role that an EC2 instance can assume to use awless/awless-scheduler (write mode) 8 | create role name=$roleName principal-service="ec2.amazonaws.com" sleep-after=10 9 | 10 | # Attach typical necessary awless permissions to the role 11 | attach policy role=$roleName service=ec2 access=full 12 | attach policy role=$roleName service=s3 access=full 13 | attach policy role=$roleName service=sns access=full 14 | attach policy role=$roleName service=sqs access=full 15 | attach policy role=$roleName service=vpc access=full 16 | attach policy role=$roleName service=autoscaling access=full 17 | attach policy role=$roleName service=rds access=full 18 | attach policy role=$roleName service=route53 access=full 19 | attach policy role=$roleName service=lambda access=full 20 | 21 | # We keep IAM on read only mode 22 | attach policy role=$roleName service=iam access=readonly 23 | 24 | # Launch new instance running remote user data script installing awless 25 | create instance name=AwlessWithScheduler type=t2.nano keypair={ssh.keypair} userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/install_awless_suite.yml role=$roleName -------------------------------------------------------------------------------- /instance_with_tags_and_publicip.aws: -------------------------------------------------------------------------------- 1 | # Title: Create an instance with tags and public IP 2 | # Description: Create an instance with mulitple tags and attach to it an elastic IP 3 | 4 | inst = create instance subnet={instance.subnet} image={instance.image} type={instance.type} keypair={instance.keypair} name={instance.name} securitygroup={instance.securitygroup} 5 | 6 | # Putting a tag on the instance 7 | create tag resource=$inst key={instance.tagkey} value={instance.tagvalue} 8 | 9 | # Creating a elastic IP 10 | pubip = create elasticip domain=vpc 11 | 12 | # Attaching the IP onto the instance 13 | attach elasticip id=$pubip instance=$inst -------------------------------------------------------------------------------- /kafka_infra.aws: -------------------------------------------------------------------------------- 1 | # Title: Create a classic Kafka infra 2 | # Description: Create a classic Kafka infra: brokers, 1 zookeeper instance 3 | # CLIExample: awless run repo:kafka_infra remote-access.cidr=$(awless whoami --ip-only)/32 broker.instance.type=t2.medium zookeeper.instance.type=t2.medium 4 | # MinimalVersion: v0.1.7 5 | 6 | # Create the VPC and its internet gateway 7 | vpc = create vpc cidr=10.0.0.0/16 name=kafka-vpc 8 | igw = create internetgateway 9 | attach internetgateway id=$igw vpc=$vpc 10 | 11 | # Create a public subnet 12 | subnet_cidr = 10.0.0.0/24 13 | subnet = create subnet cidr=$subnet_cidr vpc=$vpc name=kafka-subnet 14 | update subnet id=$subnet public=true 15 | routetable = create routetable vpc=$vpc 16 | attach routetable subnet=$subnet id=$routetable 17 | create route cidr=0.0.0.0/0 gateway=$igw table=$routetable 18 | 19 | # Create securitygroup for SSH: opening port 22 for all IPs 20 | sshsecgroup = create securitygroup vpc=$vpc description=SSHSecurityGroup name=SSHSecurityGroup 21 | update securitygroup id=$sshsecgroup inbound=authorize protocol=tcp cidr={remote-access.cidr} portrange=22 22 | 23 | # Create securitygroup for Kafka instances (brokers & zookeeper) 24 | kafkasecgroup = create securitygroup vpc=$vpc description=KafkaSecurityGroup name=KafkaSecurityGroup 25 | update securitygroup id=$kafkasecgroup inbound=authorize protocol=tcp cidr=$subnet_cidr portrange=0-65535 26 | 27 | # Create a role with policy for ec2 resources so that an instance can list other instances using a local `awless` 28 | create role name=EC2ReadonlyRole principal-service="ec2.amazonaws.com" sleep-after=20 29 | attach policy role=EC2ReadonlyRole service=ec2 access=readonly 30 | 31 | # Create Zookeeper instance with security groups attached 32 | zookeeper = create instance name=zookeeper distro=redhat type={zookeeper.instance.type} keypair={keypair.name} subnet=$subnet securitygroup=[$sshsecgroup,$kafkasecgroup] userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/redhat/zookeeper.sh 33 | 34 | # Wait the Zookeeper instance is up and running 35 | check instance id=$zookeeper state=running timeout=180 36 | 37 | # Create Kafka broker instances with role created above and security groups attached 38 | broker_1 = create instance name=broker_1 distro=redhat type={broker.instance.type} keypair={keypair.name} subnet=$subnet role=EC2ReadonlyRole securitygroup=[$sshsecgroup,$kafkasecgroup] userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/redhat/kafka.sh 39 | broker_2 = create instance name=broker_2 distro=redhat type={broker.instance.type} keypair={keypair.name} subnet=$subnet role=EC2ReadonlyRole securitygroup=[$sshsecgroup,$kafkasecgroup] userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/redhat/kafka.sh 40 | broker_3 = create instance name=broker_3 distro=redhat type={broker.instance.type} keypair={keypair.name} subnet=$subnet role=EC2ReadonlyRole securitygroup=[$sshsecgroup,$kafkasecgroup] userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/redhat/kafka.sh -------------------------------------------------------------------------------- /linux_bastion.aws: -------------------------------------------------------------------------------- 1 | # Title: Create VPC with a Linux host bastion 2 | # Tags: infra 3 | # Description: This template build this typical Linux bastion [architecture](http://docs.aws.amazon.com/quickstart/latest/linux-bastion/architecture.html) except it only deploys one host bastion on one public subnet 4 | # MinimalVersion: v0.1.3 5 | 6 | # Create a new VPC and make it public with an internet gateway 7 | vpc = create vpc cidr=10.0.0.0/16 name=BastionVpc 8 | gateway = create internetgateway 9 | attach internetgateway id=$gateway vpc=$vpc 10 | 11 | # Create 2 private subnets each on a different availability zone 12 | # That is where you will deploy resources only accessible through the bastion 13 | create subnet cidr=10.0.0.0/19 name=PrivSubnet1 vpc=$vpc availabilityzone={availabilityzone.1} 14 | create subnet cidr=10.0.32.0/19 name=PrivSubnet2 vpc=$vpc availabilityzone={availabilityzone.2} 15 | 16 | # Create the the public subnet hosting the bastion 17 | pubSubnet = create subnet cidr=10.0.128.0/20 name=PubSubnet1 vpc=$vpc availabilityzone={availabilityzone.1} 18 | update subnet id=$pubSubnet public=true 19 | 20 | # Create a route table (with routing only allowed within VPC by default) 21 | rtable = create routetable vpc=$vpc 22 | 23 | # Make the public subnet use the route table 24 | attach routetable id=$rtable subnet=$pubSubnet 25 | 26 | create route cidr=0.0.0.0/0 gateway=$gateway table=$rtable 27 | 28 | # Create the firewall with the remote access CIDR applied on each bastion host 29 | bastionSecGroup = create securitygroup vpc=$vpc description=BastionSecGroup name=bastion-secgroup 30 | update securitygroup id=$bastionSecGroup inbound=authorize protocol=tcp cidr={remoteaccess-cidr} portrange=22 31 | update securitygroup id=$bastionSecGroup inbound=authorize protocol=icmp cidr={remoteaccess-cidr} portrange=any 32 | 33 | # Allow only a set of permitted actions for the 2 host bastions 34 | create role name=BastionHostRole principal-service=ec2.amazonaws.com sleep-after=30 35 | bastionEc2Policy = create policy name=BastionEc2Permissions action=[ec2:DescribeAddresses,ec2:AssociateAddress] resource="*" effect=Allow 36 | attach policy role=BastionHostRole arn=$bastionEc2Policy 37 | 38 | # Create one elastic IPs for that will be dynamically aasigned to the host bastion by the bootstrap script 39 | create elasticip domain=vpc 40 | 41 | # Create the autoscaling group 42 | launchConfig = create launchconfiguration image={instance.image} keypair={keypair.name} securitygroups=$bastionSecGroup name=BastionHostsLaunchConfig type=t2.micro role=BastionHostRole userdata=https://raw.githubusercontent.com/wallix/awless-templates/master/userdata/prepare_bastion.yml 43 | create scalinggroup desired-capacity=1 launchconfiguration=$launchConfig max-size=1 min-size=1 name=autoscaling-instances-group subnets=$pubSubnet -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Title": "ECS Autoscaling Cluster", 4 | "Description": "Note that the AMI in this template is working only in eu-west-1 region", 5 | "MinimalVersion": "v0.1.3", 6 | "Tags": [ 7 | "autoscaling", 8 | "container", 9 | "infra" 10 | ], 11 | "Name": "ECS_autoscaling_cluster", 12 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/ECS_autoscaling_cluster.aws" 13 | }, 14 | { 15 | "Title": "Awless readonly group", 16 | "Name": "awless_readonly_group", 17 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/awless_readonly_group.aws" 18 | }, 19 | { 20 | "Title": "Pre-defined policies for awless users", 21 | "Description": "Useful pre-defined readonly \u0026 readwrite policies for awless users", 22 | "MinimalVersion": "v0.1.3", 23 | "Name": "awless_readonly_policies", 24 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/awless_readonly_policies.aws" 25 | }, 26 | { 27 | "Title": "Awless readwrite group", 28 | "Name": "awless_readwrite_group", 29 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/awless_readwrite_group.aws" 30 | }, 31 | { 32 | "Title": "Create a postgres instance", 33 | "Description": "Create a private basic postgres instance with firewall. As an example, instance has only basic required properties filled in", 34 | "MinimalVersion": "v0.1.7", 35 | "Name": "db_postgres", 36 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/db_postgres.aws" 37 | }, 38 | { 39 | "Title": "Group of instances scaling with CPU consumption", 40 | "Description": "Create an autoscaling group of instances and watch their CPU to dynamically allocate/delete instances when needed.", 41 | "Tags": [ 42 | "infra", 43 | "autoscaling" 44 | ], 45 | "Name": "dynamic_autoscaling_watching_CPU", 46 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/dynamic_autoscaling_watching_CPU.aws" 47 | }, 48 | { 49 | "Title": "Highly-available wordpress infrastructure", 50 | "MinimalVersion": "v0.1.7", 51 | "Tags": [ 52 | "infra" 53 | ], 54 | "Name": "highly_available_wordpress_infra", 55 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/highly_available_wordpress_infra.aws" 56 | }, 57 | { 58 | "Title": "Install awless scheduler", 59 | "CLIExample": "awless run repo:install_awless_scheduler", 60 | "MinimalVersion": "v0.1.7", 61 | "Name": "install_awless_scheduler", 62 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/install_awless_scheduler.aws" 63 | }, 64 | { 65 | "Title": "Create an instance accessible with ssh with a new keypair", 66 | "Tags": [ 67 | "infra", 68 | "ssh" 69 | ], 70 | "Name": "instance_ssh", 71 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/instance_ssh.aws" 72 | }, 73 | { 74 | "Title": "Create an instance with preinstalled awless with completion", 75 | "Tags": [ 76 | "infra", 77 | "awless" 78 | ], 79 | "Name": "instance_with_awless", 80 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/instance_with_awless.aws" 81 | }, 82 | { 83 | "Title": "Create an instance with preconfigured awless and awless-scheduler", 84 | "Tags": [ 85 | "infra", 86 | "awless", 87 | "awless-scheduler" 88 | ], 89 | "Name": "instance_with_awless_scheduler", 90 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/instance_with_awless_scheduler.aws" 91 | }, 92 | { 93 | "Title": "Create an instance with tags and public IP", 94 | "Description": "Create an instance with mulitple tags and attach to it an elastic IP", 95 | "Name": "instance_with_tags_and_publicip", 96 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/instance_with_tags_and_publicip.aws" 97 | }, 98 | { 99 | "Title": "Create a classic Kafka infra", 100 | "CLIExample": "awless run repo:kafka_infra remote-access.cidr=$(awless whoami --ip-only)/32 broker.instance.type=t2.medium zookeeper.instance.type=t2.medium", 101 | "Description": "Create a classic Kafka infra: brokers, 1 zookeeper instance", 102 | "MinimalVersion": "v0.1.7", 103 | "Name": "kafka_infra", 104 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/kafka_infra.aws" 105 | }, 106 | { 107 | "Title": "Create VPC with a Linux host bastion", 108 | "Description": "This template build this typical Linux bastion [architecture](http://docs.aws.amazon.com/quickstart/latest/linux-bastion/architecture.html) except it only deploys one host bastion on one public subnet", 109 | "MinimalVersion": "v0.1.3", 110 | "Tags": [ 111 | "infra" 112 | ], 113 | "Name": "linux_bastion", 114 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/linux_bastion.aws" 115 | }, 116 | { 117 | "Title": "Create a dbsubnetgroups", 118 | "CLIExample": "run repo:new_dbsubnetgroup.draft first.subnet.cidr=10.0.0.0/25 first.subnet.availabilityzone=us-west-1a second.subnet.cidr=10.0.0.128/25 second.subnet.availabilityzone=us-west-1c vpc.cidr=10.0.0.0/24 vpc.name=myvpc", 119 | "Description": "Create 2 subnets on different availability zones to later on constitute the dbsubnet group", 120 | "Name": "new_dbsubnetgroup", 121 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/new_dbsubnetgroup.aws" 122 | }, 123 | { 124 | "Title": "Attach usual readonly AWS policies (set of permissions) on group", 125 | "Description": "When you want your users to have a set of permissions, instead of attaching permissions directly on users it is a good practice and simpler to define a group having those permissions and then adding/removing as needed users from those groups.", 126 | "Tags": [ 127 | "access", 128 | "policy", 129 | "role" 130 | ], 131 | "Name": "policies_on_group", 132 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/policies_on_group.aws" 133 | }, 134 | { 135 | "Title": "Create a public network enabling routing from the Internet", 136 | "Tags": [ 137 | "infra" 138 | ], 139 | "Name": "public_subnet", 140 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/public_subnet.aws" 141 | }, 142 | { 143 | "Title": "Create a AWS role with usual readonly policies that applies on a resource", 144 | "Description": "Create a AWS role that applies on a resource (retrieve the account id with `awless whoami`)", 145 | "Tags": [ 146 | "access", 147 | "policy", 148 | "role" 149 | ], 150 | "Name": "role_for_resource", 151 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/role_for_resource.aws" 152 | }, 153 | { 154 | "Title": "Create a AWS role with usual readonly policies that applies on a user", 155 | "Description": "Create a AWS role that applies on a user (retrieve the id with `awless whoami`)", 156 | "Tags": [ 157 | "access", 158 | "policy", 159 | "user" 160 | ], 161 | "Name": "role_for_user", 162 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/role_for_user.aws" 163 | }, 164 | { 165 | "Title": "Create a static website on S3", 166 | "Tags": [ 167 | "s3" 168 | ], 169 | "Name": "s3website", 170 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/s3website.aws" 171 | }, 172 | { 173 | "Title": "Simple wordpress deployment", 174 | "Tags": [ 175 | "infra" 176 | ], 177 | "Name": "simple_wordpress_infra", 178 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/simple_wordpress_infra.aws" 179 | }, 180 | { 181 | "Title": "Upload Image from local file", 182 | "Description": "This template uploads on s3 a local VM file (VHD, OVA, VMDK). Then it creates an AMI from the S3 object.", 183 | "Tags": [ 184 | "infra", 185 | "s3" 186 | ], 187 | "Name": "upload_image", 188 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/upload_image.aws" 189 | }, 190 | { 191 | "Title": "Create a user with its SDK/Shell access key and console password", 192 | "Tags": [ 193 | "access", 194 | "user" 195 | ], 196 | "Name": "user", 197 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/user.aws" 198 | }, 199 | { 200 | "Title": "Create a VPC with its internet routing gateway", 201 | "Tags": [ 202 | "infra", 203 | "VPC" 204 | ], 205 | "Name": "vpc", 206 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/vpc.aws" 207 | }, 208 | { 209 | "Title": "Create a VPC with 3 internal subnets", 210 | "Name": "vpc_with_subnets", 211 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/vpc_with_subnets.aws" 212 | }, 213 | { 214 | "Title": "Highly-available wordpress behind a loadbalancer, with a RDS database", 215 | "MinimalVersion": "v0.1.1", 216 | "Tags": [ 217 | "infra", 218 | "rds", 219 | "autoscaling" 220 | ], 221 | "Name": "wordpress_ha", 222 | "Link": "https://raw.githubusercontent.com/wallix/awless-templates/master/wordpress_ha.aws" 223 | } 224 | ] -------------------------------------------------------------------------------- /new_dbsubnetgroup.aws: -------------------------------------------------------------------------------- 1 | # Title: Create a dbsubnetgroups 2 | # Description: Create 2 subnets on different availability zones to later on constitute the dbsubnet group 3 | # CLIExample: run repo:new_dbsubnetgroup.draft first.subnet.cidr=10.0.0.0/25 first.subnet.availabilityzone=us-west-1a second.subnet.cidr=10.0.0.128/25 second.subnet.availabilityzone=us-west-1c vpc.cidr=10.0.0.0/24 vpc.name=myvpc 4 | 5 | # Create a new VPC open to Internet to host the subnets 6 | vpc = create vpc cidr={vpc.cidr} name={vpc.name} 7 | gateway = create internetgateway 8 | attach internetgateway id=$gateway vpc=$vpc 9 | 10 | firstsubnet = create subnet cidr={first.subnet.cidr} vpc=$vpc name={first.subnet.name} availabilityzone={first.subnet.availabilityzone} 11 | update subnet id=$firstsubnet public=true 12 | 13 | secondsubnet = create subnet cidr={second.subnet.cidr} vpc=$vpc name={second.subnet.name} availabilityzone={second.subnet.availabilityzone} 14 | update subnet id=$secondsubnet public=true 15 | 16 | # Create a route table for this network 17 | rtable = create routetable vpc=$vpc 18 | 19 | # Make the subnets open to the Internet (through vpc that has an internetgateway) 20 | attach routetable id=$rtable subnet=$firstsubnet 21 | attach routetable id=$rtable subnet=$secondsubnet 22 | 23 | create dbsubnetgroup name={dbsubnetgroup.name} description={dbsubnetgroup.description} subnets=[$firstsubnet, $secondsubnet] 24 | -------------------------------------------------------------------------------- /policies_on_group.aws: -------------------------------------------------------------------------------- 1 | # Title: Attach usual readonly AWS policies (set of permissions) on group 2 | # Tags: access, policy, role 3 | # Description: When you want your users to have a set of permissions, instead of attaching permissions directly on users it is a good practice and simpler to define a group having those permissions and then adding/removing as needed users from those groups. 4 | 5 | attach policy service=ec2 access=readonly group={group-name} 6 | attach policy service=s3 access=readonly group={group-name} 7 | attach policy service=sns access=readonly group={group-name} 8 | attach policy service=sqs access=readonly group={group-name} 9 | attach policy service=vpc access=readonly group={group-name} 10 | attach policy service=autoscaling access=readonly group={group-name} 11 | attach policy service=iam access=readonly group={group-name} 12 | attach policy service=rds access=readonly group={group-name} 13 | attach policy service=route53 access=readonly group={group-name} -------------------------------------------------------------------------------- /public_subnet.aws: -------------------------------------------------------------------------------- 1 | # Title: Create a public network enabling routing from the Internet 2 | # Tags: infra 3 | 4 | # Create the subnet 5 | subnet = create subnet cidr={subnet.cidr} vpc={subnet.vpc} name={subnet.name} 6 | # Allow instances in this network to have public IP addresses 7 | update subnet id=$subnet public=true 8 | 9 | # Create a route table for this network 10 | rtable = create routetable vpc={subnet.vpc} 11 | attach routetable id=$rtable subnet=$subnet 12 | 13 | # Enable routing from the Internet to this subnet 14 | create route cidr=0.0.0.0/0 gateway={vpc.internetgateway} table=$rtable 15 | -------------------------------------------------------------------------------- /role_for_resource.aws: -------------------------------------------------------------------------------- 1 | # Title: Create a AWS role with usual readonly policies that applies on a resource 2 | # Tags: access, policy, role 3 | # Description: Create a AWS role that applies on a resource (retrieve the account id with `awless whoami`) 4 | 5 | roleName = {role-name} 6 | 7 | create role name=$roleName principal-service={aws-service} 8 | 9 | # Attach policy (set of permissions) to the created role 10 | attach policy role=$roleName service=ec2 access=readonly 11 | attach policy role=$roleName service=s3 access=readonly 12 | attach policy role=$roleName service=sns access=readonly 13 | attach policy role=$roleName service=sqs access=readonly 14 | attach policy role=$roleName service=vpc access=readonly 15 | attach policy role=$roleName service=autoscaling access=readonly 16 | attach policy role=$roleName service=iam access=readonly 17 | attach policy role=$roleName service=rds access=readonly 18 | attach policy role=$roleName service=route53 access=readonly 19 | -------------------------------------------------------------------------------- /role_for_user.aws: -------------------------------------------------------------------------------- 1 | # Title: Create a AWS role with usual readonly policies that applies on a user 2 | # Tags: access, policy, user 3 | # Description: Create a AWS role that applies on a user (retrieve the id with `awless whoami`) 4 | 5 | newRole = create role name={role-name} principal-account={aws-account-id} 6 | 7 | # Attach policy (set of permissions) to the created role 8 | attach policy role={role-name} service=ec2 access=readonly 9 | attach policy role={role-name} service=s3 access=readonly 10 | attach policy role={role-name} service=sns access=readonly 11 | attach policy role={role-name} service=sqs access=readonly 12 | attach policy role={role-name} service=vpc access=readonly 13 | attach policy role={role-name} service=autoscaling access=readonly 14 | attach policy role={role-name} service=iam access=readonly 15 | attach policy role={role-name} service=rds access=readonly 16 | attach policy role={role-name} service=route53 access=readonly 17 | 18 | # Create a policy to allow user with this policy to assume only this role 19 | # You can then attach this policy to a user via `awless attach policy arn=... user=jsmith` 20 | create policy name={assume-policy-name} effect=Allow action=sts:AssumeRole resource=$newRole 21 | -------------------------------------------------------------------------------- /s3website.aws: -------------------------------------------------------------------------------- 1 | # Title: Create a static website on S3 2 | # Tags: s3 3 | 4 | # Create the bucket where files will be stored 5 | create bucket name={domain.name} acl=public-read 6 | 7 | # Publish this s3bucket as a website 8 | update bucket name={domain.name} public-website=true redirect-hostname={domain.name} 9 | 10 | # Add files to the bucket with 11 | # awless create s3object bucket={domain.name} file={input-file-path} acl=public-read 12 | -------------------------------------------------------------------------------- /simple_wordpress_infra.aws: -------------------------------------------------------------------------------- 1 | # Title: Simple wordpress deployment 2 | # Tags: infra 3 | 4 | # VPC and its Internet gateway 5 | vpc = create vpc cidr=10.0.0.0/16 name=wordpress-vpc 6 | igw = create internetgateway 7 | attach internetgateway id=$igw vpc=$vpc 8 | 9 | # Subnet and its route table 10 | subnet = create subnet cidr=10.0.0.0/24 vpc=$vpc name=wordpress-subnet 11 | update subnet id=$subnet public=true 12 | routetable = create routetable vpc=$vpc 13 | attach routetable subnet=$subnet id=$routetable 14 | create route cidr=0.0.0.0/0 gateway=$igw table=$routetable 15 | 16 | # Create a security group and authorize accesses from the Internet for port 22 and 80 17 | secgroup = create securitygroup vpc=$vpc description="authorize ssh and http from internet" name=wordpress-secgroup 18 | update securitygroup id=$secgroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=22 19 | update securitygroup id=$secgroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=80 20 | 21 | # Create keypair and instance 22 | keypair = create keypair name={keypair.name} 23 | create instance name=wordpress-instance subnet=$subnet keypair=$keypair securitygroup=$secgroup userdata=https://raw.githubusercontent.com/zn3zman/AWS-WordPress-Creation/master/WP-Setup.sh 24 | -------------------------------------------------------------------------------- /upload_image.aws: -------------------------------------------------------------------------------- 1 | # Title: Upload Image from local file 2 | # Tags: infra, s3 3 | # Description: This template uploads on s3 a local VM file (VHD, OVA, VMDK). Then it creates an AMI from the S3 object. 4 | 5 | # Upload the image on s3 6 | bucket = {image.bucket} 7 | imageObject = create s3object bucket=$bucket file={image.filepath} 8 | 9 | # Create the AMI from the object on S3 10 | import image description={image.description} bucket=$bucket s3object=$imageObject -------------------------------------------------------------------------------- /user.aws: -------------------------------------------------------------------------------- 1 | # Title: Create a user with its SDK/Shell access key and console password 2 | # Tags: access, user 3 | 4 | username = {user.name} 5 | 6 | # Create user 7 | create user name=$username 8 | 9 | # Create AWS Console password 10 | create loginprofile username=$username password={user.console-password} 11 | 12 | # Create SDK/shell access key 13 | create accesskey user=$username -------------------------------------------------------------------------------- /userdata/install_awless.yml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | repo_update: true 3 | repo_upgrade: all 4 | 5 | yum_repos: 6 | epel_custom: 7 | name: Extra Packages for Enterprise Linux 6 - $basearch 8 | baseurl: http://download.fedoraproject.org/pub/epel/6/$basearch 9 | mirrorlist: https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch 10 | failovermethod: priority 11 | enabled: true 12 | gpgcheck: true 13 | gpgkey: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 14 | 15 | packages: 16 | - bash-completion 17 | - curl 18 | 19 | runcmd: 20 | - [curl, -O, "https://raw.githubusercontent.com/wallix/awless/master/getawless.sh"] 21 | - /bin/bash getawless.sh 22 | - mv awless /usr/bin 23 | - [sed, -i, "$ a\\source <(awless completion bash)", /etc/bashrc] -------------------------------------------------------------------------------- /userdata/install_awless_suite.yml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | repo_update: true 3 | repo_upgrade: all 4 | 5 | yum_repos: 6 | epel_custom: 7 | name: Extra Packages for Enterprise Linux 6 - $basearch 8 | baseurl: http://download.fedoraproject.org/pub/epel/6/$basearch 9 | mirrorlist: https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch 10 | failovermethod: priority 11 | enabled: true 12 | gpgcheck: true 13 | gpgkey: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 14 | 15 | packages: 16 | - bash-completion 17 | - curl 18 | - docker 19 | 20 | runcmd: 21 | - [curl, -O, "https://raw.githubusercontent.com/wallix/awless/master/getawless.sh"] 22 | - /bin/bash getawless.sh 23 | - mv awless /usr/bin 24 | - [sed, -i, "$ a\\source <(awless completion bash)", /etc/bashrc] 25 | - service docker start 26 | - [docker, run, -d, --name, awless-scheduler, --restart=always, -p, "127.0.0.1:8082-8083:8082-8083", -v, "/var/awless-scheduler:/root/.awless-scheduler", wallix/awless-scheduler] -------------------------------------------------------------------------------- /userdata/prepare_bastion.yml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | repo_update: true 3 | repo_upgrade: all 4 | 5 | packages: 6 | - epel-release 7 | - curl 8 | - python-pip 9 | 10 | runcmd: 11 | - export PATH=$PATH:/usr/local/bin 12 | - pip install --upgrade pip 13 | - pip install awscli --ignore-installed six 14 | - [easy_install, "https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz"] 15 | - [curl, -O, "https://s3.amazonaws.com/quickstart-reference/linux/bastion/latest/scripts/bastion_bootstrap.sh"] 16 | - /bin/bash bastion_bootstrap.sh -- --tcp-forwarding true --enable false -------------------------------------------------------------------------------- /userdata/redhat/kafka.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | yum -y install java 4 | 5 | curl https://raw.githubusercontent.com/wallix/awless/master/getawless.sh | bash 6 | mv awless /usr/bin 7 | 8 | ZOOKEEPER_IP=$(/usr/bin/awless ls instances --filter name=zookeeper --filter state=run --format csv | tail -1 | cut -d, -f7) 9 | 10 | KAFKA_DOWNLOAD=kafka_2.12-1.0.0 11 | 12 | curl -O http://apache.mediamirrors.org/kafka/1.0.0/$KAFKA_DOWNLOAD.tgz 13 | 14 | tar -zxvf $KAFKA_DOWNLOAD.tgz -C /opt 15 | ln -s /opt/$KAFKA_DOWNLOAD /opt/kafka 16 | 17 | mkdir /tmp/kafka-logs 18 | 19 | INSTANCE_IP=$(curl http://169.254.169.254/latest/meta-data/local-ipv4) 20 | INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id) 21 | BROKER_ID=$(/usr/bin/awless ls instances --filter name=broker --sort name --format tsv --no-headers | grep $INSTANCE_ID -n | cut -d: -f1) 22 | 23 | sed -i "s/zookeeper.connect=.*/zookeeper.connect=$ZOOKEEPER_IP:2181/" /opt/kafka/config/server.properties 24 | sed -i "s/broker.id=.*/broker.id=$BROKER_ID/" /opt/kafka/config/server.properties 25 | sed -i "s_#listeners=PLAINTEXT://:9092_listeners=PLAINTEXT://$INSTANCE_IP:9092_" /opt/kafka/config/server.properties 26 | 27 | nohup /opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/server.properties > /dev/null 2>&1 & -------------------------------------------------------------------------------- /userdata/redhat/zookeeper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | yum -y install java 4 | 5 | KAFKA_DOWNLOAD=kafka_2.12-1.0.0 6 | 7 | curl -O http://apache.mediamirrors.org/kafka/1.0.0/$KAFKA_DOWNLOAD.tgz 8 | 9 | tar -zxvf $KAFKA_DOWNLOAD.tgz -C /opt 10 | ln -s /opt/$KAFKA_DOWNLOAD /opt/kafka 11 | 12 | nohup /opt/kafka/bin/zookeeper-server-start.sh /opt/kafka/config/zookeeper.properties > /dev/null 2>&1 & -------------------------------------------------------------------------------- /userdata/ubuntu/cockroach_haproxy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | apt-get -y install haproxy 4 | 5 | curl https://raw.githubusercontent.com/wallix/awless/master/getawless.sh | bash 6 | 7 | NODE_1_IP=$(./awless ls instances --filter name=cockroachdb-node-1 --filter state=running --format tsv --no-headers | cut -f7) 8 | NODE_2_IP=$(./awless ls instances --filter name=cockroachdb-node-2 --filter state=running --format tsv --no-headers | cut -f7) 9 | NODE_3_IP=$(./awless ls instances --filter name=cockroachdb-node-3 --filter state=running --format tsv --no-headers | cut -f7) 10 | 11 | rm awless 12 | 13 | /bin/cat > haproxy.cfg < ./wp-config.php <<-EOF 90 | ./wp-config.php <<-EOF 80 | > $PROFILE_PATH 73 | echo "export PATH=\$PATH:/usr/local/go/bin:\$HOME/go/bin" >> $PROFILE_PATH 74 | 75 | # Generate SSH key for remotes scans. Public key need to be added to ~/.ssh/authorized_keys on remote hosts to be scanned 76 | ssh-keygen -t rsa -N "" -f $USER_HOME/.ssh/id_rsa 77 | 78 | # Prepare toml local files for remote scans 79 | /bin/cat > $USER_HOME/config.toml < $USER_HOME/$FETCH_DATA_FILENAME <