Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ hypershift install --render | oc delete -f -

## How to create a hosted cluster

The `hypershift` CLI tool comes with a command to help create an example hosted cluster. The cluster will come with a node pool consisting of two workers nodes.
The `hypershift` CLI tool comes with commands to help create an example hosted cluster. The cluster will come with a node pool consisting of two workers nodes.

**Prerequisites:**

Expand All @@ -55,14 +55,32 @@ The `hypershift` CLI tool comes with a command to help create an example hosted
- An SSH public key file for guest node access
- An [AWS credentials file](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) with permissions to create infrastructure for the cluster

Run the `hypershift` command to create an IAM instance profile for your workers:
```shell
hypershift create iam aws --aws-creds /my/aws-credentials
```
NOTE: The default profile name is `hypershift-worker-profile`. To use a different name (for example, in a shared account), use the `--profile-name` flag. The worker instance profile only needs to be created once per account and you can reuse it as needed for your clusters.

Run the `hypershift` command to create cloud infrastructure for your cluster:
NOTE: Infrastructure for a cluster can be created once and reused. However it should only correspond to one cluster at a time.
```shell
hypershift create infra aws --aws-creds /my/aws-credentials --infra-id INFRA-ID --region us-east-2 --output-file /tmp/infra.json
```
For `INFRA-ID` use a short identifier for your cluster such as `mycluster-1234`. It should be unique in your AWS account.
For region, the default region is `us-east-1`, specify a different region if desired.
The output file will contain JSON with the details of your provisioned infrastructure.

Run the `hypershift` command to generate and install the example cluster:

```shell
hypershift create cluster \
--pull-secret /my/pull-secret \
--aws-creds /my/aws-credentials \
--ssh-key /my/ssh-public-key
--ssh-key /my/ssh-public-key \
--infra-json /tmp/infra.json
```
NOTE: The file specified in the `--infra-json` flag should be the same file you created with the `create infra aws` command above.
If you created an instance profile named something other than `hypershift-worker-profile`, you need to pass the profile name with the `--instance-profile` flag.

Eventually the cluster's kubeconfig will become available and can be fetched and decoded locally:

Expand All @@ -79,6 +97,19 @@ To delete the cluster, run:
oc delete --namespace clusters
```

NOTE: After deleting the cluster, you can use an existing `infra.json` to create a new cluster.

To destroy your AWS infrastructure:
```shell
hypershift destroy infra aws --aws-creds /my/aws/credentials --infra-id INFRA-ID --region us-east-2
```
Specify the same INFRA-ID and region as your original `create infra` command.

To destroy the IAM instance profile:
```shell
hypershift destroy iam aws --aws-creds /my/aws-credentials
```

## How to add node pools to the example cluster

**Prerequisites:**
Expand Down
45 changes: 40 additions & 5 deletions api/fixtures/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ type ExampleOptions struct {
AWSCredentials []byte
SSHKey []byte
NodePoolReplicas int
InfraID string
ComputeCIDR string

AWS ExampleAWSOptions
}

type ExampleAWSOptions struct {
Region string
Zone string
VPCID string
SubnetID string
SecurityGroupID string
InstanceProfile string
InstanceType string
}

func (o ExampleOptions) Resources() *ExampleResources {
Expand Down Expand Up @@ -104,11 +118,32 @@ func (o ExampleOptions) Resources() *ExampleResources {
Image: o.ReleaseImage,
},
InitialComputeReplicas: o.NodePoolReplicas,
ServiceCIDR: "172.31.0.0/16",
PodCIDR: "10.132.0.0/14",
PullSecret: corev1.LocalObjectReference{Name: pullSecret.Name},
ProviderCreds: corev1.LocalObjectReference{Name: awsCredsSecret.Name},
SSHKey: corev1.LocalObjectReference{Name: sshKeySecret.Name},
Networking: hyperv1.ClusterNetworking{
ServiceCIDR: "172.31.0.0/16",
PodCIDR: "10.132.0.0/14",
MachineCIDR: o.ComputeCIDR,
},
InfraID: o.InfraID,
PullSecret: corev1.LocalObjectReference{Name: pullSecret.Name},
ProviderCreds: corev1.LocalObjectReference{Name: awsCredsSecret.Name},
SSHKey: corev1.LocalObjectReference{Name: sshKeySecret.Name},
Platform: hyperv1.PlatformSpec{
AWS: &hyperv1.AWSPlatformSpec{
Region: o.AWS.Region,
VPC: o.AWS.VPCID,
NodePoolDefaults: &hyperv1.AWSNodePoolPlatform{
InstanceType: o.AWS.InstanceType,
InstanceProfile: o.AWS.InstanceProfile,
Subnet: &hyperv1.AWSResourceReference{
ID: &o.AWS.SubnetID,
},
SecurityGroups: []hyperv1.AWSResourceReference{
{ID: &o.AWS.SecurityGroupID},
},
Zone: o.AWS.Zone,
},
},
},
},
}

Expand Down
3 changes: 3 additions & 0 deletions api/v1alpha1/hosted_controlplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ type HostedControlPlaneSpec struct {
PullSecret corev1.LocalObjectReference `json:"pullSecret"`
ServiceCIDR string `json:"serviceCIDR"`
PodCIDR string `json:"podCIDR"`
MachineCIDR string `json:"machineCIDR"`
SSHKey corev1.LocalObjectReference `json:"sshKey"`
ProviderCreds corev1.LocalObjectReference `json:"providerCreds"`
InfraID string `json:"infraID"`
Platform PlatformSpec `json:"platform"`
}

type ConditionType string
Expand Down
51 changes: 51 additions & 0 deletions api/v1alpha1/hostedcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,61 @@ type HostedClusterSpec struct {

SSHKey corev1.LocalObjectReference `json:"sshKey"`

// ProviderCreds is a reference to a secret containing cloud account info
ProviderCreds corev1.LocalObjectReference `json:"providerCreds"`

// Networking contains network-specific settings for this cluster
Networking ClusterNetworking `json:"networking"`

Platform PlatformSpec `json:"platform"`

// InfraID is used to identify the cluster in cloud platforms
InfraID string `json:"infraID,omitempty"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for the record I'm not a fan of the UX exposing the infraID in the API. I think we could infer it from the VPC ID and let that be the only contract.
Discussed with @csrwng to go as in this PR for now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should definitely do a follow up. Right now specifying the infra ID allows me to avoid doing an AWS call from the hypershift operator to discover it. I can pass it directly to the control plane where it's needed for the cloud config.

}

