Last active
December 29, 2021 08:02
-
-
Save markusl/cd1d9ab2c312b0aff18f2f1b19146a00 to your computer and use it in GitHub Desktop.
How to run AWS macOS EC2 instance and automatically resize disk using AWS CDK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
To be used with https://aws.amazon.com/blogs/opensource/integrating-ec2-macos-workers-with-eks-and-jenkins/ | |
*/ | |
import { | |
aws_ec2 as ec2, | |
aws_eks as eks, | |
aws_iam as iam, | |
Stack, | |
StackProps, | |
CfnOutput, | |
} from 'aws-cdk-lib'; | |
import { Construct } from 'constructs'; | |
export interface JenkinsWorkerProps extends StackProps { | |
cluster: eks.Cluster; | |
keyName: string; | |
publicKey: string; | |
instanceRole?: iam.IRole; | |
amiMap: Record<string, string>; | |
} | |
export class JenkinsWorker extends Stack { | |
constructor(scope: Construct, id: string, props: JenkinsWorkerProps) { | |
super(scope, id, props); | |
const securityGroup = new ec2.SecurityGroup(this, `${id}securityGroup`, { | |
vpc: props.cluster.vpc, | |
description: 'Allow ssh access to Jenkins instances from internal network', | |
allowAllOutbound: true | |
}); | |
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(22), 'allow private ssh access'); | |
const instance = new ec2.Instance(this, `${id}Mac1MetalInstance`, { | |
instanceType: new ec2.InstanceType('mac1.metal'), | |
machineImage: ec2.MachineImage.genericLinux(props.amiMap), | |
securityGroup, | |
role: props.instanceRole, | |
vpc: props.cluster.vpc, | |
keyName: props.keyName, | |
blockDevices: [ | |
{ | |
deviceName: '/dev/sda1', | |
volume: ec2.BlockDeviceVolume.ebs(256) | |
}, | |
], | |
userDataCausesReplacement: true, | |
}); | |
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-mac-instances.html#mac-instance-increase-volume | |
const resizeSh = Buffer.from(`PDISK=$(diskutil list physical external | head -n1 | cut -d" " -f1) | |
APFSCONT=$(diskutil list physical external | grep "Apple_APFS" | tr -s " " | cut -d" " -f8) | |
yes | sudo diskutil repairDisk $PDISK | |
sudo diskutil apfs resizeContainer $APFSCONT 0 | |
`, 'binary').toString('base64'); | |
// If there any errors here you can check /var/log/amazon/ec2/ec2-macos-init.log | |
instance.addUserData( | |
// Install Corretto Java (required by Jenkins) | |
'su - ec2-user -c "/usr/local/bin/brew install --cask corretto"', | |
// iOS builds require this | |
`su - ec2-user -c "echo 'export LANG=en_US.UTF-8' >> ~/.profile"`, | |
// Allow SSH access for eks-jenkins-ssh-key to be able to log in for installing XCode | |
`su - ec2-user -c "echo '${props.publicKey}' >> ~/.ssh/authorized_keys"`, | |
// Resize disk | |
`su - ec2-user -c "echo \"${resizeSh}\" | base64 --decode > resize.sh"`, | |
`su - ec2-user -c "sh resize.sh"`, | |
// Enable VNC https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-mac-instances.html#mac-instance-vnc | |
'/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -access -on -restart -agent -privs -all', | |
// Rest of the steps need to be done manually as per https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-mac-instances.html#mac-instance-vnc | |
); | |
const cfnInstance = instance.node.defaultChild as ec2.CfnInstance; | |
cfnInstance.addPropertyOverride('Tenancy', 'host'); | |
new CfnOutput(this, 'MacOS Worker Private DNS name', { | |
value: instance.instancePrivateDnsName | |
}); | |
// The private IP is configured in the Jenkins config file | |
new CfnOutput(this, 'MacOS Worker Private IP', { | |
value: instance.instancePrivateIp | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
new JenkinsWorker(app, 'JenkinsWorker', { | |
env: { | |
region, | |
}, | |
keyName: 'eks-jenkins-ssh-key', | |
publicKey: 'ssh-rsa AAAAB3-.....x2j2baEa2O1VTNWGc= eks-jenkins-ssh-key-2', | |
cluster: primaryCluster.cluster, | |
instanceRole: s3bucket.role, | |
amiMap: { | |
'eu-central-1': 'ami-0ec2b8cc005c0a1d1', // macOS Monterey 12.0.1 | |
// 'eu-central-1: 'ami-0fab661bd6dd419af', // macOS Big Sur 11.6.1 | |
}, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment