import requests
url = "https://api.platform.ankra.app/org/clusters/aws/preflight"
payload = {
"name": "<string>",
"credential_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"ssh_key_credential_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"region": "<string>"
}
headers = {
"cookie": "ankra_session=",
"X-Ankra-CSRF": "<x-ankra-csrf>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
cookie: 'ankra_session=',
'X-Ankra-CSRF': '<x-ankra-csrf>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: '<string>',
credential_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
ssh_key_credential_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
region: '<string>'
})
};
fetch('https://api.platform.ankra.app/org/clusters/aws/preflight', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));curl --request POST \
--url https://api.platform.ankra.app/org/clusters/aws/preflight \
--header 'Content-Type: application/json' \
--header 'X-Ankra-CSRF: <x-ankra-csrf>' \
--cookie ankra_session= \
--data '
{
"name": "<string>",
"credential_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"ssh_key_credential_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"region": "<string>"
}
'{
"items": [
{
"check": "<string>",
"status": "ok",
"message": "<string>"
}
],
"can_proceed": true,
"network_ownership": "created",
"resolved_egress_mode": "nat_gateway",
"resolved_availability_zones": [
"<string>"
]
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": "Cluster not found"
}Preflight an AWS EC2 cluster create (browser session)
Browser session authentication; RBAC permission clusters.create. Runs every check the create runs against AWS without creating anything. Each item is three-state: ok, warning (a read Ankra could not perform, or a caveat such as flannel not enforcing the IMDS guard), or error. network_ownership says which shape the request describes; a created network is checked for its CIDR plan (cidr), its zones (zones - chosen here when the request names none), the VPC, NAT-gateway and elastic-IP quotas, while an adopted VPC is checked for its VPC, subnets, egress routes and bastion subnet. resolved_egress_mode is the mode the create will run under, null when it could not be decided; resolved_availability_zones the zones the cluster will spread over. Answers 404 while the organisation’s aws_provider feature flag is off.
import requests
url = "https://api.platform.ankra.app/org/clusters/aws/preflight"
payload = {
"name": "<string>",
"credential_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"ssh_key_credential_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"region": "<string>"
}
headers = {
"cookie": "ankra_session=",
"X-Ankra-CSRF": "<x-ankra-csrf>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
cookie: 'ankra_session=',
'X-Ankra-CSRF': '<x-ankra-csrf>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: '<string>',
credential_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
ssh_key_credential_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
region: '<string>'
})
};
fetch('https://api.platform.ankra.app/org/clusters/aws/preflight', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));curl --request POST \
--url https://api.platform.ankra.app/org/clusters/aws/preflight \
--header 'Content-Type: application/json' \
--header 'X-Ankra-CSRF: <x-ankra-csrf>' \
--cookie ankra_session= \
--data '
{
"name": "<string>",
"credential_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"ssh_key_credential_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"region": "<string>"
}
'{
"items": [
{
"check": "<string>",
"status": "ok",
"message": "<string>"
}
],
"can_proceed": true,
"network_ownership": "created",
"resolved_egress_mode": "nat_gateway",
"resolved_availability_zones": [
"<string>"
]
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": "Cluster not found"
}Authorizations
Body
POST /clusters/aws body. Two network shapes (ADR 0015 §3): omit vpc_id and Ankra creates the VPC from network_ip_range over availability_zones (one public /24 and one private /20 per zone, an internet gateway, and NAT gateways as the default egress), all torn down with the cluster; pass vpc_id with node_subnet_ids and bastion_subnet_id to adopt an existing VPC, whose network Ankra never modifies. Nodes never receive a public IP; the bastion holds the elastic IP and is the SSH hop (and the NAT instance in bastion_nat mode).
Cluster name: 1 to 53 lowercase letters, digits and hyphens, starting with a letter and ending with a letter or digit (an RFC 1035 DNS label). It prefixes every server hostname of the cluster; a create carrying any other name is refused, and nothing is created.
1 - 53^[a-z]([-a-z0-9]*[a-z0-9])?$Created VPC only: the zones the VPC is laid out over, in the order the spread walks them (the bastion and the first control plane land in the first). Each must exist and be available in the region; more than one needs control_plane_count >= 3. Omitted: the preflight picks one zone when control_plane_count < 3 and three otherwise, from the region's available zones in name order, and reports them as resolved_availability_zones. Refused (422) alongside vpc_id.
Which modes apply depends on the network shape. Created VPC: nat_gateway (default; Ankra-created NAT gateways with their own elastic IPs) or bastion_nat (the bastion is the NAT instance); existing is refused (422). Adopted VPC: omitted is resolved by preflight; existing keeps the subnets' NAT routing; bastion_nat makes the bastion the NAT instance behind one Ankra-owned route table and is refused when a node subnet carries instances Ankra did not create; nat_gateway is refused (422) because it would re-point the customer's route tables.
nat_gateway, bastion_nat, existing GitOps provider of the repository the cluster is bootstrapped onto. Omitted is github, where gitops_repository is owner/name. bitbucket_cloud names the repository by gitops_workspace and gitops_repo_slug (or gitops_repository as workspace/repo_slug) and binds it as a Bitbucket Cloud repository.
github, bitbucket_cloud Install the Kubernetes Gateway API beside Traefik's Ingress: the Gateway API standard CRDs, Traefik's Gateway provider with the traefik GatewayClass and a shared traefik-gateway Gateway in the traefik namespace (a plain HTTP listener that accepts routes from every namespace), cert-manager's Gateway support, and external-dns publishing of HTTPRoute hostnames. Ingress keeps working; one Traefik serves both. Requires include_networking.
Response
Successful response