type ClusterNetworking struct {
ServiceCIDR string `json:"serviceCIDR"`
PodCIDR string `json:"podCIDR"`
MachineCIDR string `json:"machineCIDR"`
}

type PlatformSpec struct {
// AWS contains AWS-specific settings for the HostedCluster
// +optional
AWS *AWSPlatformSpec `json:"aws,omitempty"`
}

type AWSPlatformSpec struct {
// Region is the AWS region for the cluster
Region string `json:"region"`

// VPC specifies the VPC used for the cluster
VPC string `json:"vpc"`

// NodePoolDefaults specifies the default platform
// +optional
NodePoolDefaults *AWSNodePoolPlatform `json:"nodePoolDefaults,omitempty"`

// ServiceEndpoints list contains custom endpoints which will override default
// service endpoint of AWS Services.
// There must be only one ServiceEndpoint for a service.
// +optional
ServiceEndpoints []AWSServiceEndpoint `json:"serviceEndpoints,omitempty"`
}

// AWSServiceEndpoint stores the configuration for services to
// override existing defaults of AWS Services.
type AWSServiceEndpoint struct {
// Name is the name of the AWS service.
// This must be provided and cannot be empty.
Name string `json:"name"`

// URL is fully qualified URI with scheme https, that overrides the default generated
// endpoint for a client.
// This must be provided and cannot be empty.
//
// +kubebuilder:validation:Pattern=`^https://`
URL string `json:"url"`
}

type Release struct {
Expand Down
17 changes: 14 additions & 3 deletions api/v1alpha1/nodepool_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,20 @@ type NodePoolPlatform struct {
type AWSNodePoolPlatform struct {
// InstanceType defines the ec2 instance type.
// eg. m4-large
InstanceType string `json:"instanceType"`
InstanceProfile string `json:"instanceProfile,omitempty"`
Subnet *AWSResourceReference `json:"subnet,omitempty"`
InstanceType string `json:"instanceType"`
InstanceProfile string `json:"instanceProfile,omitempty"`
// Subnet is the subnet to use for instances
// +optional
Subnet *AWSResourceReference `json:"subnet,omitempty"`
// AMI is the image id to use
// +optional
AMI string `json:"ami,omitempty"`
// SecurityGroups is the set of security groups to associate with nodepool machines
// +optional
SecurityGroups []AWSResourceReference `json:"securityGroups,omitempty"`
// Zone is the availability zone where the instances are created
// +optional
Zone string `json:"zone,omitempty"`
}

// AWSResourceReference is a reference to a specific AWS resource by ID, ARN, or filters.
Expand Down
89 changes: 87 additions & 2 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading