AWSTemplateFormatVersion: '2010-09-09' Description: "AWS FIS workshop - EC2/static stack. Launch Windows and Linux Instance for CPU Stress Test during FIS Workshop." Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: EC2 Instance Configuration Parameters: - LinuxImageId - WindowsImageId - InstanceType ParameterLabels: LinuxImageId: default: AMZ Linux Amazon Machine Image (AMI) Id WindowsImageId: default: AMZ Linux Amazon Machine Image (AMI) Id InstanceType: default: EC2 Instance Type Parameters: LinuxImageId: Type: AWS::SSM::Parameter::Value Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 Description: 'SSM Parameter for Amazon Linux AMI.' WindowsImageId: Type: AWS::SSM::Parameter::Value Default: /aws/service/ami-windows-latest/Windows_Server-2019-English-Full-Base Description: 'SSM Parameter for Windows 2019 AMI.' InstanceType: AllowedValues: - t3.nano - t3.micro - t3.small - t3.medium - t3.large Default: t3.medium Description: Amazon EC2 instance type for the Internet Information Services servers Type: String SubnetId: Description: Subnet in which to instantiate VM - needed if no Default VPC was configured # Can't use Type: AWS::EC2::Subnet::Id because it checks the default before the condition Type: String AllowedPattern: "subnet-[a-z0-9]+" Default: "subnet-000000" Conditions: UseDefaultVpc: !Equals - !Ref SubnetId - "subnet-000000" Resources: SSMInstanceRole: Type : AWS::IAM::Role Properties: ManagedPolicyArns: - !Sub 'arn:${AWS::Partition}:iam::aws:policy/AmazonSSMManagedInstanceCore' AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "ec2.amazonaws.com" Action: "sts:AssumeRole" SSMInstanceProfile: Type: "AWS::IAM::InstanceProfile" Properties: Roles: - !Ref SSMInstanceRole WindowsInstance: Type: AWS::EC2::Instance Properties: ImageId: !Ref 'WindowsImageId' IamInstanceProfile: !Ref 'SSMInstanceProfile' InstanceType: !Ref 'InstanceType' Monitoring: true SubnetId: !If [UseDefaultVpc, !Ref "AWS::NoValue", !Ref SubnetId] Tags: - Key: Name Value: 'FisWindowsCPUStress' LinuxInstance: Type: AWS::EC2::Instance Properties: ImageId: !Ref 'LinuxImageId' IamInstanceProfile: !Ref 'SSMInstanceProfile' InstanceType: !Ref 'InstanceType' Monitoring: true SubnetId: !If [UseDefaultVpc, !Ref "AWS::NoValue", !Ref SubnetId] Tags: - Key: Name Value: 'FisLinuxCPUStress' UserData: Fn::Base64: !Sub | #!/bin/bash -xe sudo yum -y install htop FISRole: Type: AWS::IAM::Role Properties: Policies: - PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogDelivery Resource: '*' - Effect: Allow Action: - ssm:ListCommands - ssm:ListDocuments Resource: '*' - Effect: Allow Action: ssm:SendCommand Resource: - !Sub arn:${AWS::Partition}:ssm:*:*:document/AWSFIS-Run-* - !Sub arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:document/${WinStressDocument} - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:instance/* PolicyName: SSMPolicy AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - "fis.amazonaws.com" Action: sts:AssumeRole # FISExperimentCPUStress: # Type: AWS::FIS::ExperimentTemplate # Properties: # Description: Workshop for injecting CPU stress via SSM # RoleArn: # Fn::GetAtt: # - FISRole # - Arn # StopConditions: # - Source: none # Tags: # Name: BurnCPUViaSSM # Targets: # instanceTargets: # ResourceArns: # - Fn::Join: # - "" # - - "arn:aws:ec2:" # - Ref: AWS::Region # - ":" # - Ref: AWS::AccountId # - :instance/ # - Ref: EC2Instance # ResourceType: aws:ec2:instance # SelectionMode: ALL # Actions: # instanceActions: # ActionId: aws:ssm:send-command # Description: burn cpu vis SSM # Parameters: # documentArn: # Fn::Join: # - "" # - - "arn:aws:ssm:" # - Ref: AWS::Region # - ::document/AWSFIS-Run-CPU-Stress # documentParameters: '{"DurationSeconds":"120"}' # duration: PT2M # Targets: # Instances: instanceTargets WinStressDocument: Type: AWS::SSM::Document Properties: DocumentType: Command Content: | { "schemaVersion": "2.2", "description": "Stress Windows CPU.", "parameters": { "workingDirectory": { "type": "String", "default": "", "description": "(Optional) The path to the working directory on your instance.", "maxChars": 4096 }, "durationSeconds": { "type": "String", "default": "120", "description": "Duration of test in seconds.", "allowedPattern": "([1-9][0-9]{0,4})|(1[0-6][0-9]{4})|(17[0-1][0-9]{3})|(172[0-7][0-9]{2})|(172800)" }, "executionTimeout": { "type": "String", "default": "3600", "description": "(Optional) The time in seconds for a command to be completed before it is considered to have failed. Default is 3600 (1 hour). Maximum is 172800 (48 hours).", "allowedPattern": "([1-9][0-9]{0,4})|(1[0-6][0-9]{4})|(17[0-1][0-9]{3})|(172[0-7][0-9]{2})|(172800)" } }, "mainSteps": [ { "action": "aws:runPowerShellScript", "name": "invokeCpuStress", "precondition": { "StringEquals": [ "platformType", "Windows" ] }, "inputs": { "runCommand": [ "try {", " $NumThreads = Get-WmiObject win32_processor | Select-Object -ExpandProperty NumberOfLogicalProcessors", " $StartDate = Get-Date -ErrorAction Stop", " Write-Output \"============= CPU Stress Test Started: $StartDate =============\"", " foreach ($loopnumber in 1..$NumThreads){", " Start-Job -ScriptBlock{", " $result = 1", " foreach ($number in 1..2147483647){", " $result = $result * $number", " }", " } -Name SSMCpuJob$loopnumber -ErrorAction Stop", " }", " Start-Sleep -s {{durationSeconds}}", " Stop-Job -Name SSMCpuJob* -ErrorAction Stop", " $EndDate = Get-Date -ErrorAction Stop", " Write-Output \"============= CPU Stress Test Complete: $EndDate =============\"", " Get-Job -ErrorAction Stop | Remove-Job -ErrorAction Stop", "} catch {", " Write-Host \"Failed to Run CPU Stress Test\"", " Get-Job -ErrorAction Stop | Remove-Job -ErrorAction Stop", " Exit 1", "}" ] } } ] } Outputs: WinStressDocumentArn: Value: !Sub arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:document/${WinStressDocument} WindowsInstanceId: Value: !Ref WindowsInstance