Skip to content

Commit b831a87

Browse files
authored
deploy macos instances (#8794)
1 parent 64e676f commit b831a87

File tree

14 files changed

+297
-155
lines changed

14 files changed

+297
-155
lines changed

.atlantis.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ projects:
1414
branch: /main/
1515
dir: infra/aws/terraform/kops-infra-ci
1616
workflow: aws
17+
- name: k8s-infra-macos
18+
branch: /main/
19+
dir: infra/aws/terraform/macos
20+
workflow: aws

infra/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ AWS:
1313

1414
- 10.128.0.0/16 k8s-infra-kops-prow-build
1515
- 10.0.0.0/16 eks-prow-build-cluster
16+
- 10.1.0.0/16 macos VPC
1617

1718
GCP:
1819

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# infra/aws/terraform/macos
2+
3+
This AWS account holds our MacOS infrastructure used by various Kubernetes projects.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
assume_role = {
2+
role_arn = "arn:aws:iam::230049944443:role/OrganizationAccountAccessRole"
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
atlantis_role_arn = "arn:aws:iam::230049944443:role/OrganizationAccountAccessRole"

infra/aws/terraform/macos/main.tf

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
18+
resource "aws_ec2_host" "mac" {
19+
count = 1
20+
instance_type = "mac2-m2.metal"
21+
availability_zone = "us-east-2c"
22+
host_recovery = "on"
23+
auto_placement = "on"
24+
tags = {
25+
Name = "mac-dedicated-host-${count.index + 1}"
26+
}
27+
}
28+
29+
# Data source to get the latest macOS AMI
30+
data "aws_ami" "macos" {
31+
most_recent = true
32+
owners = ["amazon"]
33+
34+
filter {
35+
name = "name"
36+
values = ["amzn-ec2-macos-15.7*-arm64"] # macOS Sequoia
37+
}
38+
39+
filter {
40+
name = "architecture"
41+
values = ["arm64_mac"]
42+
}
43+
}
44+
45+
46+
// IAM
47+
resource "aws_iam_role" "macos" {
48+
name = "macos-role"
49+
assume_role_policy = jsonencode({
50+
Version = "2012-10-17",
51+
Statement = [
52+
{
53+
Action = "sts:AssumeRole",
54+
Effect = "Allow",
55+
Principal = {
56+
Service = "ec2.amazonaws.com"
57+
}
58+
}
59+
]
60+
})
61+
}
62+
63+
resource "aws_iam_role_policy_attachments_exclusive" "macos" {
64+
role_name = aws_iam_role.macos.name
65+
policy_arns = [
66+
"arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore",
67+
"arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy",
68+
]
69+
}
70+
71+
72+
resource "aws_iam_instance_profile" "macos" {
73+
name = "macos"
74+
role = aws_iam_role.macos.name
75+
}
76+
77+
resource "aws_key_pair" "macos" {
78+
key_name = "macos" # this is the same key as the aws-ssh key in prow
79+
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCnUSQbmHOztLhE7to3RhMElJeKWkEeK3va4sluwelJH8oHA8bQhGfleXYrIIvXFsZagpoggZ9b9Ed6JMcBOtI382o7yW8G9ZC7pxQVe+V2xYQAlDl5grdtgBVA3Cgy6ZtwLVATZhVnd7WIQh2FuvbR0I03PXO/dSWo2j8f/PInRdRTfubKTEWJV78OItYu6TCn+Fc5RABGlKRdWfhvkixmClOEATO+5o7q+p40VefQE84WLXApY8pCjCFL90SCCDqkgG9UFAdC/hSrvzs+Jk4N1Vhmj2c5jsZm0a9iWKTNKbohUlCnnatWvRY1WgbDiijJydXZzIliTInxZQeidZR7 zml"
80+
}
81+
82+
resource "aws_instance" "mac_node" {
83+
count = 1
84+
instance_type = "mac2-m2.metal"
85+
key_name = aws_key_pair.macos.key_name
86+
availability_zone = "us-east-2c"
87+
iam_instance_profile = aws_iam_instance_profile.macos.name
88+
ami = data.aws_ami.macos.id
89+
tenancy = "host"
90+
91+
subnet_id = module.vpc.public_subnets[2]
92+
associate_public_ip_address = true
93+
user_data = <<-EOF
94+
#!/bin/bash
95+
brew install git make golang
96+
EOF
97+
98+
root_block_device {
99+
volume_size = 200
100+
volume_type = "gp3"
101+
}
102+
103+
tags = {
104+
Name = "mac-1"
105+
}
106+
}
107+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
terraform {
18+
required_version = "~> 1.1"
19+
20+
required_providers {
21+
aws = {
22+
source = "hashicorp/aws"
23+
version = "~> 6.22.1"
24+
}
25+
}
26+
27+
backend "s3" {
28+
bucket = "k8-infra-macos-tfstate"
29+
key = "terraform.state"
30+
region = "us-east-2"
31+
}
32+
}
33+
34+
provider "aws" {
35+
region = "us-east-2"
36+
assume_role {
37+
role_arn = var.atlantis_role_arn
38+
}
39+
default_tags {
40+
tags = {
41+
Environment = "prod"
42+
group = "sig-k8s-infra"
43+
}
44+
}
45+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
variable "prefix" {
18+
description = "Prefix for every resource so that the resources can be created without using the same names. Useful for testing and staging"
19+
type = string
20+
default = "prod-"
21+
22+
validation {
23+
condition = can(regex(".*-$|^$", var.prefix))
24+
error_message = "The string must end with a hyphen or be empty."
25+
}
26+
}
27+
28+
variable "atlantis_role_arn" {
29+
description = "The ARN of the Atlantis IAM role"
30+
default = null
31+
}

infra/aws/terraform/macos/vpc.tf

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
module "vpc" {
18+
source = "terraform-aws-modules/vpc/aws"
19+
version = "~> 6.5"
20+
21+
name = "macos-vpc"
22+
23+
cidr = "10.1.0.0/16"
24+
25+
azs = ["us-east-2a", "us-east-2b", "us-east-2c"]
26+
private_subnets = ["10.1.0.0/24", "10.1.1.0/24", "10.1.2.0/24"]
27+
public_subnets = ["10.1.3.0/24", "10.1.4.0/24", "10.1.5.0/24"]
28+
29+
# Enable public IPv4 addresses
30+
map_public_ip_on_launch = true
31+
32+
# Enable IPv6
33+
enable_ipv6 = true
34+
create_egress_only_igw = true
35+
36+
# Assign IPv6 address on creation to each instance
37+
public_subnet_assign_ipv6_address_on_creation = true
38+
private_subnet_assign_ipv6_address_on_creation = true
39+
40+
# Used for calculating IPv6 CIDR based on the following formula:
41+
# cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.private_subnet_ipv6_prefixes[count.index])
42+
private_subnet_ipv6_prefixes = [0, 1, 2]
43+
public_subnet_ipv6_prefixes = [3, 4, 5]
44+
45+
# NAT Gateway allows connection to external services (e.g. Internet).
46+
enable_nat_gateway = true
47+
single_nat_gateway = true
48+
enable_dns_hostnames = true
49+
default_security_group_ingress = [
50+
{
51+
from_port = 22
52+
to_port = 22
53+
protocol = "tcp"
54+
cidr_blocks = "0.0.0.0/0"
55+
ipv6_cidr_blocks = "::/0"
56+
description = "Allow SSH from anywhere"
57+
}
58+
]
59+
60+
default_security_group_egress = [
61+
{
62+
from_port = 0
63+
to_port = 65535
64+
protocol = "tcp"
65+
cidr_blocks = "0.0.0.0/0"
66+
ipv6_cidr_blocks = "::/0"
67+
description = "Allow all outbound traffic"
68+
}
69+
]
70+
}

infra/aws/terraform/management-account/organization-accounts-workloads-prod.tf

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,22 @@ module "capa-ami" {
8383
"eu-south-2",
8484
]
8585
}
86+
87+
// This AWS accounts holds macOS Instances for kubernetes CI/CD
88+
module "macos" {
89+
source = "../modules/org-account"
90+
91+
account_name = "k8s-infra-macos"
92+
email = "k8s-infra-aws-admins+macos@kubernetes.io"
93+
parent_id = aws_organizations_organizational_unit.production.id
94+
tags = {
95+
"production" = "true",
96+
"environment" = "prod",
97+
"group" = "sig-k8s-infra",
98+
}
99+
permissions_map = {
100+
"aws-macos-maintainers" = [
101+
"AdministratorAccess",
102+
]
103+
}
104+
}

0 commit comments

Comments
 (0)