first commit

This commit is contained in:
Kfir Dayan 2023-09-10 10:14:03 +03:00
parent 5d49ede413
commit 95de21d691
7 changed files with 199 additions and 39 deletions

5
.gitignore vendored
View file

@ -1 +1,4 @@
certificates certificates/
cli-helpers.md
commit-stack.yml
tmp

120
README.md
View file

@ -1,5 +1,117 @@
1. Create a VPC and Two Subnets:
``` shell
aws ec2 create-vpc --cidr-block 10.0.0.0/16
```
``` shell
aws ec2 create-subnet --vpc-id <your-vpc-id> --cidr-block 10.0.1.0/24 --availability-zone <availability-zone-1>
```
``` shell
aws ec2 create-subnet --vpc-id <your-vpc-id> --cidr-block 10.0.2.0/24 --availability-zone <availability-zone-2>
```
Replace <your-vpc-id> with the VPC ID you got in the first command, and replace <availability-zone-1> and <availability-zone-2> with your preferred availability zones.
2. Create a Network ACL (NACL) and Associate it with Subnets:
``` shell
aws ec2 create-network-acl --vpc-id <your-vpc-id>
```
``` shell
aws ec2 create-network-acl-entry --network-acl-id <your-nacl-id> --rule-number 100 --protocol tcp --rule-action allow --cidr-block 0.0.0.0/0 --port-range From=80,To=80
```
``` shell
aws ec2 create-network-acl-association --network-acl-id <your-nacl-id> --subnet-id <subnet-1-id>
```
``` shell
aws ec2 create-network-acl-association --network-acl-id <your-nacl-id> --subnet-id <subnet-2-id>
```
Replace <your-nacl-id>, <subnet-1-id>, and <subnet-2-id> with the appropriate values.
3. Create an ECS Cluster:
``` shell
aws ecs create-cluster --cluster-name <your-cluster-name>
```
4. Create a Docker Container with NGINX:
You will need to create a Dockerfile and build a Docker image with NGINX and your "Hello Commit" page. Once you have the image, you can push it to a container registry like Amazon ECR or Docker Hub.
5. Deploy the NGINX Container to ECS:
Before deploying, make sure you have an ECS Task Definition and Service configured. Then, use the ECS CLI or AWS Console to create the service and deploy the container to one of your subnets.
Task Definition:
``` json
{
"family": "nginx-task",
"containerDefinitions": [
{
"name": "nginx-container",
"image": "<your-ecr-image-uri>",
"memory": 512,
"cpu": 256,
"essential": true,
"portMappings": [
{
"containerPort": 80,
"hostPort": 80
}
]
}
]
}
```
then, register the task definition:
``` shell
aws ecs register-task-definition --cli-input-json file://nginx-task-definition.json
```
Create an ECS Service:
Create an ECS service that uses the task definition you just registered. Replace <your-cluster-name>, <your-subnet-id>, and other placeholders with your specific values:
``` shell
aws ecs create-service --cluster <your-cluster-name> --service-name nginx-service --task-definition nginx-task --desired-count 1 --launch-type EC2 --scheduling-strategy REPLICA --network-configuration "awsvpcConfiguration={subnets=[<your-subnet-id>]}"
```
This command will create an ECS service called nginx-service running one instance of your NGINX container in one of your subnets.
Update Security Groups and Inbound Rules:
Create a New Security Group:
To create a new security group that allows incoming traffic on port 80 (HTTP) and 443 (HTTPS), use the following AWS CLI command:
``` shell
aws ec2 create-security-group --group-name my-ecs-sg --description "ECS Security Group"
```
Authorize Inbound Traffic on Port 80 and 443:
``` shell
aws ec2 authorize-security-group-ingress --group-id <your-security-group-id> --protocol tcp --port 80 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id <your-security-group-id> --protocol tcp --port 443 --cidr 0.0.0.0/0
```
Associate the Security Group with Your ECS Instances:
To associate the newly created security group with your ECS instances, you'll need to update the launch configuration or task definition associated with your ECS cluster. If you're using AWS Fargate, you can specify the security group in the task definition. If you're using EC2 instances for ECS, make sure to specify the security group when launching or updating the instances.
For example, when launching EC2 instances with the create-service command, you can use the --launch-type EC2 option and specify the --security-groups parameter with your security group ID:
``` shell
aws ecs create-service --cluster <your-cluster-name> --service-name nginx-service --task-definition nginx-task --desired-count 1 --launch-type EC2 --network-configuration "awsvpcConfiguration={subnets=[<your-subnet-id>],securityGroups=[<your-security-group-id>]}"
```
6. Create an RDS Instance (MySQL/PostgreSQL):
aws rds create-db-instance --db-instance-identifier my-rds-instance --db-instance-class db.t2.micro --engine mysql --master-username <username> --master-user-password <password> --allocated-storage 20
7. Configure NGINX to Query the RDS Database:
You'll need to modify your NGINX configuration to connect to the RDS instance and execute queries. This will depend on your NGINX configuration and application logic.
8. Expose the Service Over HTTPS with a Self-Signed Certificate:
You'll need to create a self-signed certificate and configure NGINX to serve HTTPS requests. This will depend on your NGINX configuration and application logic.
Self Signed Certificate: Self Signed Certificate:
``` shell
openssl genpkey -algorithm RSA -out private-key.pem - this is the private key openssl genpkey -algorithm RSA -out private-key.pem
openssl req -new -key private-key.pem -x509 -days 365 -out certificate.pem - this is the certificate openssl req -new -key private-key.pem -x509 -days 365 -out certificate.pem
```

View file

@ -1,9 +1,27 @@
# Use the official NGINX image as the base image # Use the official Nginx base image
FROM nginx FROM nginx:latest
# Copy your custom HTML and logo files to the NGINX web root # Create a directory to store your custom Nginx configuration
RUN mkdir -p /etc/nginx/custom
# Install MySQL client library (if needed)
# RUN apt-get update && apt-get install -y default-mysql-client
# Copy your custom HTML and logo files to the Nginx web root
COPY index.html /usr/share/nginx/html/ COPY index.html /usr/share/nginx/html/
COPY logo.png /usr/share/nginx/html/ COPY logo.png /usr/share/nginx/html/
# Expose port 80 for HTTP traffic # Copy Nginx configuration file
EXPOSE 80 COPY nginx.conf /etc/nginx/custom/nginx.conf
# Copy a custom script that will start Nginx and keep it running
COPY start-nginx.sh /usr/local/bin/start-nginx.sh
# Make the script executable
RUN chmod +x /usr/local/bin/start-nginx.sh
# Expose port 80 for incoming HTTP traffic
EXPOSE 80
# Define the command to start Nginx using your custom script
CMD ["/usr/local/bin/start-nginx.sh"]

11
nginx/nginx.conf Normal file
View file

@ -0,0 +1,11 @@
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
# Other server block configurations...
}

4
nginx/start-nginx.sh Normal file
View file

@ -0,0 +1,4 @@
#!/bin/bash
# Start Nginx in the foreground
nginx -g "daemon off;"

View file

@ -0,0 +1,18 @@
{
"family": "nginx-task",
"containerDefinitions": [
{
"name": "nginx-container",
"image": "<your-ecr-image-uri>",
"memory": 512,
"cpu": 256,
"essential": true,
"portMappings": [
{
"containerPort": 80,
"hostPort": 80
}
]
}
]
}

View file

