first commit
This commit is contained in:
parent
5d49ede413
commit
95de21d691
7 changed files with 199 additions and 39 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1 +1,4 @@
|
||||||
certificates
|
certificates/
|
||||||
|
cli-helpers.md
|
||||||
|
commit-stack.yml
|
||||||
|
tmp
|
120
README.md
120
README.md
|
@ -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
|
||||||
|
```
|
|
@ -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
11
nginx/nginx.conf
Normal 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
4
nginx/start-nginx.sh
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Start Nginx in the foreground
|
||||||
|
nginx -g "daemon off;"
|
18
service/nginx-task-definition.json
Normal file
18
service/nginx-task-definition.json
Normal 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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue