github.com/openshift/installer@v1.4.17/upi/aws/cloudformation/02_cluster_infra.yaml (about) 1 AWSTemplateFormatVersion: 2010-09-09 2 Description: Template for OpenShift Cluster Network Elements (Route53 & LBs) 3 4 Parameters: 5 ClusterName: 6 AllowedPattern: ^([a-zA-Z][a-zA-Z0-9\-]{0,26})$ 7 MaxLength: 27 8 MinLength: 1 9 ConstraintDescription: Cluster name must be alphanumeric, start with a letter, and have a maximum of 27 characters. 10 Description: A short, representative cluster name to use for host names and other identifying names. 11 Type: String 12 InfrastructureName: 13 AllowedPattern: ^([a-zA-Z][a-zA-Z0-9\-]{0,26})$ 14 MaxLength: 27 15 MinLength: 1 16 ConstraintDescription: Infrastructure name must be alphanumeric, start with a letter, and have a maximum of 27 characters. 17 Description: A short, unique cluster ID used to tag cloud resources and identify items owned or used by the cluster. 18 Type: String 19 HostedZoneId: 20 Description: The Route53 public zone ID to register the targets with, such as Z21IXYZABCZ2A4. 21 Type: String 22 HostedZoneName: 23 Description: The Route53 zone to register the targets with, such as example.com. Omit the trailing period. 24 Type: String 25 Default: "example.com" 26 PublicSubnets: 27 Description: The internet-facing subnets. 28 Type: List<AWS::EC2::Subnet::Id> 29 PrivateSubnets: 30 Description: The internal subnets. 31 Type: List<AWS::EC2::Subnet::Id> 32 VpcId: 33 Description: The VPC-scoped resources will belong to this VPC. 34 Type: AWS::EC2::VPC::Id 35 36 Metadata: 37 AWS::CloudFormation::Interface: 38 ParameterGroups: 39 - Label: 40 default: "Cluster Information" 41 Parameters: 42 - ClusterName 43 - InfrastructureName 44 - Label: 45 default: "Network Configuration" 46 Parameters: 47 - VpcId 48 - PublicSubnets 49 - PrivateSubnets 50 - Label: 51 default: "DNS" 52 Parameters: 53 - HostedZoneName 54 - HostedZoneId 55 ParameterLabels: 56 ClusterName: 57 default: "Cluster Name" 58 InfrastructureName: 59 default: "Infrastructure Name" 60 VpcId: 61 default: "VPC ID" 62 PublicSubnets: 63 default: "Public Subnets" 64 PrivateSubnets: 65 default: "Private Subnets" 66 HostedZoneName: 67 default: "Public Hosted Zone Name" 68 HostedZoneId: 69 default: "Public Hosted Zone ID" 70 71 Resources: 72 ExtApiElb: 73 Type: AWS::ElasticLoadBalancingV2::LoadBalancer 74 Properties: 75 Name: !Join ["-", [!Ref InfrastructureName, "ext"]] 76 IpAddressType: ipv4 77 Subnets: !Ref PublicSubnets 78 Type: network 79 80 IntApiElb: 81 Type: AWS::ElasticLoadBalancingV2::LoadBalancer 82 Properties: 83 Name: !Join ["-", [!Ref InfrastructureName, "int"]] 84 Scheme: internal 85 IpAddressType: ipv4 86 Subnets: !Ref PrivateSubnets 87 Type: network 88 89 IntDns: 90 Type: "AWS::Route53::HostedZone" 91 Properties: 92 HostedZoneConfig: 93 Comment: "Managed by CloudFormation" 94 Name: !Join [".", [!Ref ClusterName, !Ref HostedZoneName]] 95 HostedZoneTags: 96 - Key: Name 97 Value: !Join ["-", [!Ref InfrastructureName, "int"]] 98 - Key: !Join ["", ["kubernetes.io/cluster/", !Ref InfrastructureName]] 99 Value: "owned" 100 VPCs: 101 - VPCId: !Ref VpcId 102 VPCRegion: !Ref "AWS::Region" 103 104 ExternalApiServerRecord: 105 Type: AWS::Route53::RecordSetGroup 106 Properties: 107 Comment: Alias record for the API server 108 HostedZoneId: !Ref HostedZoneId 109 RecordSets: 110 - Name: 111 !Join [ 112 ".", 113 ["api", !Ref ClusterName, !Join ["", [!Ref HostedZoneName, "."]]], 114 ] 115 Type: A 116 AliasTarget: 117 HostedZoneId: !GetAtt ExtApiElb.CanonicalHostedZoneID 118 DNSName: !GetAtt ExtApiElb.DNSName 119 120 InternalApiServerRecord: 121 Type: AWS::Route53::RecordSetGroup 122 Properties: 123 Comment: Alias record for the API server 124 HostedZoneId: !Ref IntDns 125 RecordSets: 126 - Name: 127 !Join [ 128 ".", 129 ["api", !Ref ClusterName, !Join ["", [!Ref HostedZoneName, "."]]], 130 ] 131 Type: A 132 AliasTarget: 133 HostedZoneId: !GetAtt IntApiElb.CanonicalHostedZoneID 134 DNSName: !GetAtt IntApiElb.DNSName 135 - Name: 136 !Join [ 137 ".", 138 ["api-int", !Ref ClusterName, !Join ["", [!Ref HostedZoneName, "."]]], 139 ] 140 Type: A 141 AliasTarget: 142 HostedZoneId: !GetAtt IntApiElb.CanonicalHostedZoneID 143 DNSName: !GetAtt IntApiElb.DNSName 144 145 ExternalApiListener: 146 Type: AWS::ElasticLoadBalancingV2::Listener 147 Properties: 148 DefaultActions: 149 - Type: forward 150 TargetGroupArn: 151 Ref: ExternalApiTargetGroup 152 LoadBalancerArn: 153 Ref: ExtApiElb 154 Port: 6443 155 Protocol: TCP 156 157 ExternalApiTargetGroup: 158 Type: AWS::ElasticLoadBalancingV2::TargetGroup 159 Properties: 160 HealthCheckIntervalSeconds: 10 161 HealthCheckPath: "/readyz" 162 HealthCheckPort: 6443 163 HealthCheckProtocol: HTTPS 164 HealthyThresholdCount: 2 165 UnhealthyThresholdCount: 2 166 Port: 6443 167 Protocol: TCP 168 TargetType: ip 169 VpcId: 170 Ref: VpcId 171 TargetGroupAttributes: 172 - Key: deregistration_delay.timeout_seconds 173 Value: 60 174 175 InternalApiListener: 176 Type: AWS::ElasticLoadBalancingV2::Listener 177 Properties: 178 DefaultActions: 179 - Type: forward 180 TargetGroupArn: 181 Ref: InternalApiTargetGroup 182 LoadBalancerArn: 183 Ref: IntApiElb 184 Port: 6443 185 Protocol: TCP 186 187 InternalApiTargetGroup: 188 Type: AWS::ElasticLoadBalancingV2::TargetGroup 189 Properties: 190 HealthCheckIntervalSeconds: 10 191 HealthCheckPath: "/readyz" 192 HealthCheckPort: 6443 193 HealthCheckProtocol: HTTPS 194 HealthyThresholdCount: 2 195 UnhealthyThresholdCount: 2 196 Port: 6443 197 Protocol: TCP 198 TargetType: ip 199 VpcId: 200 Ref: VpcId 201 TargetGroupAttributes: 202 - Key: deregistration_delay.timeout_seconds 203 Value: 60 204 205 InternalServiceInternalListener: 206 Type: AWS::ElasticLoadBalancingV2::Listener 207 Properties: 208 DefaultActions: 209 - Type: forward 210 TargetGroupArn: 211 Ref: InternalServiceTargetGroup 212 LoadBalancerArn: 213 Ref: IntApiElb 214 Port: 22623 215 Protocol: TCP 216 217 InternalServiceTargetGroup: 218 Type: AWS::ElasticLoadBalancingV2::TargetGroup 219 Properties: 220 HealthCheckIntervalSeconds: 10 221 HealthCheckPath: "/healthz" 222 HealthCheckPort: 22623 223 HealthCheckProtocol: HTTPS 224 HealthyThresholdCount: 2 225 UnhealthyThresholdCount: 2 226 Port: 22623 227 Protocol: TCP 228 TargetType: ip 229 VpcId: 230 Ref: VpcId 231 TargetGroupAttributes: 232 - Key: deregistration_delay.timeout_seconds 233 Value: 60 234 235 RegisterTargetLambdaIamRole: 236 Type: AWS::IAM::Role 237 Properties: 238 RoleName: !Join ["-", [!Ref InfrastructureName, "nlb", "lambda", "role"]] 239 AssumeRolePolicyDocument: 240 Version: "2012-10-17" 241 Statement: 242 - Effect: "Allow" 243 Principal: 244 Service: 245 - "lambda.amazonaws.com" 246 Action: 247 - "sts:AssumeRole" 248 Path: "/" 249 Policies: 250 - PolicyName: !Join ["-", [!Ref InfrastructureName, "master", "policy"]] 251 PolicyDocument: 252 Version: "2012-10-17" 253 Statement: 254 - Effect: "Allow" 255 Action: 256 [ 257 "elasticloadbalancing:RegisterTargets", 258 "elasticloadbalancing:DeregisterTargets", 259 ] 260 Resource: !Ref InternalApiTargetGroup 261 - Effect: "Allow" 262 Action: 263 [ 264 "elasticloadbalancing:RegisterTargets", 265 "elasticloadbalancing:DeregisterTargets", 266 ] 267 Resource: !Ref InternalServiceTargetGroup 268 - Effect: "Allow" 269 Action: 270 [ 271 "elasticloadbalancing:RegisterTargets", 272 "elasticloadbalancing:DeregisterTargets", 273 ] 274 Resource: !Ref ExternalApiTargetGroup 275 276 RegisterNlbIpTargets: 277 Type: "AWS::Lambda::Function" 278 Properties: 279 Handler: "index.handler" 280 Role: 281 Fn::GetAtt: 282 - "RegisterTargetLambdaIamRole" 283 - "Arn" 284 Code: 285 ZipFile: | 286 import json 287 import boto3 288 import cfnresponse 289 def handler(event, context): 290 elb = boto3.client('elbv2') 291 if event['RequestType'] == 'Delete': 292 elb.deregister_targets(TargetGroupArn=event['ResourceProperties']['TargetArn'],Targets=[{'Id': event['ResourceProperties']['TargetIp']}]) 293 elif event['RequestType'] == 'Create': 294 elb.register_targets(TargetGroupArn=event['ResourceProperties']['TargetArn'],Targets=[{'Id': event['ResourceProperties']['TargetIp']}]) 295 responseData = {} 296 cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, event['ResourceProperties']['TargetArn']+event['ResourceProperties']['TargetIp']) 297 Runtime: "python3.8" 298 Timeout: 120 299 300 RegisterSubnetTagsLambdaIamRole: 301 Type: AWS::IAM::Role 302 Properties: 303 RoleName: !Join ["-", [!Ref InfrastructureName, "subnet-tags-lambda-role"]] 304 AssumeRolePolicyDocument: 305 Version: "2012-10-17" 306 Statement: 307 - Effect: "Allow" 308 Principal: 309 Service: 310 - "lambda.amazonaws.com" 311 Action: 312 - "sts:AssumeRole" 313 Path: "/" 314 Policies: 315 - PolicyName: !Join ["-", [!Ref InfrastructureName, "subnet-tagging-policy"]] 316 PolicyDocument: 317 Version: "2012-10-17" 318 Statement: 319 - Effect: "Allow" 320 Action: 321 [ 322 "ec2:DeleteTags", 323 "ec2:CreateTags" 324 ] 325 Resource: "arn:aws:ec2:*:*:subnet/*" 326 - Effect: "Allow" 327 Action: 328 [ 329 "ec2:DescribeSubnets", 330 "ec2:DescribeTags" 331 ] 332 Resource: "*" 333 334 RegisterSubnetTags: 335 Type: "AWS::Lambda::Function" 336 Properties: 337 Handler: "index.handler" 338 Role: 339 Fn::GetAtt: 340 - "RegisterSubnetTagsLambdaIamRole" 341 - "Arn" 342 Code: 343 ZipFile: | 344 import json 345 import boto3 346 import cfnresponse 347 def handler(event, context): 348 ec2_client = boto3.client('ec2') 349 if event['RequestType'] == 'Delete': 350 for subnet_id in event['ResourceProperties']['Subnets']: 351 ec2_client.delete_tags(Resources=[subnet_id], Tags=[{'Key': 'kubernetes.io/cluster/' + event['ResourceProperties']['InfrastructureName']}]); 352 elif event['RequestType'] == 'Create': 353 for subnet_id in event['ResourceProperties']['Subnets']: 354 ec2_client.create_tags(Resources=[subnet_id], Tags=[{'Key': 'kubernetes.io/cluster/' + event['ResourceProperties']['InfrastructureName'], 'Value': 'shared'}]); 355 responseData = {} 356 cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, event['ResourceProperties']['InfrastructureName']+event['ResourceProperties']['Subnets'][0]) 357 Runtime: "python3.8" 358 Timeout: 120 359 360 RegisterPublicSubnetTags: 361 Type: Custom::SubnetRegister 362 Properties: 363 ServiceToken: !GetAtt RegisterSubnetTags.Arn 364 InfrastructureName: !Ref InfrastructureName 365 Subnets: !Ref PublicSubnets 366 367 RegisterPrivateSubnetTags: 368 Type: Custom::SubnetRegister 369 Properties: 370 ServiceToken: !GetAtt RegisterSubnetTags.Arn 371 InfrastructureName: !Ref InfrastructureName 372 Subnets: !Ref PrivateSubnets 373 374 Outputs: 375 PrivateHostedZoneId: 376 Description: Hosted zone ID for the private DNS, which is required for private records. 377 Value: !Ref IntDns 378 ExternalApiLoadBalancerName: 379 Description: Full name of the external API load balancer. 380 Value: !GetAtt ExtApiElb.LoadBalancerFullName 381 InternalApiLoadBalancerName: 382 Description: Full name of the internal API load balancer. 383 Value: !GetAtt IntApiElb.LoadBalancerFullName 384 ApiServerDnsName: 385 Description: Full hostname of the API server, which is required for the Ignition config files. 386 Value: !Join [".", ["api-int", !Ref ClusterName, !Ref HostedZoneName]] 387 RegisterNlbIpTargetsLambda: 388 Description: Lambda ARN useful to help register or deregister IP targets for these load balancers. 389 Value: !GetAtt RegisterNlbIpTargets.Arn 390 ExternalApiTargetGroupArn: 391 Description: ARN of the external API target group. 392 Value: !Ref ExternalApiTargetGroup 393 InternalApiTargetGroupArn: 394 Description: ARN of the internal API target group. 395 Value: !Ref InternalApiTargetGroup 396 InternalServiceTargetGroupArn: 397 Description: ARN of the internal service target group. 398 Value: !Ref InternalServiceTargetGroup