From 9bdf9d512122684c03958b7d17adbbb257e04b2e Mon Sep 17 00:00:00 2001 From: SleepWith Coffee Date: Thu, 30 May 2024 15:15:11 +0000 Subject: [PATCH 1/4] Refactor CFN code --- .../efficient-auto-scaling-quickstart-cnf.yml | 45 +++++-------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/content/efficient-and-resilient-ec2-auto-scaling/files/efficient-auto-scaling-quickstart-cnf.yml b/content/efficient-and-resilient-ec2-auto-scaling/files/efficient-auto-scaling-quickstart-cnf.yml index 69c8a5ff..d4b18fb8 100644 --- a/content/efficient-and-resilient-ec2-auto-scaling/files/efficient-auto-scaling-quickstart-cnf.yml +++ b/content/efficient-and-resilient-ec2-auto-scaling/files/efficient-auto-scaling-quickstart-cnf.yml @@ -141,9 +141,7 @@ Resources: SecurityGroupIds: - !Ref InstanceSecurityGroup IamInstanceProfile: - Arn: !GetAtt - - InstanceProfile - - Arn + Arn: !GetAtt InstanceProfile.Arn UserData: 'Fn::Base64': |- @@ -267,11 +265,7 @@ Resources: - sts:AssumeRole Path: "/" Policies: - - PolicyName: - Fn::Join: - - '' - - - C9LambdaPolicy- - - Ref: AWS::Region + - PolicyName: !Sub 'C9LambdaPolicy-${AWS::Region}' PolicyDocument: Version: '2012-10-17' Statement: @@ -298,27 +292,22 @@ Resources: ################## LAMBDA BOOTSTRAP FUNCTION ################ C9BootstrapInstanceLambda: - Description: Bootstrap Cloud9 instance Type: Custom::C9BootstrapInstanceLambda DependsOn: - - C9BootstrapInstanceLambdaFunction - - C9Instance - C9LambdaExecutionRole Properties: + Description: Bootstrap Cloud9 instance Tags: - Key: Environment Value: AWS Example - ServiceToken: - Fn::GetAtt: - - C9BootstrapInstanceLambdaFunction - - Arn + ServiceToken: !GetAtt C9BootstrapInstanceLambdaFunction.Arn REGION: Ref: AWS::Region StackName: Ref: AWS::StackName EnvironmentId: Ref: C9Instance - LabIdeInstanceProfileArn: !If [ NotEventEngine, !GetAtt C9InstanceProfile.Arn, !Sub 'arn:aws:iam::${AWS::AccountId}:instance-profile/TeamRoleInstanceProfile' ] + LabIdeInstanceProfileArn: !If [ NotEventEngine, !GetAtt C9InstanceProfile.Arn, !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:instance-profile/TeamRoleInstanceProfile' ] C9BootstrapInstanceLambdaFunction: Type: AWS::Lambda::Function @@ -327,10 +316,7 @@ Resources: - Key: Environment Value: AWS Example Handler: index.lambda_handler - Role: - Fn::GetAtt: - - C9LambdaExecutionRole - - Arn + Role: !GetAtt C9LambdaExecutionRole.Arn Runtime: python3.9 MemorySize: 256 Timeout: '600' @@ -399,7 +385,7 @@ Resources: Tags: - Key: Environment Value: AWS Example - Content: Yaml + DocumentFormat: YAML DocumentType: Command Content: schemaVersion: '2.2' @@ -457,8 +443,6 @@ Resources: C9BootstrapAssociation: Type: AWS::SSM::Association - DependsOn: - - C9OutputBucket Properties: Name: !Ref C9SSMDocument OutputLocation: @@ -479,9 +463,8 @@ Resources: Roles: - Ref: C9Role C9Instance: - Description: "-" - DependsOn: C9BootstrapAssociation Type: AWS::Cloud9::EnvironmentEC2 + DependsOn: C9BootstrapAssociation Properties: Description: AWS Cloud9 instance for Examples AutomaticStopTimeMinutes: 240 @@ -491,7 +474,7 @@ Resources: Name: Ref: AWS::StackName # OwnerArn: !Sub 'arn:aws:sts::${AWS::AccountId}:assumed-role/TeamRole/MasterKey' - OwnerArn: !If [NotEventEngine , !Ref AWS::NoValue , !Sub 'arn:aws:sts::${AWS::AccountId}:assumed-role/TeamRole/MasterKey'] + OwnerArn: !If [NotEventEngine , !Ref AWS::NoValue , !Sub 'arn:${AWS::Partition}:sts::${AWS::AccountId}:assumed-role/TeamRole/MasterKey'] Tags: - Key: SSMBootstrap @@ -504,14 +487,8 @@ Resources: Outputs: Cloud9IDE: Value: - Fn::Join: - - '' - - - https:// - - Ref: AWS::Region - - ".console.aws.amazon.com/cloud9/ide/" - - Ref: C9Instance - - "?region=" - - Ref: AWS::Region + !Sub 'https://${AWS::Region}.console.aws.amazon.com/cloud9/ide/${C9Instance}?region=${AWS::Region}' + VPC: Description: A reference to the created VPC Value: !Ref VPC From b1e792b9e650a43a7d754c38b66585dddef8d4cd Mon Sep 17 00:00:00 2001 From: SleepWith Coffee Date: Thu, 30 May 2024 15:15:28 +0000 Subject: [PATCH 2/4] Refactor userdata for Linux instance --- .../efficient-auto-scaling-quickstart-cnf.yml | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/content/efficient-and-resilient-ec2-auto-scaling/files/efficient-auto-scaling-quickstart-cnf.yml b/content/efficient-and-resilient-ec2-auto-scaling/files/efficient-auto-scaling-quickstart-cnf.yml index d4b18fb8..6e0c41ca 100644 --- a/content/efficient-and-resilient-ec2-auto-scaling/files/efficient-auto-scaling-quickstart-cnf.yml +++ b/content/efficient-and-resilient-ec2-auto-scaling/files/efficient-auto-scaling-quickstart-cnf.yml @@ -161,34 +161,33 @@ Resources: Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="userdata.txt" #!/bin/bash - rpm -q httpd &> /dev/null + rpm -q stress &> /dev/null if [ $? -ne 0 ] then sudo amazon-linux-extras install epel -y sudo yum install stress -y fi - rpm -q httpd &> /dev/null - + + rpm -q httpd &> /dev/null if [ $? -ne 0 ] then echo "Application is not installed, install and start it." - INSTANCE_ID="`wget -q -O - http://instance-data/latest/meta-data/instance-id`" && \ - REGION="`wget -q -O - http://instance-data/latest/meta-data/placement/region`" && \ sudo yum -y install httpd && \ sudo service httpd start && \ echo "Sleeping for 120 seconds to simulate additional configuration time." && \ - sleep 120 && \ - aws autoscaling complete-lifecycle-action --lifecycle-action-result CONTINUE --instance-id $INSTANCE_ID --lifecycle-hook-name ec2-workshop-launch-hook --auto-scaling-group-name ec2-workshop-asg --region $REGION || \ - aws autoscaling complete-lifecycle-action --lifecycle-action-result ABANDON --instance-id $INSTANCE_ID --lifecycle-hook-name ec2-workshop-launch-hook --auto-scaling-group-name ec2-workshop-asg --region $REGION + sleep 120 else echo "Application is installed, start it." - INSTANCE_ID="`wget -q -O - http://instance-data/latest/meta-data/instance-id`" && \ - REGION="`wget -q -O - http://instance-data/latest/meta-data/placement/region`" && \ - sudo service httpd start && \ - aws autoscaling complete-lifecycle-action --lifecycle-action-result CONTINUE --instance-id $INSTANCE_ID --lifecycle-hook-name ec2-workshop-launch-hook --auto-scaling-group-name ec2-workshop-asg --region $REGION || \ - aws autoscaling complete-lifecycle-action --lifecycle-action-result ABANDON --instance-id $INSTANCE_ID --lifecycle-hook-name ec2-workshop-launch-hook --auto-scaling-group-name ec2-workshop-asg --region $REGION + sudo service httpd start fi + + # TODO check if aws cli is preinstalled + INSTANCE_ID="`wget -q -O - http://instance-data/latest/meta-data/instance-id`" && \ + REGION="`wget -q -O - http://instance-data/latest/meta-data/placement/region`" && \ + aws autoscaling complete-lifecycle-action --lifecycle-action-result CONTINUE --instance-id $INSTANCE_ID --lifecycle-hook-name ec2-workshop-launch-hook --auto-scaling-group-name ec2-workshop-asg --region $REGION || \ + aws autoscaling complete-lifecycle-action --lifecycle-action-result ABANDON --instance-id $INSTANCE_ID --lifecycle-hook-name ec2-workshop-launch-hook --auto-scaling-group-name ec2-workshop-asg --region $REGION --// + InstanceRole: Type: "AWS::IAM::Role" Properties: From fc4fb8761196a1177573f6858e847ae9b24f2de8 Mon Sep 17 00:00:00 2001 From: SleepWith Coffee Date: Thu, 30 May 2024 15:15:51 +0000 Subject: [PATCH 3/4] Add option to use Windows OS Family --- .../efficient-auto-scaling-quickstart-cnf.yml | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/content/efficient-and-resilient-ec2-auto-scaling/files/efficient-auto-scaling-quickstart-cnf.yml b/content/efficient-and-resilient-ec2-auto-scaling/files/efficient-auto-scaling-quickstart-cnf.yml index 6e0c41ca..cb79bfaf 100644 --- a/content/efficient-and-resilient-ec2-auto-scaling/files/efficient-auto-scaling-quickstart-cnf.yml +++ b/content/efficient-and-resilient-ec2-auto-scaling/files/efficient-auto-scaling-quickstart-cnf.yml @@ -45,6 +45,16 @@ Parameters: - t3.large - m5.large ConstraintDescription: Must be a valid Cloud9 instance type + + InstanceOSFamily: + Description: Instance OS Family + Type: String + Default: Linux + AllowedValues: + - Linux + - Windows + ConstraintDescription: Must be a valid OS family + #Used only by Event Engine, if you are self-deploying the stack leave the default value to NONE EETeamRoleArn: Description: "ARN of the Team Role" @@ -54,6 +64,8 @@ Parameters: Conditions: NotEventEngine: !Equals [!Ref EETeamRoleArn, NONE] + UseLinux: !Equals [!Ref InstanceOSFamily, Linux] + UseWindows: !Equals [!Ref InstanceOSFamily, Windows] Resources: ################## VPC AND SUBNETs ################# @@ -132,6 +144,7 @@ Resources: ################## Launch Template ################# MyLaunchTemplate: Type: AWS::EC2::LaunchTemplate + Condition: UseLinux Properties: LaunchTemplateName: EC2WorkshopLaunchTemplate LaunchTemplateData: @@ -188,6 +201,38 @@ Resources: aws autoscaling complete-lifecycle-action --lifecycle-action-result ABANDON --instance-id $INSTANCE_ID --lifecycle-hook-name ec2-workshop-launch-hook --auto-scaling-group-name ec2-workshop-asg --region $REGION --// + MyLaunchTemplateWindows: + Type: AWS::EC2::LaunchTemplate + Condition: UseWindows + Properties: + LaunchTemplateName: EC2WorkshopLaunchTemplateWindows + LaunchTemplateData: + ImageId: resolve:ssm:/aws/service/ami-windows-latest/Windows_Server-2022-English-Core-Base + InstanceType: t3.micro + KeyName: !Ref EC2WorkshopInstanceKeyPair + SecurityGroupIds: + - !Ref InstanceSecurityGroup + IamInstanceProfile: + Arn: !GetAtt InstanceProfile.Arn + UserData: + 'Fn::Base64': + |- + + # Minial IIS setup + Install-WindowsFeature Web-Server + + $AWS_CLI_INSTALLED=(Get-Command aws -ErrorAction SilentlyContinue) + if ($AWS_CLI_INSTALLED -eq $null) { + Start-Process msiexec.exe -ArgumentList "/i `"https://awscli.amazonaws.com/AWSCLIV2.msi`" /q" -Wait + $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + } + + $INSTANCE_ID=(Invoke-WebRequest -Uri http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing).Content + $REGION=(Invoke-WebRequest -Uri http://169.254.169.254/latest/meta-data/placement/region -UseBasicParsing).Content + aws autoscaling complete-lifecycle-action --lifecycle-action-result CONTINUE --instance-id "$INSTANCE_ID" --lifecycle-hook-name ec2-workshop-launch-hook --auto-scaling-group-name ec2-workshop-asg --region "$REGION" + aws autoscaling complete-lifecycle-action --lifecycle-action-result ABANDON --instance-id "$INSTANCE_ID" --lifecycle-hook-name ec2-workshop-launch-hook --auto-scaling-group-name ec2-workshop-asg --region "$REGION" + + InstanceRole: Type: "AWS::IAM::Role" Properties: From 38dea43643ade6b55097b9006498a9a12294058a Mon Sep 17 00:00:00 2001 From: SleepWith Coffee Date: Thu, 30 May 2024 15:16:15 +0000 Subject: [PATCH 4/4] Update & add new asg config for both OS families --- .../asg.json | 2 +- .../asg_windows.json | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 workshops/efficient-and-resilient-ec2-auto-scaling/asg_windows.json diff --git a/workshops/efficient-and-resilient-ec2-auto-scaling/asg.json b/workshops/efficient-and-resilient-ec2-auto-scaling/asg.json index f5b0f2cb..701ef04e 100644 --- a/workshops/efficient-and-resilient-ec2-auto-scaling/asg.json +++ b/workshops/efficient-and-resilient-ec2-auto-scaling/asg.json @@ -2,7 +2,7 @@ "AutoScalingGroupName": "ec2-workshop-asg", "LaunchTemplate": { "LaunchTemplateName": "EC2WorkshopLaunchTemplate", - "Version": "1" + "Version": "$Latest" }, "MinSize": 0, "MaxSize": 5, diff --git a/workshops/efficient-and-resilient-ec2-auto-scaling/asg_windows.json b/workshops/efficient-and-resilient-ec2-auto-scaling/asg_windows.json new file mode 100644 index 00000000..93f6b0dc --- /dev/null +++ b/workshops/efficient-and-resilient-ec2-auto-scaling/asg_windows.json @@ -0,0 +1,20 @@ +{ + "AutoScalingGroupName": "ec2-workshop-asg", + "LaunchTemplate": { + "LaunchTemplateName": "EC2WorkshopLaunchTemplateWindows", + "Version": "$Latest" + }, + "MinSize": 0, + "MaxSize": 5, + "DesiredCapacity": 0, + "CapacityRebalance": true, + "HealthCheckType": "EC2", + "VPCZoneIdentifier": "%PublicSubnet1%,%PublicSubnet2%", + "Tags": [ + { + "Key": "App", + "Value": "EC2ScalingWorkshop", + "PropagateAtLaunch": true + } + ] +} \ No newline at end of file