From f830dce7b642d4e37c69db67380132c98e9e79ae Mon Sep 17 00:00:00 2001 From: taherbs Date: Thu, 15 Nov 2018 12:03:13 +0100 Subject: [PATCH 1/2] adding make file automation + cloudformation iam profile creation + updating the locust version --- .ebextensions/resources.config | 4 +-- .ebextensions/setup.config | 5 ++- .env.sample | 13 ++++++++ .gitignore | 7 ++++ Makefile | 60 ++++++++++++++++++++++++++++++++++ README.md | 45 +++++++++++++++++++++++++ iam-profile.yaml | 48 +++++++++++++++++++++++++++ policy.json | 2 +- 8 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 .env.sample create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 iam-profile.yaml diff --git a/.ebextensions/resources.config b/.ebextensions/resources.config index 6f1f318..f89a0a9 100644 --- a/.ebextensions/resources.config +++ b/.ebextensions/resources.config @@ -21,7 +21,7 @@ Resources: Properties: FromPort: "9876" ToPort: "9876" - GroupName: { "Ref": "AWSEBSecurityGroup" } + GroupId: { "Fn::GetAtt": ["AWSEBSecurityGroup", "GroupId"] } IpProtocol: "tcp" SourceSecurityGroupId: { "Fn::GetAtt": ["AWSEBSecurityGroup", "GroupId"] } FollowerToMaster: @@ -29,6 +29,6 @@ Resources: Properties: FromPort: "5557" ToPort: "5558" - GroupName: { "Ref": "AWSEBSecurityGroup" } + GroupId: { "Fn::GetAtt": ["AWSEBSecurityGroup", "GroupId"] } IpProtocol: "tcp" SourceSecurityGroupId: { "Fn::GetAtt": ["AWSEBSecurityGroup", "GroupId"] } diff --git a/.ebextensions/setup.config b/.ebextensions/setup.config index 0638058..e9c4014 100644 --- a/.ebextensions/setup.config +++ b/.ebextensions/setup.config @@ -14,9 +14,12 @@ packages: gcc-c++: [] python: pyzmq: [ "16.0.3" ] - locustio: [ "0.8.1" ] + locustio: [ "0.9.0" ] + bs4: [] option_settings: + aws:elasticbeanstalk:command: + DeploymentPolicy: AllAtOnce aws:elasticbeanstalk:application:environment: MASTER_IP_TABLE: '`{ "Ref" : "MasterIPTable"}`' EB_ENV_NAME: '`{"Ref" : "AWSEBEnvironmentName"}`' diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..27b5546 --- /dev/null +++ b/.env.sample @@ -0,0 +1,13 @@ +# Service configuration variables + +LOCUST_TARGET_URL = "https://www.YourWebSite.com" # Set the target website URL +SERVICE_PROFILE_NAME="elasticbeanstalk-locust-profile" # Keep this as default +SERVICE_PROFILE_FILE_PATH = "./iam-profile.yaml" # Keep this as default +SERVICE_INSTANCE_TYPE="c3.large" +SERVICE_REGION = "eu-west-1" +SERVICE_SCALE = "10" +SERVICE_ENV = "test" +SERVICE_CNAME = "$(SERVICE_ENV)-taherbs-locust" +SERVICE_VPC = vpc-XXXXXX #Eb app VPC ID +SERVICE_EC2_SUBNETS = subnet-XXXXXX #Eb app EC2 subnets +SERVICE_ELB_SUBNESTS = subnet-XXXXXX #Eb app ALB subnets diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1d354ef --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.elasticbeanstalk/* +!.elasticbeanstalk/*.cfg.yml +!.elasticbeanstalk/*.global.yml +.virtualenv +.env +site-locustfile.py +.DS_Store diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..28c47e7 --- /dev/null +++ b/Makefile @@ -0,0 +1,60 @@ +# makefile for automating service deployment + +# Load env vars +include .env +VARS:=$(shell sed -ne 's/ *\#.*$$//; /./ s/=.*$$// p' .env ) +$(foreach v,$(VARS),$(eval $(shell echo export $(v)="$($(v))"))) + +.PHONY: profile-create +profile-create: + aws cloudformation create-stack --stack-name $(SERVICE_PROFILE_NAME) \ + --region $(SERVICE_REGION) \ + --template-body file://$(SERVICE_PROFILE_FILE_PATH) \ + --parameters ParameterKey=InstanceProfileName,ParameterValue=$(SERVICE_PROFILE_NAME) \ + --capabilities CAPABILITY_NAMED_IAM + aws cloudformation wait stack-create-complete --stack-name $(SERVICE_PROFILE_NAME) \ + --region $(SERVICE_REGION) + echo "elasticbeanstalk-locust-role stack created..." + +.PHONY: profile-delete +profile-delete: + aws cloudformation delete-stack --stack-name $(SERVICE_PROFILE_NAME) \ + --region $(SERVICE_REGION) + aws cloudformation wait stack-delete-complete --stack-name $(SERVICE_PROFILE_NAME) \ + --region $(SERVICE_REGION) + echo "elasticbeanstalk-locust-role stack deleted..." + +.PHONY: profile-check +profile-check: + aws iam get-instance-profile --instance-profile-name $(SERVICE_PROFILE_NAME) 1>/dev/null + +.PHONY: eb-init +eb-init: + eb init -r $(SERVICE_REGION) -p "Java 8" + +.PHONY: eb-deploy +eb-deploy: profile-check eb-init + eb create --instance_type $(SERVICE_INSTANCE_TYPE) \ + --scale $(SERVICE_SCALE) \ + --instance_profile $(SERVICE_PROFILE_NAME) \ + --cname $(SERVICE_CNAME) \ + --branch_default $(SERVICE_ENV) \ + --vpc.id $(SERVICE_VPC) \ + --vpc.ec2subnets $(SERVICE_EC2_SUBNETS) \ + --vpc.elbsubnets $(SERVICE_ELB_SUBNESTS) \ + --vpc.elbpublic --vpc.publicip \ + --envvars TARGET_URL=$(LOCUST_TARGET_URL) \ + --region $(SERVICE_REGION) + +.PHONY: eb-update +eb-update: + eb setenv TARGET_URL=$(LOCUST_TARGET_URL) + eb scale $(SERVICE_SCALE) + eb deploy --staged + +.PHONY: eb-terminate +eb-terminate: + eb terminate --all --force + +.PHONY: terminate-all +terminate-all: eb-terminate profile-delete diff --git a/README.md b/README.md index 3d11e18..92e325b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,38 @@ # AWS Elastic Beanstalk Load Generator Example This sample application uses the [Locust](http://locust.io/) open source load testing tool to create a simple load generator for your applications. The sample test definition *[locustfile.py](locustfile.py)* tests the root of an endpoint passed in as an environment variable *(TARGET_URL)*. For more information on the format of the test definition file, see [Writing a locustfile](http://docs.locust.io/en/latest/writing-a-locustfile.html). +## Requirements: +[AWS Elastic Beanstalk Command Line Interface (CLI)](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install.html) + +## Usage: + +### Automated Deployment + + 1. Edit/create the *[.env](.env.sample)* file and specify any/all configuration settings for your environment. + + 2. Create IAM Instance Profile + ```bash + make profile-create + ``` + + 3. Deploy the Elastic Beanstalk service + ```bash + make eb-deploy + ``` + + 4. If want to update the target url, update the LOCUST_TARGET_URL attribute in the *[.env](.env)* file then run: + ```bash + make eb-update + ``` + *Note:* git stage your changes before running the update so EB take on consideration your changes. + + 5. Terminate the application + ```bash + make eb-terminate # terminate the eb application + make terminate-all # terminate the eb application and delete the IAM Instance Profile + ``` + +### Manual Deployment You can get started using the following steps: 1. [Install the AWS Elastic Beanstalk Command Line Interface (CLI)](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install.html). 2. Create an IAM Instance Profile named **aws-elasticbeanstalk-locust-role** with the policy in [policy.json](policy.json). For more information on how to create an IAM Instance Profile, see [Create an IAM Instance Profile for Your Amazon EC2 Instances](https://docs.aws.amazon.com/codedeploy/latest/userguide/how-to-create-iam-instance-profile.html). @@ -26,3 +58,16 @@ You can get started using the following steps: 8. When you are done with your tests, run `eb terminate --all` to clean up. *Note: Running Locust in distributed mode requires a master/slave architecture. This sample requires that the auto scaling minimum and maximum be set to the same value to ensure that the master isn't terminated by auto scaling. If for some reason the master instance is replaced, an `eb deploy` should be all it takes to fix it.* + +### Useful AWS Elastic Beanstalk Command Line Interface: + +```bash +eb open # Open application dashboard +eb status # Check application status +eb deploy # Deploy application changes +eb list -v # Show running applications list +eb logs # Show application logs +eb printenv # List application env variables +eb scale # Scale application +eb setenv TARGET_URL="https://new-url.test.com" # Update application TARGET_URL env variables +``` diff --git a/iam-profile.yaml b/iam-profile.yaml new file mode 100644 index 0000000..7a09682 --- /dev/null +++ b/iam-profile.yaml @@ -0,0 +1,48 @@ +AWSTemplateFormatVersion: '2010-09-09' + +Parameters: + InstanceProfileName: + Description: IAM instance profile name + Type: String + +Resources: + LocustServiceRole: + Type: AWS::IAM::Role + Properties: + RoleName: elasticbeanstalk-locust-role + AssumeRolePolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: elasticbeanstalk-locust-policy + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - dynamodb:GetItem + - dynamodb:UpdateItem + Resource: + - 'arn:aws:dynamodb:*:*:table/*-stack-MasterIPTable*' + - Effect: Allow + Action: + - autoscaling:DescribeAutoScalingGroups + - cloudformation:ListStackResources + - elasticbeanstalk:DescribeEnvironmentResources + Resource: '*' + LocustServiceProfile: + Type: AWS::IAM::InstanceProfile + Properties: + InstanceProfileName: !Ref InstanceProfileName + Roles: + - !Ref 'LocustServiceRole' +Outputs: + RoleName: + Value: !Ref 'LocustServiceRole' + ProfileName: + Value: !Ref 'LocustServiceProfile' diff --git a/policy.json b/policy.json index cefb0e9..af1df27 100644 --- a/policy.json +++ b/policy.json @@ -25,4 +25,4 @@ ] } ] -} \ No newline at end of file +} From 6e351808b93a6bfcec66a3b5de36f2b34bf31893 Mon Sep 17 00:00:00 2001 From: taherbs Date: Thu, 7 Mar 2019 16:48:16 +0100 Subject: [PATCH 2/2] fixing paramter typo --- .env.sample | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.sample b/.env.sample index 27b5546..048d491 100644 --- a/.env.sample +++ b/.env.sample @@ -10,4 +10,4 @@ SERVICE_ENV = "test" SERVICE_CNAME = "$(SERVICE_ENV)-taherbs-locust" SERVICE_VPC = vpc-XXXXXX #Eb app VPC ID SERVICE_EC2_SUBNETS = subnet-XXXXXX #Eb app EC2 subnets -SERVICE_ELB_SUBNESTS = subnet-XXXXXX #Eb app ALB subnets +SERVICE_ELB_SUBNETS = subnet-XXXXXX #Eb app ALB subnets diff --git a/Makefile b/Makefile index 28c47e7..fabbb1f 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ eb-deploy: profile-check eb-init --branch_default $(SERVICE_ENV) \ --vpc.id $(SERVICE_VPC) \ --vpc.ec2subnets $(SERVICE_EC2_SUBNETS) \ - --vpc.elbsubnets $(SERVICE_ELB_SUBNESTS) \ + --vpc.elbsubnets $(SERVICE_ELB_SUBNETS) \ --vpc.elbpublic --vpc.publicip \ --envvars TARGET_URL=$(LOCUST_TARGET_URL) \ --region $(SERVICE_REGION)