====== AWS CLI Commands ====== Get AWS EC2 instance information and format into a table aws ec2 describe-instances --filters Name=tag-key,Values=Name --query "Reservations[*].Instances[*].{IP:PrivateIpAddress,Instance:InstanceId,AZ:Placement.AvailabilityZone,Name:Tags[?Key=='Name']|[0].Value}" --output table --color off aws ec2 describe-instances --query "Reservations[*].Instances[*].{State:State.Name,IP:PrivateIpAddress,Instance:InstanceId,AZ:Placement.AvailabilityZone,Function:Tags[?Key=='Function']|[0].Value,Name:Tags[?Key=='Name']|[0].Value,Owner:Tags[?Key=='Owner']|[0].Value}" --output table --color off aws ec2 describe-instances --filters "Name=tag:Backup,Values=Yes" --query 'Reservations[*].Instances[*].{InstanceID:InstanceId, Name:Tags[?Key==`Name`].Value|[0],Backup:Tags[?Key==`Backup`].Value|[0],Function:Tags[?Key==`Function`].Value|[0],State:State.Name}' --output table --color off aws ec2 describe-instances --filters Name=instance-state-name,Values=running --query 'Reservations[*].Instances[*].{InstanceID:InstanceId, Name:Tags[?Key==`Name`].Value|[0],Backup:Tags[?Key==`Backup`].Value|[0],Function:Tags[?Key==`Function`].Value|[0],State:State.Name,Owner:Tags[?Key==`Owner`].Value|[0],BackupPlan:Tags[?Key==`BackupPlan`].Value|[0]}' --output table --color off Get all AWS EC2 tags formatted into a table import json import subprocess import pandas as pd # Run AWS CLI command to get instance details in JSON format cmd = [ "aws", "ec2", "describe-instances", "--filters", "Name=instance-state-name,Values=running", "--query", "Reservations[*].Instances[*]", "--output", "json" ] try: result = subprocess.run(cmd, capture_output=True, text=True, check=True) instances = json.loads(result.stdout) except subprocess.CalledProcessError as e: print("Error executing AWS CLI command:", e) exit(1) # Flatten the instance data and extract unique tag keys instance_data = [] all_tag_keys = set() for reservation in instances: for instance in reservation: instance_id = instance.get("InstanceId", "N/A") state = instance.get("State", {}).get("Name", "N/A") # Extract tag key-value pairs tags = {tag["Key"]: tag["Value"] for tag in instance.get("Tags", [])} all_tag_keys.update(tags.keys()) # Collect all unique tag keys # Store instance data instance_data.append({"InstanceId": instance_id, "State": state, **tags}) # Convert data to DataFrame and fill missing tags with 'N/A' df = pd.DataFrame(instance_data).fillna("N/A") # Sort columns: InstanceId, State first, then all tag columns alphabetically column_order = ["InstanceId", "State"] + sorted(all_tag_keys) df = df[column_order] # Print as a formatted table df.to_csv("c:\\temp\\ec2_instances_test.csv", index=False) print("EC2 instance details saved to ec2_instances.csv") Then run following Python command (where aws_ec2_tags.py is in the c:\temp directory) python .\aws_ec2_tags.py Update Tags using python import pandas as pd import subprocess import json # Load updated CSV file csv_file = r"c:\temp\updated_ec2_tags.csv" # Modify path if needed df = pd.read_csv(csv_file) # Iterate over each row and update tags in AWS for _, row in df.iterrows(): instance_id = row["InstanceId"] tags = [] # Loop through all columns (except InstanceId and State) to create tag key-value pairs for col in df.columns: if col not in ["InstanceId", "State"]: # Ignore non-tag columns tag_value = row[col] if pd.notna(tag_value): # Only include non-empty values tags.append({"Key": col, "Value": str(tag_value)}) if tags: # AWS CLI command to update tags cmd = [ "aws", "ec2", "create-tags", "--resources", instance_id, "--tags", json.dumps(tags) ] try: result = subprocess.run(cmd, capture_output=True, text=True, check=True) print(f"āœ… Successfully updated tags for {instance_id}") except subprocess.CalledProcessError as e: print(f"āŒ Error updating {instance_id}: {e}") print("\nāœ… Tag updates completed!") Then run following Python command (where update_ec2_tags.py is in the c:\temp directory) python .\update_ec2_tags.py Get Route 53 Resolver Rules and format into a table aws route53resolver list-resolver-rules --query "ResolverRules[*].{Name:Name,ID:Id,Domain:DomainName,IPs:TargetIps}" --output table --color off Start AWS Session Manager to RDP to and EC2 Server aws ssm start-session --target i-053e069767460be0f --document-name AWS-StartPortForwardingSession --parameters "localPortNumber=55678,portNumber=3389" ---- ====== AWS Scripts ====== === Replace EC2 IAM Instance role === # Replace 'YOUR_NEW_IAM_ROLE_NAME' with the name of the new IAM role $NEW_ROLE_NAME = 'InstanceRoleForAmazonSSM' # Get a list of instance IDs $instanceIds = (aws ec2 describe-instances --query "Reservations[*].Instances[*].InstanceId" --output text) foreach ($instanceId in $instanceIds.Split("`n")) { # Get the instance's IAM instance profile associations $profileAssociations = aws ec2 describe-iam-instance-profile-associations --filters "Name=instance-id,Values=$instanceId" --query "IamInstanceProfileAssociations[*].AssociationId" --output text # If there are existing associations, replace the IAM instance profile if ($profileAssociations -ne "") { $associationId = $profileAssociations.Trim() aws ec2 replace-iam-instance-profile-association --iam-instance-profile Name=$NEW_ROLE_NAME --association-id $associationId Write-Host "Replaced IAM Role for instance $instanceId" } else { # If no association is found, associate the new IAM role directly aws ec2 associate-iam-instance-profile --instance-id $instanceId --iam-instance-profile Name=$NEW_ROLE_NAME Write-Host "Associated IAM Role for instance $instanceId" } } === Amazon Linux 2023 Deploy with UserData installation === --- AWSTemplateFormatVersion: '2010-09-09' Description: Launch a Linux instance and install Crowdstrike and attach IAM role to EC2 instance for CS installation Version 3.4 Metadata: Stack: Value: 0 VersionDate: Value: 20190725 Identifier: Value: main Input: Description: Input of all required parameters in the stack Output: Description: N/A AWS::CloudFormation::Interface: ParameterGroups: - Label: default: EC2 Instance Configuration Parameters: - AccountOU - VPC - AMI - InstanceType - DiskSize - DiskType - Subnet - ExistingSecurityGroupID - KeyPair - Label: default: Tag Information Parameters: - TagName - TagLinuxServerName - TagBackup - TagPatched - TagOwner - TagFunction - TagOS - TagOSVersion ParameterLabels: AccountOU: default: Account OU VPC: default: VPC ID AMI: default: Amazon Machine Image InstanceType: default: Instance Type DiskSize: default: System Partition Size DiskType: default: System Partition Type Subnet: default: Instance Subnet ExistingSecurityGroupID: default: Subnet Security Group KeyPair: default: Access Key Pair TagName: default: Name TagLinuxServerName: default: Linux Server Name TagBackup: default: Backup TagOwner: default: Owner TagPatched: default: Patched TagFunction: default: Function TagOS: default: Operating System TagOSVersion: default: Operating System Version Parameters: InstanceProfileName: Description: IAM instance profile name to attach to the EC2 instance Type: String AllowedValues: - s3-bucket-role-cs Default: s3-bucket-role-cs VPC: Type: AWS::EC2::VPC::Id Description: Select the VPC to place this instance AMI: Type: String Description: Select a Linux Amazon Machine Image for this Instance AllowedValues: - Amazonlinux2023 - Amazonlinux2 InstanceType: Type: String Description: Select the Instance Type Default: t2.micro AllowedValues: - t2.micro - t2.small - t2.medium - m1.small - m1.medium - m1.large - m1.xlarge - m2.xlarge - m2.2xlarge - m2.4xlarge - m3.medium - m3.large - m3.xlarge - m3.2xlarge - m5.xlarge - c1.medium - c1.xlarge - c3.large - c3.xlarge - c3.2xlarge - c3.4xlarge - c3.8xlarge - c4.large - c4.xlarge - c4.2xlarge - c4.4xlarge - c4.8xlarge - g2.2xlarge - r3.large - r3.xlarge - r3.2xlarge - r3.4xlarge - r3.8xlarge - i2.xlarge - i2.2xlarge - i2.4xlarge - i2.8xlarge - d2.xlarge - d2.2xlarge - d2.4xlarge - d2.8xlarge - hi1.4xlarge - hs1.8xlarge - cr1.8xlarge - cc2.8xlarge - cg1.4xlarge ConstraintDescription: Must be a valid EC2 instance type. Subnet: Type: AWS::EC2::Subnet::Id Description: Select a Subnet to place this instance ExistingSecurityGroupID: Type: AWS::EC2::SecurityGroup::Id Description: Select a Security Group to place this instance KeyPair: Type: AWS::EC2::KeyPair::KeyName Description: Select a KeyPair for this EC2 Instance TagName: Description: Enter the Name of the EC2 instance Type: String Default: Name TagLinuxServerName: Description: Enter Linux Server Name Type: String Default: Linux TagBackup: Description: Is the Instance being backed up (Yes or No) Type: String Default: Yes TagOwner: Description: Enter the Team/Owner of this Instance (eg. Energy Services, Smart Buildings) Type: String Default: Team/Owner Name? TagFunction: Description: Enter the function of the EC2 instance (Monitoring Server) Type: String Default: Monitoring Server TagOS: Description: Enter the Operating System of the EC2 instance Type: String Default: Linux TagOSVersion: Description: Enter the version of Operating System Type: String Default: Amazon Linux 2023 TagPatched: Description: Is the instance being Patched Type: String Default: Yes Mappings: RegionAMIMap: eu-west-1: Amazonlinux2023: ami-0e309a5f3a6dd97ea Amazonlinux2: ami-0a1f6cc8163bdcc75 eu-west-2: Amazonlinux2023: ami-0cf6f2b898ac0b337 Amazonlinux2: ami-06d0baf788edae448 Resources: myEC2InstanceSSM: Type: AWS::EC2::Instance Properties: IamInstanceProfile: Ref: InstanceProfileName UserData: Fn::Base64: !Sub | #!/bin/bash sudo mkdir /mount sudo mkdir ~/.aws cat <<'EOF' >> ~/.aws/config [profile s3-bucket-role-cs] role_arn = arn:aws:iam::877968844667:role/s3-bucket-role-CS credential_source = Ec2InstanceMetadata EOF sudo aws s3 cp s3://crowdstrikeinstalls/falcon-sensor-7.03.0-15805.amzn2023.x86_64.rpm /mount --profile s3-bucket-role-cs sudo yum -y install ./mount/falcon-sensor-7.03.0-15805.amzn2023.x86_64.rpm sudo /opt/CrowdStrike/falconctl -s --cid=C78902F9C85144558CFCCBC3A21AF3C9-75 --tags=LocalIT sudo service falcon-sensor start sudo systemctl start falcon-sensor KeyName: Ref: KeyPair ImageId: !FindInMap - RegionAMIMap - Ref: 'AWS::Region' - Ref: AMI InstanceType: Ref: InstanceType Tags: - Key: Name Value: !Ref TagName - Key: Linux Server Name Value: !Ref TagLinuxServerName - Key: Backup Value: !Ref TagBackup - Key: Patched Value: !Ref TagPatched - Key: Owner Value: !Ref TagOwner - Key: Function Value: !Ref TagFunction - Key: OS Value: !Ref TagOS - Key: OS Version Value: !Ref TagOSVersion SubnetId: Ref: Subnet SecurityGroupIds: - Ref: ExistingSecurityGroupID === Windows EC2 Deploy with UserData installation === --- AWSTemplateFormatVersion: '2010-09-09' Description: Launch a Windows instance and install Crowdstrike and attach IAM role to EC2 instance for CS installation Version 3.4 Metadata: Stack: Value: 0 VersionDate: Value: 20190725 Identifier: Value: main Input: Description: Input of all required parameters in the stack Output: Description: N/A AWS::CloudFormation::Interface: ParameterGroups: - Label: default: EC2 Instance Configuration Parameters: - AccountOU - VPC - AMI - InstanceType - DiskSize - DiskType - Subnet - ExistingSecurityGroupID - KeyPair - Label: default: Tag Information Parameters: - TagName - TagWindowsServerName - TagBackup - TagPatched - TagOwner - TagFunction - TagOS - TagOSVersion ParameterLabels: AccountOU: default: Account OU VPC: default: VPC ID AMI: default: Amazon Machine Image InstanceType: default: Instance Type DiskSize: default: System Partition Size DiskType: default: System Partition Type Subnet: default: Instance Subnet ExistingSecurityGroupID: default: Subnet Security Group KeyPair: default: Access Key Pair TagName: default: Name TagWindowsServerName: default: Windows Server Name TagBackup: default: Backup TagOwner: default: Owner TagPatched: default: Patched TagFunction: default: Function TagOS: default: Operating System TagOSVersion: default: Operating System Version Parameters: InstanceProfileName: Description: IAM instance profile name to attach to the EC2 instance Type: String AllowedValues: - s3-bucket-role-cs - AmazonSSMRoleForInstancesQuickSetup - InstanceRoleForAmazonSSM - engieuk-hq-inf-services-prod.sysman Default: s3-bucket-role-cs VPC: Type: AWS::EC2::VPC::Id Description: Select the VPC to place this instance AMI: Type: String Description: Select a Windows Amazon Machine Image for this Instance AllowedValues: - Win2019Base - Win2016Base InstanceType: Type: String Description: Select the Instance Type Default: t2.micro AllowedValues: - t2.micro - t2.small - t2.medium - t3.micro - t3.small - t3.medium - m1.small - m1.medium - m1.large - m1.xlarge - m2.xlarge - m2.2xlarge - m2.4xlarge - m3.medium - m3.large - m3.xlarge - m3.2xlarge - m5.xlarge - c1.medium - c1.xlarge - c3.large - c3.xlarge - c3.2xlarge - c3.4xlarge - c3.8xlarge - c4.large - c4.xlarge - c4.2xlarge - c4.4xlarge - c4.8xlarge - g2.2xlarge - r3.large - r3.xlarge - r3.2xlarge - r3.4xlarge - r3.8xlarge - i2.xlarge - i2.2xlarge - i2.4xlarge - i2.8xlarge - d2.xlarge - d2.2xlarge - d2.4xlarge - d2.8xlarge - hi1.4xlarge - hs1.8xlarge - cr1.8xlarge - cc2.8xlarge - cg1.4xlarge ConstraintDescription: Must be a valid EC2 instance type. DiskSize: Description: Instance Primary Disk Size (Gb) Type: Number Default : 30 DiskType: Description: Select a Volume type (gp2=General Purpose SSD, io1=Provisioned IOPS SSD, st1=Throughput Optimized HDD, sc1=Cold HDD) AllowedValues: - gp2 - io1 - st1 - sc1 Type: String Default: gp2 Subnet: Type: AWS::EC2::Subnet::Id Description: Select a Subnet to place this instance ExistingSecurityGroupID: Type: AWS::EC2::SecurityGroup::Id Description: Select a Security Group to place this instance KeyPair: Type: AWS::EC2::KeyPair::KeyName Description: Select a KeyPair for this EC2 Instance TagName: Description: Enter the Name of the EC2 instance Type: String Default: Name TagWindowsServerName: Description: Enter Windows Server Name Type: String Default: Windows TagBackup: Description: Is the Instance being backed up (Yes or No) Type: String Default: Yes TagOwner: Description: Enter the Team/Owner of this Instance (eg. Energy Services, Smart Buildings) Type: String Default: Team/Owner Name? TagFunction: Description: Enter the function of the EC2 instance (Monitoring Server) Type: String Default: Monitoring Server TagOS: Description: Enter the Operating System of the EC2 instance Type: String Default: Windows TagOSVersion: Description: Enter the version of Operating System Type: String Default: Server 2019 TagPatched: Description: Is the instance being Patched Type: String Default: Yes Mappings: RegionAMIMap: eu-west-1: Win2019Base: ami-01c8584ce4ac83765 Win2016Base: ami-0782e691e989998df eu-west-2: Win2019Base: ami-08ce0f1cd8b30bf4e Win2016Base: ami-02a9c04e461574620 Resources: myEC2InstanceSSM: Type: AWS::EC2::Instance Properties: IamInstanceProfile: Ref: InstanceProfileName BlockDeviceMappings: - DeviceName: "/dev/sda1" Ebs: Encrypted: True VolumeSize: !Ref DiskSize VolumeType: !Ref DiskType UserData: Fn::Base64: | # Download and install AWS CLI silently $awsCliInstaller = "AWSCLIV2.msi" Invoke-WebRequest -Uri "https://awscli.amazonaws.com/$($awsCliInstaller)" -OutFile $awsCliInstaller Start-Process -Wait -FilePath msiexec -ArgumentList '/i', $awsCliInstaller, '/quiet', '/norestart' $env:Path += ";C:\Program Files\Amazon\AWSCLIV2\" # PowerShell script content here # IAM role details $roleArn = "arn:aws:iam::877968844667:role/s3-bucket-role-CS" # Assume the role using AWS CLI $assumeRoleCommand = "aws sts assume-role --role-arn $roleArn --role-session-name AssumedRoleSession --output json" $assumeRoleOutput = Invoke-Expression -Command $assumeRoleCommand | ConvertFrom-Json # Extract temporary credentials $accessKeyId = $assumeRoleOutput.Credentials.AccessKeyId $secretAccessKey = $assumeRoleOutput.Credentials.SecretAccessKey $sessionToken = $assumeRoleOutput.Credentials.SessionToken # Set AWS credentials with the assumed role aws configure set aws_access_key_id $accessKeyId aws configure set aws_secret_access_key $secretAccessKey aws configure set aws_session_token $sessionToken # S3 bucket details $bucketName = "crowdstrikeinstalls" $key = "WindowsSensor.LionLanner.exe" # Specify the source object (file) key in the bucket # Local file path mkdir c:\temp $localFilePath = "C:\temp" # Download the file from S3 bucket aws s3 cp s3://$bucketName/$key $localFilePath # Signal the completion of the installation cfn-signal -e 0 --stack ${AWS::StackName} --resource EC2Instance # Execute the application installer (replace with the actual installer command) Start-Process -Wait -FilePath "$localFilePath\WindowsSensor.LionLanner.exe" "/install /quiet /norestart CID=C78902F9C85144558CFCCBC3A21AF3C9-75 --tags=LocalIT" KeyName: Ref: KeyPair ImageId: !FindInMap - RegionAMIMap - Ref: 'AWS::Region' - Ref: AMI InstanceType: Ref: InstanceType Tags: - Key: Name Value: !Ref TagName - Key: Windows Server Name Value: !Ref TagWindowsServerName - Key: Backup Value: !Ref TagBackup - Key: Patched Value: !Ref TagPatched - Key: Owner Value: !Ref TagOwner - Key: Function Value: !Ref TagFunction - Key: OS Value: !Ref TagOS - Key: OS Version Value: !Ref TagOSVersion SubnetId: Ref: Subnet SecurityGroupIds: - Ref: ExistingSecurityGroupID ---- ====== Route 53 CLI Commands ====== To use Route53 cli download from: [[https://github.com/barnybug/cli53/releases/tag/0.8.18|https://github.com/barnybug/cli53/releases/tag/0.8.18]] (For Windows, Linux and Mac) Then to list Route53 domains do: cli53-windows-amd64.exe list To export Route53 Domains do: cli53-windows-amd64.exe export equans.co.uk To export Route53 Domains to a file do: cli53-windows-amd64.exe export equans.co.uk> c:\temp\equans.co.uk.txt ---- ====== IAM Policies ====== IAM Policy that enables SSM Port Forwarding Session so that session manager can be used to remote to EC2 instances: { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ssm:*" ], "Resource": [ "arn:aws:ec2:eu-west-3:684897324199:instance/i-0a88225b9c1fa3189", "arn:aws:ec2:eu-west-3:684897324199:instance/i-016a6934b9a373362", "arn:aws:ssm:eu-west-3::document/AWS-StartPortForwardingSession" ] }, { "Effect": "Allow", "Action": [ "ec2:*" ], "Resource": [ "arn:aws:ec2:eu-west-3:684897324199:instance/i-0a88225b9c1fa3189", "arn:aws:ec2:eu-west-3:684897324199:instance/i-016a6934b9a373362" ] } ] }