@ -1,22 +1,26 @@
AWSTemplateFormatVersion: "2010-09-09" AWSTemplateFormatVersion: "2010-09-09"
Parameters:
NginxImage:
Type: String
Default: 539634357948.dkr.ecr.eu-central-1.amazonaws.com/commit-nginx:latest
Resources: Resources:
VPC: VPC:
Type: AWS::EC2::VPC # or AWS::RDS::DBSubnetGroup Type: AWS::EC2::VPC
Properties: # or Properties Properties:
CidrBlock: 10.0.0.0/16 # this is the VPC CIDR block (CIDR = Classless Inter-Domain Routing, it means you can use 0.0.0.0/0 for all IPs) CidrBlock: 10.0.0.0/16
EnableDnsSupport: true # Enable DNS hostnames (EnableDnsSupport is true by default) EnableDnsSupport: true
EnableDnsHostnames: true # Enable DNS hostnames (EnableDnsHostnames is true by default) EnableDnsHostnames: true
SubnetA: SubnetA:
Type: AWS::EC2::Subnet # this subnet is for the ECS instances (webserver) Type: AWS::EC2::Subnet
Properties: Properties:
VpcId: !Ref VPC VpcId: !Ref VPC
CidrBlock: 10.0.0.0/24 # this is the subnet CIDR block it means that you can use 10.0.0.0/24 CidrBlock: 10.0.0.0/24
AvailabilityZone: eu-central-1a AvailabilityZone: eu-central-1a
SubnetB: SubnetB:
Type: AWS::EC2::Subnet # this subnet is for the RDS Type: AWS::EC2::Subnet
Properties: Properties:
VpcId: !Ref VPC VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24 CidrBlock: 10.0.1.0/24
@ -37,7 +41,7 @@ Resources:
PortRange: PortRange:
From: 443 From: 443
To: 443 To: 443
Egress: false # Egress means outbound Egress: false
CidrBlock: 0.0.0.0/0 CidrBlock: 0.0.0.0/0
InboundRuleHttp: InboundRuleHttp:
@ -50,7 +54,7 @@ Resources:
PortRange: PortRange:
From: 80 From: 80
To: 80 To: 80
Egress: false # Egress means outbound Egress: false
CidrBlock: 0.0.0.0/0 CidrBlock: 0.0.0.0/0
OutboundRuleHttps: OutboundRuleHttps:
@ -84,14 +88,14 @@ Resources:
Properties: Properties:
AllocatedStorage: 20 AllocatedStorage: 20
DBInstanceClass: db.t2.micro DBInstanceClass: db.t2.micro
Engine: mysql # or postgres Engine: mysql
MasterUsername: root_user MasterUsername: root_user
MasterUserPassword: root_password MasterUserPassword: root_password
DBName: root_db DBName: root_db
MultiAZ: false MultiAZ: false
ECSCluster: ECSCluster:
Type: AWS::ECS::Cluster # this ECSCluster is to run the ECS tasks Type: AWS::ECS::Cluster
ECSTaskDefinition: ECSTaskDefinition:
Type: AWS::ECS::TaskDefinition Type: AWS::ECS::TaskDefinition
@ -105,9 +109,9 @@ Resources:
Memory: 0.5GB Memory: 0.5GB
Family: !Ref ECSCluster Family: !Ref ECSCluster
ContainerDefinitions: ContainerDefinitions:
- Name: commit-nginx - Name: commit-stack # Updated application name to "commit-stack"
Image: 539634357948.dkr.ecr.eu-central-1.amazonaws.com/commit-nginx:latest Image: !Ref NginxImage
Memory: 512 # Specify memory here (in MiB) Memory: 512
PortMappings: PortMappings:
- ContainerPort: 80 - ContainerPort: 80
- ContainerPort: 443 - ContainerPort: 443
@ -117,9 +121,9 @@ Resources:
Properties: Properties:
Cluster: !Ref ECSCluster Cluster: !Ref ECSCluster
LoadBalancers: LoadBalancers:
- ContainerName: commit-nginx - ContainerName: commit-stack # Updated container name
ContainerPort: 80 ContainerPort: 80
LoadBalancerName: !GetAtt LoadBalancer.Name LoadBalancerName: !Ref LoadBalancer
TaskDefinition: !Ref ECSTaskDefinition TaskDefinition: !Ref ECSTaskDefinition
DesiredCount: 1 DesiredCount: 1
LaunchType: EC2 LaunchType: EC2
@ -128,19 +132,14 @@ Resources:
Subnets: Subnets:
- !Ref SubnetA - !Ref SubnetA
- !Ref SubnetB - !Ref SubnetB
DependsOn:
- "LoadBalancer"
LoadBalancer: LoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties: Properties:
Name: "Commit-elb" Name: "Commit-elb"
LoadBalancerAttributes: LoadBalancerAttributes:
# this is the default, but is specified here in case it needs to be changed
- Key: idle_timeout.timeout_seconds - Key: idle_timeout.timeout_seconds
Value: 60 Value: 60
# "internal" is also an option
Scheme: internet-facing Scheme: internet-facing
Subnets: Subnets:
- !Ref SubnetA - !Ref SubnetA
@ -183,9 +182,7 @@ Resources:
InternetGatewayId: !Ref MyInternetGateway InternetGatewayId: !Ref MyInternetGateway
VpcId: !Ref VPC VpcId: !Ref VPC
ListenerHTTP:
ListenerHTTPS:
Type: AWS::ElasticLoadBalancingV2::Listener Type: AWS::ElasticLoadBalancingV2::Listener
Properties: Properties:
DefaultActions: DefaultActions:
@ -194,14 +191,11 @@ Resources:
LoadBalancerArn: !Ref LoadBalancer LoadBalancerArn: !Ref LoadBalancer
Port: 80 Port: 80
Protocol: HTTP Protocol: HTTP
# Certificates:
# - CertificateArn: "arn:aws:acm:eu-central-1:539634357948:certificate/584cfb24-bc7a-431b-9150-16d47bdb8ea9"
TargetGroup: TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties: Properties:
HealthCheckIntervalSeconds: 10 HealthCheckIntervalSeconds: 10
# will look for a 200 status code by default unless specified otherwise
HealthCheckPath: "/" HealthCheckPath: "/"
HealthCheckTimeoutSeconds: 5 HealthCheckTimeoutSeconds: 5
UnhealthyThresholdCount: 2 UnhealthyThresholdCount: 2
@ -211,6 +205,6 @@ Resources:
Protocol: HTTP Protocol: HTTP
TargetGroupAttributes: TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds - Key: deregistration_delay.timeout_seconds
Value: 60 # default is 300 Value: 60
TargetType: ip TargetType: ip
VpcId: !Ref VPC VpcId: !Ref VPC