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:
openssl genpkey -algorithm RSA -out private-key.pem - this is the private key
openssl req -new -key private-key.pem -x509 -days 365 -out certificate.pem - this is the certificate
``` shell
openssl genpkey -algorithm RSA -out private-key.pem
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
FROM nginx
# Use the official Nginx base image
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 logo.png /usr/share/nginx/html/
# Expose port 80 for HTTP traffic
EXPOSE 80
# Copy Nginx configuration file
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"
Parameters:
NginxImage:
Type: String
Default: 539634357948.dkr.ecr.eu-central-1.amazonaws.com/commit-nginx:latest
Resources:
VPC:
Type: AWS::EC2::VPC # or AWS::RDS::DBSubnetGroup
Properties: # or 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)
EnableDnsSupport: true # Enable DNS hostnames (EnableDnsSupport is true by default)
EnableDnsHostnames: true # Enable DNS hostnames (EnableDnsHostnames is true by default)
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
SubnetA:
Type: AWS::EC2::Subnet # this subnet is for the ECS instances (webserver)
Type: AWS::EC2::Subnet
Properties:
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
SubnetB:
Type: AWS::EC2::Subnet # this subnet is for the RDS
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
@ -37,7 +41,7 @@ Resources:
PortRange:
From: 443
To: 443
Egress: false # Egress means outbound
Egress: false
CidrBlock: 0.0.0.0/0
InboundRuleHttp:
@ -50,7 +54,7 @@ Resources:
PortRange:
From: 80
To: 80
Egress: false # Egress means outbound
Egress: false
CidrBlock: 0.0.0.0/0
OutboundRuleHttps:
@ -84,14 +88,14 @@ Resources:
Properties:
AllocatedStorage: 20
DBInstanceClass: db.t2.micro
Engine: mysql # or postgres
Engine: mysql
MasterUsername: root_user
MasterUserPassword: root_password
DBName: root_db
MultiAZ: false
ECSCluster:
Type: AWS::ECS::Cluster # this ECSCluster is to run the ECS tasks
Type: AWS::ECS::Cluster
ECSTaskDefinition:
Type: AWS::ECS::TaskDefinition
@ -105,9 +109,9 @@ Resources:
Memory: 0.5GB
Family: !Ref ECSCluster
ContainerDefinitions:
- Name: commit-nginx
Image: 539634357948.dkr.ecr.eu-central-1.amazonaws.com/commit-nginx:latest
Memory: 512 # Specify memory here (in MiB)
- Name: commit-stack # Updated application name to "commit-stack"
Image: !Ref NginxImage
Memory: 512
PortMappings:
- ContainerPort: 80
- ContainerPort: 443
@ -117,9 +121,9 @@ Resources:
Properties:
Cluster: !Ref ECSCluster
LoadBalancers:
- ContainerName: commit-nginx
- ContainerName: commit-stack # Updated container name
ContainerPort: 80
LoadBalancerName: !GetAtt LoadBalancer.Name
LoadBalancerName: !Ref LoadBalancer
TaskDefinition: !Ref ECSTaskDefinition
DesiredCount: 1
LaunchType: EC2
@ -128,19 +132,14 @@ Resources:
Subnets:
- !Ref SubnetA
- !Ref SubnetB
DependsOn:
- "LoadBalancer"
LoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: "Commit-elb"
LoadBalancerAttributes:
# this is the default, but is specified here in case it needs to be changed
- Key: idle_timeout.timeout_seconds
Value: 60
# "internal" is also an option
Scheme: internet-facing
Subnets:
- !Ref SubnetA
@ -183,9 +182,7 @@ Resources:
InternetGatewayId: !Ref MyInternetGateway
VpcId: !Ref VPC
ListenerHTTPS:
ListenerHTTP:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
@ -194,14 +191,11 @@ Resources:
LoadBalancerArn: !Ref LoadBalancer
Port: 80
Protocol: HTTP
# Certificates:
# - CertificateArn: "arn:aws:acm:eu-central-1:539634357948:certificate/584cfb24-bc7a-431b-9150-16d47bdb8ea9"
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 10
# will look for a 200 status code by default unless specified otherwise
HealthCheckPath: "/"
HealthCheckTimeoutSeconds: 5
UnhealthyThresholdCount: 2
@ -211,6 +205,6 @@ Resources:
Protocol: HTTP
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 60 # default is 300
Value: 60
TargetType: ip
VpcId: !Ref VPC