Created
December 28, 2024 19:52
-
-
Save dmc5179/8b76a6b288f908e228c55d52491b5a4c to your computer and use it in GitHub Desktop.
AWS Cloudformation template to create a disconnected environment for OpenShift testing
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
AWSTemplateFormatVersion: 2010-09-09 | |
Description: Template for creating a disconnected VPC in up to 3 AZs | |
Parameters: | |
VpcCidr: | |
AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-4]))$ | |
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-24. | |
Default: 10.0.0.0/16 | |
Description: CIDR block for VPC. | |
Type: String | |
AvailabilityZoneCount: | |
ConstraintDescription: "The number of availability zones. (Min: 1, Max: 3)" | |
MinValue: 1 | |
MaxValue: 3 | |
Default: 3 | |
Description: "How many AZs to create VPC subnets for. (Min: 1, Max: 3)" | |
Type: Number | |
SubnetBits: | |
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/19-27. | |
MinValue: 5 | |
MaxValue: 13 | |
Default: 12 | |
Description: "Size of each subnet to create within the availability zones. (Min: 5 = /27, Max: 13 = /19)" | |
Type: Number | |
AmiId: | |
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>' | |
Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2' | |
Description: AMI ID pointer in AWS Systems Manager Parameter Store. Default value points to the | |
latest Amazon Linux 2 AMI ID. | |
KeyName: | |
Type: AWS::EC2::KeyPair::KeyName | |
Description: Name of RSA key for EC2 access for testing and troubleshooting. | |
OpenShiftVersion: | |
Default: "4.17.9" | |
Description: OpenShift Version Number | |
Type: String | |
PullSecretJson: | |
Description: OpenShift 4 Pull Secret JSON | |
Type: String | |
Default: "{}" | |
NATInstanceType: | |
Type: String | |
Default: t3.large | |
Description: Instance type to use to launch the NAT instance. | |
AllowedValues: | |
- t3.nano | |
- t3.micro | |
- t3.small | |
- t3.medium | |
- t3.large | |
- m4.large | |
- m4.xlarge | |
- m4.2xlarge | |
- m5.large | |
- m5.xlarge | |
- m5.2xlarge | |
- c4.large | |
- c4.xlarge | |
- c4.large | |
- c5.large | |
- c5.xlarge | |
- c5.large | |
BastionInstanceType: | |
Type: String | |
Default: t3.large | |
Description: Instance type to use to launch the Bastion Instance. | |
RegistryInstanceType: | |
Type: String | |
Default: t3.large | |
Description: Instance type to use to launch the Registry instance. | |
Metadata: | |
AWS::CloudFormation::Interface: | |
ParameterGroups: | |
- Label: | |
default: "Network Configuration" | |
Parameters: | |
- VpcCidr | |
- SubnetBits | |
- Label: | |
default: "Availability Zones" | |
Parameters: | |
- AvailabilityZoneCount | |
ParameterLabels: | |
AvailabilityZoneCount: | |
default: "Availability Zone Count" | |
VpcCidr: | |
default: "VPC CIDR" | |
SubnetBits: | |
default: "Bits Per Subnet" | |
Mappings: | |
RHELMap: | |
us-east-1: | |
HVM64: ami-0b4466ff0aec45222 | |
us-east-2: | |
HVM64: ami-002acc74c401fa86b | |
us-west-1: | |
HVM64: ami-02bfa5a117cd76b94 | |
eu-west-1: | |
HVM64: ami-01810eb03ac7f790c | |
Conditions: | |
DoAz3: !Equals [3, !Ref AvailabilityZoneCount] | |
DoAz2: !Or [!Equals [2, !Ref AvailabilityZoneCount], Condition: DoAz3] | |
Resources: | |
VPC: | |
Type: "AWS::EC2::VPC" | |
Properties: | |
EnableDnsSupport: "true" | |
EnableDnsHostnames: "true" | |
CidrBlock: !Ref VpcCidr | |
##################################################################### | |
# Public Subnets | |
PublicSubnet: | |
Type: "AWS::EC2::Subnet" | |
Properties: | |
VpcId: !Ref VPC | |
CidrBlock: !Select [0, !Cidr [!Ref VpcCidr, 6, !Ref SubnetBits]] | |
MapPublicIpOnLaunch: true | |
Tags: | |
- Key: Name | |
Value: !Sub 'Public Subnet - ${AWS::StackName}' | |
AvailabilityZone: !Select | |
- 0 | |
- Fn::GetAZs: !Ref "AWS::Region" | |
PublicSubnet2: | |
Type: "AWS::EC2::Subnet" | |
Condition: DoAz2 | |
Properties: | |
VpcId: !Ref VPC | |
CidrBlock: !Select [1, !Cidr [!Ref VpcCidr, 6, !Ref SubnetBits]] | |
MapPublicIpOnLaunch: true | |
Tags: | |
- Key: Name | |
Value: !Sub 'Public Subnet 2 - ${AWS::StackName}' | |
AvailabilityZone: !Select | |
- 1 | |
- Fn::GetAZs: !Ref "AWS::Region" | |
PublicSubnet3: | |
Type: "AWS::EC2::Subnet" | |
Condition: DoAz3 | |
Properties: | |
VpcId: !Ref VPC | |
CidrBlock: !Select [2, !Cidr [!Ref VpcCidr, 6, !Ref SubnetBits]] | |
MapPublicIpOnLaunch: true | |
Tags: | |
- Key: Name | |
Value: !Sub 'Public Subnet 3 - ${AWS::StackName}' | |
AvailabilityZone: !Select | |
- 2 | |
- Fn::GetAZs: !Ref "AWS::Region" | |
InternetGateway: | |
Type: "AWS::EC2::InternetGateway" | |
GatewayToInternet: | |
Type: "AWS::EC2::VPCGatewayAttachment" | |
Properties: | |
VpcId: !Ref VPC | |
InternetGatewayId: !Ref InternetGateway | |
PublicRouteTable: | |
Type: "AWS::EC2::RouteTable" | |
Properties: | |
VpcId: !Ref VPC | |
PublicRoute: | |
Type: "AWS::EC2::Route" | |
DependsOn: GatewayToInternet | |
Properties: | |
RouteTableId: !Ref PublicRouteTable | |
DestinationCidrBlock: 0.0.0.0/0 | |
GatewayId: !Ref InternetGateway | |
PublicSubnetRouteTableAssociation: | |
Type: "AWS::EC2::SubnetRouteTableAssociation" | |
Properties: | |
SubnetId: !Ref PublicSubnet | |
RouteTableId: !Ref PublicRouteTable | |
PublicSubnetRouteTableAssociation2: | |
Type: "AWS::EC2::SubnetRouteTableAssociation" | |
Condition: DoAz2 | |
Properties: | |
SubnetId: !Ref PublicSubnet2 | |
RouteTableId: !Ref PublicRouteTable | |
PublicSubnetRouteTableAssociation3: | |
Condition: DoAz3 | |
Type: "AWS::EC2::SubnetRouteTableAssociation" | |
Properties: | |
SubnetId: !Ref PublicSubnet3 | |
RouteTableId: !Ref PublicRouteTable | |
####################################################################3 | |
# Private Subnets | |
PrivateSubnet: | |
Type: "AWS::EC2::Subnet" | |
Properties: | |
VpcId: !Ref VPC | |
CidrBlock: !Select [3, !Cidr [!Ref VpcCidr, 6, !Ref SubnetBits]] | |
Tags: | |
- Key: Name | |
Value: !Sub 'Private Subnet - ${AWS::StackName}' | |
AvailabilityZone: !Select | |
- 0 | |
- Fn::GetAZs: !Ref "AWS::Region" | |
PrivateRouteTable: | |
Type: AWS::EC2::RouteTable | |
Properties: | |
VpcId: !Ref VPC | |
Tags: | |
- Key: Name | |
Value: !Sub 'Private Route Table - ${AWS::StackName}' | |
PrivateRouteTableSubnetAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnet | |
RouteTableId: !Ref PrivateRouteTable | |
PrivateSubnetNATRoute: | |
Type: AWS::EC2::Route | |
DependsOn: NATInstance | |
Properties: | |
RouteTableId: | |
Ref: PrivateRouteTable | |
DestinationCidrBlock: 0.0.0.0/0 | |
InstanceId: !Ref NATInstance | |
PrivateSubnet2: | |
Type: "AWS::EC2::Subnet" | |
Condition: DoAz2 | |
Properties: | |
VpcId: !Ref VPC | |
CidrBlock: !Select [4, !Cidr [!Ref VpcCidr, 6, !Ref SubnetBits]] | |
Tags: | |
- Key: Name | |
Value: !Sub 'Private Subnet 2 - ${AWS::StackName}' | |
AvailabilityZone: !Select | |
- 1 | |
- Fn::GetAZs: !Ref "AWS::Region" | |
PrivateRouteTable2: | |
Type: AWS::EC2::RouteTable | |
Condition: DoAz2 | |
Properties: | |
VpcId: !Ref VPC | |
Tags: | |
- Key: Name | |
Value: !Sub 'Private Route Table 2 - ${AWS::StackName}' | |
PrivateRouteTableSubnetAssociation2: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Condition: DoAz2 | |
Properties: | |
SubnetId: !Ref PrivateSubnet2 | |
RouteTableId: !Ref PrivateRouteTable2 | |
PrivateSubnetNATRoute2: | |
Type: AWS::EC2::Route | |
Condition: DoAz2 | |
DependsOn: NATInstance | |
Properties: | |
RouteTableId: | |
Ref: PrivateRouteTable2 | |
DestinationCidrBlock: 0.0.0.0/0 | |
InstanceId: !Ref NATInstance | |
PrivateSubnet3: | |
Type: "AWS::EC2::Subnet" | |
Condition: DoAz3 | |
Properties: | |
VpcId: !Ref VPC | |
CidrBlock: !Select [5, !Cidr [!Ref VpcCidr, 6, !Ref SubnetBits]] | |
Tags: | |
- Key: Name | |
Value: !Sub 'Private Subnet 3 - ${AWS::StackName}' | |
AvailabilityZone: !Select | |
- 2 | |
- Fn::GetAZs: !Ref "AWS::Region" | |
PrivateRouteTable3: | |
Type: AWS::EC2::RouteTable | |
Condition: DoAz3 | |
Properties: | |
VpcId: !Ref VPC | |
Tags: | |
- Key: Name | |
Value: !Sub 'Private Route Table 3 - ${AWS::StackName}' | |
PrivateRouteTableSubnetAssociation3: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Condition: DoAz3 | |
Properties: | |
SubnetId: !Ref PrivateSubnet3 | |
RouteTableId: !Ref PrivateRouteTable3 | |
PrivateSubnetNATRoute3: | |
Type: AWS::EC2::Route | |
Condition: DoAz3 | |
DependsOn: NATInstance | |
Properties: | |
RouteTableId: | |
Ref: PrivateRouteTable3 | |
DestinationCidrBlock: 0.0.0.0/0 | |
InstanceId: !Ref NATInstance | |
############################################################################## | |
# | |
# NAT Instance | |
######## | |
NATInstanceRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- ec2.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Path: / | |
ManagedPolicyArns: | |
- arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM | |
- arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy | |
Policies: | |
- PolicyName: root | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
# - Effect: Allow | |
# Action: | |
# - s3:GetObject | |
# - s3:ListObject | |
# Resource: !Sub '${S3Bucket.Arn}*' | |
- Effect: Allow | |
Action: | |
- ec2:ModifyInstanceAttribute | |
Resource: '*' | |
NATInstanceProfile: | |
Type: AWS::IAM::InstanceProfile | |
Properties: | |
Roles: | |
- !Ref NATInstanceRole | |
Path: / | |
NATInstanceSG: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: Allows HTTP and HTTPS from private instances to NAT instances | |
SecurityGroupIngress: | |
- CidrIp: !Ref VpcCidr | |
FromPort: 22 | |
ToPort: 22 | |
IpProtocol: tcp | |
- CidrIp: !Ref VpcCidr | |
FromPort: 80 | |
ToPort: 80 | |
IpProtocol: TCP | |
- CidrIp: !Ref VpcCidr | |
FromPort: 443 | |
ToPort: 443 | |
IpProtocol: TCP | |
# - CidrIp: '10.0.0.0/25' | |
# FromPort: 80 | |
# ToPort: 80 | |
# IpProtocol: TCP | |
# - CidrIp: '10.0.0.0/25' | |
# FromPort: 443 | |
# ToPort: 443 | |
# IpProtocol: TCP | |
Tags: | |
- Key: Name | |
Value: !Sub 'NAT Instance SG - ${AWS::StackName}' | |
VpcId: !Ref VPC | |
NATInstance: | |
Type: AWS::EC2::Instance | |
Properties: | |
ImageId: !FindInMap [RHELMap, !Ref "AWS::Region", HVM64] | |
InstanceType: !Ref NATInstanceType | |
IamInstanceProfile: !Ref NATInstanceProfile | |
KeyName: !Ref KeyName | |
Tags: | |
- Key: Name | |
Value: !Sub 'NAT Instance - ${AWS::StackName}' | |
NetworkInterfaces: | |
- AssociatePublicIpAddress: "true" | |
DeviceIndex: "0" | |
GroupSet: | |
- !Ref NATInstanceSG | |
SubnetId: !Ref PublicSubnet | |
UserData: | |
Fn::Base64: | |
!Sub | | |
#!/bin/bash -xe | |
# Redirect the user-data output to the console logs | |
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1 | |
# Apply the latest security patches | |
yum update -y --security | |
yum install -y unzip vim wget firewalld | |
# Trust the RHUI certs | |
cp /etc/pki/rhui/cdn.redhat.com-chain.crt /etc/pki/ca-trust/source/anchors/cdn.redhat.com-chain.crt | |
update-ca-trust extract | |
update-ca-trust | |
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" | |
unzip awscliv2.zip | |
./aws/install | |
# Disable source / destination check. It cannot be disabled from the launch configuration | |
region=${AWS::Region} | |
instanceid=`curl -s http://169.254.169.254/latest/meta-data/instance-id` | |
/usr/local/bin/aws ec2 modify-instance-attribute --no-source-dest-check --instance-id $instanceid --region $region | |
# Install and start Squid | |
yum install -y squid net-tools | |
cp -a /etc/squid /etc/squid_orig | |
# Create a SSL certificate for the SslBump Squid module | |
mkdir /etc/squid/ssl | |
pushd /etc/squid/ssl | |
openssl genrsa -out squid.key 4096 | |
openssl req -new -key squid.key -out squid.csr -subj "/C=US/ST=VA/L=squid/O=squid/CN=squid" | |
openssl x509 -req -days 3650 -in squid.csr -signkey squid.key -out squid.crt | |
cat squid.key squid.crt >> squid.pem | |
echo '.amazonaws.com' > /etc/squid/whitelist.txt | |
echo '.cloudfront.net' >> /etc/squid/whitelist.txt | |
echo '.ce.redhat.com' >> /etc/squid/whitelist.txt | |
cat > /etc/squid/squid.conf << 'EOF' | |
visible_hostname squid | |
cache deny all | |
# Log format and rotation | |
logformat squid %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %ssl::>sni %Sh/%<a %mt | |
logfile_rotate 10 | |
debug_options rotate=10 | |
# Handle HTTP requests | |
http_port 3128 | |
http_port 3129 intercept | |
# Handle HTTPS requests | |
https_port 3130 cert=/etc/squid/ssl/squid.pem ssl-bump intercept | |
acl SSL_port port 443 | |
http_access allow SSL_port | |
acl step1 at_step SslBump1 | |
acl step2 at_step SslBump2 | |
acl step3 at_step SslBump3 | |
ssl_bump peek step1 all | |
# Deny requests to proxy instance metadata | |
acl instance_metadata dst 169.254.169.254 | |
http_access deny instance_metadata | |
# Filter HTTP requests based on the whitelist | |
acl allowed_http_sites dstdomain "/etc/squid/whitelist.txt" | |
http_access allow allowed_http_sites | |
# Filter HTTPS requests based on the whitelist | |
acl allowed_https_sites ssl::server_name "/etc/squid/whitelist.txt" | |
ssl_bump peek step2 allowed_https_sites | |
ssl_bump splice step3 allowed_https_sites | |
ssl_bump terminate step2 all | |
http_access deny all | |
EOF | |
/usr/lib64/squid/security_file_certgen -c -s /var/spool/squid/ssl_db -M 4MB | |
systemctl enable --now squid | |
/usr/sbin/squid -k parse && /usr/sbin/squid -k reconfigure | |
sleep 5 | |
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3129 | |
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 3130 | |
# End Nat Instance | |
############################################################################ | |
S3Bucket: | |
Type: AWS::S3::Bucket | |
HelperIamRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: "2012-10-17" | |
Statement: | |
- Effect: "Allow" | |
Principal: | |
Service: | |
- "ec2.amazonaws.com" | |
Action: | |
- "sts:AssumeRole" | |
Path: "/" | |
Policies: | |
- PolicyName: !Join ["-", ["helper", "policy"]] | |
PolicyDocument: | |
Version: "2012-10-17" | |
Statement: | |
- Effect: "Allow" | |
Action: "ec2:Describe*" | |
Resource: "*" | |
- Effect: "Allow" | |
Action: "ec2:AttachVolume" | |
Resource: "*" | |
- Effect: "Allow" | |
Action: "ec2:DetachVolume" | |
Resource: "*" | |
- Effect: "Allow" | |
Action: "s3:*" | |
Resource: "*" | |
HelperInstanceProfile: | |
Type: "AWS::IAM::InstanceProfile" | |
Properties: | |
Path: "/" | |
Roles: | |
- Ref: "HelperIamRole" | |
HelperInstanceSG: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: Allows SSH connections to the bastion node | |
SecurityGroupIngress: | |
- CidrIp: 0.0.0.0/0 | |
FromPort: 22 | |
ToPort: 22 | |
IpProtocol: tcp | |
Tags: | |
- Key: Name | |
Value: !Sub 'Bastion SG - ${AWS::StackName}' | |
VpcId: !Ref VPC | |
HelperInstanceWaitHandle: | |
Type: AWS::CloudFormation::WaitConditionHandle | |
Properties: {} | |
HelperInstanceWaitCondition: | |
Type: AWS::CloudFormation::WaitCondition | |
Properties: | |
Handle: !Ref HelperInstanceWaitHandle | |
Timeout: 4500 | |
HelperInstance: | |
Type: AWS::EC2::Instance | |
Properties: | |
ImageId: !FindInMap [RHELMap, !Ref "AWS::Region", HVM64] | |
IamInstanceProfile: !Ref HelperInstanceProfile | |
InstanceType: !Ref BastionInstanceType | |
KeyName: !Ref KeyName | |
BlockDeviceMappings: | |
- DeviceName: "/dev/sda1" | |
Ebs: | |
VolumeType: "gp2" | |
DeleteOnTermination: "true" | |
VolumeSize: "150" | |
Tags: | |
- Key: Name | |
Value: !Sub 'Bastion Node - ${AWS::StackName}' | |
NetworkInterfaces: | |
- AssociatePublicIpAddress: "true" | |
DeviceIndex: "0" | |
GroupSet: | |
- !Ref HelperInstanceSG | |
SubnetId: !Ref "PublicSubnet" | |
UserData: | |
Fn::Base64: !Sub | |
- | | |
#!/bin/bash -x | |
yum update -y --security | |
dnf -y install wget vim podman unzip jq | |
cd /tmp | |
region=${AWS::Region} | |
echo '${pull_secret}' > /tmp/pull-secret.json | |
echo '${pull_secret}' > /home/ec2-user/pull-secret.json | |
wget -q https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/${ocp_ver}/openshift-client-linux-amd64-rhel9-${ocp_ver}.tar.gz | |
wget -q https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/${ocp_ver}/openshift-install-rhel9-amd64.tar.gz | |
wget -q https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/${ocp_ver}/oc-mirror.rhel9.tar.gz | |
wget -q https://developers.redhat.com/content-gateway/file/pub/openshift-v4/clients/mirror-registry/1.3.11/mirror-registry.tar.gz | |
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" | |
unzip awscliv2.zip | |
./aws/install | |
podman pull docker.io/library/registry:2 | |
podman save > docker_registry.tar docker.io/library/registry:2 | |
/usr/local/bin/aws s3 cp --quiet openshift-client-linux-amd64-rhel9-${ocp_ver}.tar.gz "s3://${s3_bucket}/" | |
/usr/local/bin/aws s3 cp --quiet openshift-install-rhel9-amd64.tar.gz "s3://${s3_bucket}/" | |
/usr/local/bin/aws s3 cp --quiet oc-mirror.rhel9.tar.gz "s3://${s3_bucket}/" | |
/usr/local/bin/aws s3 cp --quiet docker_registry.tar "s3://${s3_bucket}/" | |
/usr/local/bin/aws s3 cp --quiet mirror-registry.tar.gz "s3://${s3_bucket}/" | |
tar -xzf openshift-client-linux-amd64-rhel9-${ocp_ver}.tar.gz | |
tar -xzf openshift-install-rhel9-amd64.tar.gz | |
tar -xzf oc-mirror.rhel9.tar.gz | |
rm -f README.md | |
sudo mv oc openshift-install-fips kubectl oc-mirror /usr/local/bin | |
sudo chown root.root /usr/local/bin/oc /usr/local/bin/kubectl /usr/local/bin/openshift-install-fips /usr/local/bin/oc-mirror | |
sudo chmod 0755 /usr/local/bin/oc /usr/local/bin/kubectl /usr/local/bin/openshift-install-fips /usr/local/bin/oc-mirror | |
sudo restorecon -v /usr/local/bin/oc /usr/local/bin/kubectl /usr/local/bin/openshift-install-fips /usr/local/bin/oc-mirror | |
sudo ln -sf /usr/local/bin/openshift-install-fips /usr/local/bin/openshift-install | |
# Signal to the registry node that we're done mirroring to S3 | |
curl -X PUT -H 'Content-Type:' --data-binary \ | |
'{"Status" : "SUCCESS","Reason" : "Configuration Complete","UniqueId" : "ID1234","Data" : "Application has completed configuration."}' \ | |
"${signal_url}" | |
- pull_secret: !Ref PullSecretJson | |
ocp_ver: !Ref OpenShiftVersion | |
s3_bucket: !Ref S3Bucket | |
signal_url: !Ref HelperInstanceWaitHandle | |
# End Helper/Bastion Node | |
###########################################################3 | |
RegistryIamRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: "2012-10-17" | |
Statement: | |
- Effect: "Allow" | |
Principal: | |
Service: | |
- "ec2.amazonaws.com" | |
Action: | |
- "sts:AssumeRole" | |
Path: "/" | |
Policies: | |
- PolicyName: !Join ["-", ["helper", "policy"]] | |
PolicyDocument: | |
Version: "2012-10-17" | |
Statement: | |
- Effect: "Allow" | |
Action: "ec2:Describe*" | |
Resource: "*" | |
- Effect: "Allow" | |
Action: "ec2:AttachVolume" | |
Resource: "*" | |
- Effect: "Allow" | |
Action: "ec2:DetachVolume" | |
Resource: "*" | |
- Effect: "Allow" | |
Action: "s3:*" | |
Resource: "*" | |
RegistryInstanceProfile: | |
Type: "AWS::IAM::InstanceProfile" | |
Properties: | |
Path: "/" | |
Roles: | |
- Ref: "RegistryIamRole" | |
RegistryInstanceSG: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: Allows SSH connections to the registry node | |
SecurityGroupIngress: | |
- CidrIp: 0.0.0.0/0 # TODO: VPC Cidr?? | |
FromPort: 22 | |
ToPort: 22 | |
IpProtocol: tcp | |
- CidrIp: 0.0.0.0/0 # TODO: VPC Cidr?? | |
FromPort: 8443 | |
ToPort: 8443 | |
IpProtocol: tcp | |
Tags: | |
- Key: Name | |
Value: !Sub 'Registry SG - ${AWS::StackName}' | |
VpcId: !Ref VPC | |
RegistryInstance: | |
Type: AWS::EC2::Instance | |
DependsOn: HelperInstanceWaitCondition | |
Properties: | |
ImageId: !FindInMap [RHELMap, !Ref "AWS::Region", HVM64] | |
IamInstanceProfile: !Ref RegistryInstanceProfile | |
InstanceType: !Ref RegistryInstanceType | |
KeyName: !Ref KeyName | |
BlockDeviceMappings: | |
- DeviceName: "/dev/sda1" | |
Ebs: | |
VolumeType: "gp2" | |
DeleteOnTermination: "true" | |
VolumeSize: "150" | |
Tags: | |
- Key: Name | |
Value: !Sub 'Registry Node - ${AWS::StackName}' | |
NetworkInterfaces: | |
- AssociatePublicIpAddress: false | |
DeviceIndex: "0" | |
GroupSet: | |
- !Ref RegistryInstanceSG | |
SubnetId: !Ref PrivateSubnet | |
UserData: | |
Fn::Base64: !Sub | |
- | | |
#!/bin/bash -x | |
cd /tmp | |
# Set the HOME env var missing in systemd | |
export HOME="/root" | |
export USER="root" | |
dnf -y install wget vim podman unzip jq | |
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" | |
unzip awscliv2.zip | |
./aws/install | |
region=${AWS::Region} | |
/usr/local/bin/aws s3 cp --quiet "s3://${s3_bucket}/openshift-client-linux-amd64-rhel9-${ocp_ver}.tar.gz" . | |
/usr/local/bin/aws s3 cp --quiet "s3://${s3_bucket}/openshift-install-rhel9-amd64.tar.gz" . | |
/usr/local/bin/aws s3 cp --quiet "s3://${s3_bucket}/oc-mirror.rhel9.tar.gz" . | |
/usr/local/bin/aws s3 cp --quiet "s3://${s3_bucket}/docker_registry.tar" . | |
/usr/local/bin/aws s3 cp --quiet "s3://${s3_bucket}/mirror-registry.tar.gz" . | |
tar -xzf openshift-client-linux-amd64-rhel9-${ocp_ver}.tar.gz | |
tar -xzf openshift-install-rhel9-amd64.tar.gz | |
tar -xzf oc-mirror.rhel9.tar.gz | |
tar -xzf mirror-registry.tar.gz | |
rm -f README.md | |
sudo mv oc openshift-install-fips kubectl oc-mirror /usr/local/bin | |
sudo chown root.root /usr/local/bin/oc /usr/local/bin/kubectl /usr/local/bin/openshift-install-fips /usr/local/bin/oc-mirror | |
sudo chmod 0755 /usr/local/bin/oc /usr/local/bin/kubectl /usr/local/bin/openshift-install-fips /usr/local/bin/oc-mirror | |
sudo restorecon -v /usr/local/bin/oc /usr/local/bin/kubectl /usr/local/bin/openshift-install-fips /usr/local/bin/oc-mirror | |
sudo ln -sf /usr/local/bin/openshift-install-fips /usr/local/bin/openshift-install | |
./mirror-registry install 2>&1 | tee mirror-registry.log # probably should do this as the ec2-user | |
cp /root/quay-install/quay-rootCA/rootCA.pem /etc/pki/ca-trust/source/anchors/quay.pem | |
update-ca-trust | |
update-ca-trust extract | |
#podman load < docker_registry.tar | |
#REGISTRY_DIR="/home/ec2-user/registry" | |
#mkdir -p ${!REGISTRY_DIR}/{auth,certs,data} | |
#export REGISTRY_IP=$(hostname -I | awk '{print $NF}') | |
#openssl req -newkey rsa:4096 -nodes -keyout "${!REGISTRY_DIR}/certs/registry.key" \ | |
# -x509 -days 365 -out "${!REGISTRY_DIR}/certs/registry.crt" \ | |
# -addext "subjectAltName = IP:${!REGISTRY_IP},DNS:${!HOSTNAME}" \ | |
# -subj "/C=US/ST=VA/L=Chantilly/O=RedHat/OU=RedHat/CN=${!HOSTNAME}/" | |
# Generate the registry htpasswd file | |
#htpasswd -bBc ${!REGISTRY_DIR}/auth/htpasswd "dummy" "dummy" | |
#dummy:$2y$05$pUhcEFsOgS3iMO0hvkSFNeuFkzeXcTqVeO/QPNZEjn3FR1V2KeuG2 | |
#Make sure to trust the self signed cert we just made | |
#sudo cp -f ${!REGISTRY_DIR}/certs/registry.crt /etc/pki/ca-trust/source/anchors/ | |
#sudo update-ca-trust | |
#sudo update-ca-trust extract | |
# Configure the firewall | |
#sudo systemctl enable --now firewalld | |
#sudo firewall-cmd --add-port=8443/tcp --zone=internal --permanent | |
#sudo firewall-cmd --add-port=8443/tcp --zone=public --permanent | |
#sudo firewall-cmd --add-service=http --permanent | |
#sudo firewall-cmd --reload | |
# Configure SELinux to allow containers in systemd services | |
#setsebool -P container_manage_cgroup on | |
#podman run --name registry_server -p 8443:8443 \ | |
#-v ${!REGISTRY_DIR}/data:/var/lib/registry:z \ | |
#-v ${!REGISTRY_DIR}/auth:/auth:z \ | |
#-e "REGISTRY_AUTH=htpasswd" \ | |
#-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry" \ | |
#-e "REGISTRY_HTTP_SECRET=ALongRandomSecretForRegistry" \ | |
#-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ | |
#-v ${!REGISTRY_DIR}/certs:/certs:z \ | |
#-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \ | |
#-e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \ | |
#-e REGISTRY_STORAGE=s3 \ | |
#-e REGISTRY_STORAGE_S3_REGION=us-east-2 \ | |
#-e REGISTRY_STORAGE_S3_BUCKET=${s3_bucket} \ | |
#-e REGISTRY_STORAGE_S3_ENCRYPT=false \ | |
#-e REGISTRY_STORAGE_S3_SECURE=true \ | |
#-e REGISTRY_STORAGE_S3_V4AUTH=true \ | |
#-e REGISTRY_STORAGE_S3_CHUNKSIZE=5242880 \ | |
#-e REGISTRY_STORAGE_S3_ROOTDIRECTORY=/image-registry \ | |
#--hostname=${!HOSTNAME} \ | |
#--conmon-pidfile=/tmp/podman-registry-conman.pid \ | |
#--detach \ | |
#docker.io/library/registry:2 | |
- ocp_ver: !Ref OpenShiftVersion | |
s3_bucket: !Ref S3Bucket | |
# End Registry Node | |
###################################################################################################### | |
Outputs: | |
VpcId: | |
Description: ID of the new VPC. | |
Value: !Ref VPC | |
PublicSubnetIds: | |
Description: Subnet IDs of the public subnets. | |
Value: | |
!Join [ | |
",", | |
[!Ref PublicSubnet, !If [DoAz2, !Ref PublicSubnet2, !Ref "AWS::NoValue"], !If [DoAz3, !Ref PublicSubnet3, !Ref "AWS::NoValue"]] | |
] | |
PrivateSubnetIds: | |
Description: Subnet IDs of the private subnets. | |
Value: | |
!Join [ | |
",", | |
[!Ref PrivateSubnet, !If [DoAz2, !Ref PrivateSubnet2, !Ref "AWS::NoValue"], !If [DoAz3, !Ref PrivateSubnet3, !Ref "AWS::NoValue"]] | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment