Last time, I built the basic configuration (ec2 + rds environment) for running web applications on pulumi on AWS previous article.
This time, we will build the ALB + ec2 dynamic website configuration with pulumi. In addition, WordPress (docker container) is operated in the AWS environment built with pulumi.
This is the pulumi code created this time.
__main__.py
import pulumi
import pulumi_aws as aws
#Creating a VPC
vpc = aws.ec2.Vpc(
"pulumi-vpc",
cidr_block="10.0.0.0/16",
tags={
"Name": "pulumi-vpc",
})
#Creating a Subnet
public_subnet_a = aws.ec2.Subnet(
"pulumi-public-subnet-a",
cidr_block="10.0.1.0/24",
availability_zone="ap-northeast-1a",
tags={
"Name": "pulumi-public-subnet-a",
},
vpc_id=vpc.id)
public_subnet_c = aws.ec2.Subnet(
"pulumi-public-subnet-c",
cidr_block="10.0.2.0/24",
availability_zone="ap-northeast-1c",
tags={
"Name": "pulumi-public-subnet-c",
},
vpc_id=vpc.id)
private_subnet_a = aws.ec2.Subnet(
"pulumi-private-subnet-a",
cidr_block="10.0.3.0/24",
availability_zone="ap-northeast-1a",
tags={
"Name": "pulumi-private-subnet-a",
},
vpc_id=vpc.id)
private_subnet_c = aws.ec2.Subnet(
"pulumi-private-subnet-c",
cidr_block="10.0.4.0/24",
availability_zone="ap-northeast-1c",
tags={
"Name": "pulumi-private-subnet-c",
},
vpc_id=vpc.id)
#Creating an Internet Gateway
igw = aws.ec2.InternetGateway(
"pulumi-igw",
tags={
"Name": "pulumi-igw",
},
vpc_id=vpc.id)
#Creating an EIP
ngw_eip_a = aws.ec2.Eip("pulumi-ngw-eip-a")
ngw_eip_c = aws.ec2.Eip("pulumi-ngw-eip-c")
#Creating Nat Gateway
ngw_a = aws.ec2.NatGateway(
"pulumi-ngw-a",
allocation_id=ngw_eip_a.id,
subnet_id=public_subnet_a.id)
#Creating Nat Gateway
ngw_c = aws.ec2.NatGateway(
"pulumi-ngw-c",
allocation_id=ngw_eip_c.id,
subnet_id=public_subnet_c.id)
#Creating a RouteTable
public_route_table_a = aws.ec2.RouteTable(
"pulumi-public-route-table-a",
routes=[
{
"cidr_block": "0.0.0.0/0",
"gateway_id": igw.id,
},
],
tags={
"Name": "pulumi-public-route-table-a",
},
vpc_id=vpc.id)
public_route_table_c = aws.ec2.RouteTable(
"pulumi-public-route-table-c",
routes=[
{
"cidr_block": "0.0.0.0/0",
"gateway_id": igw.id,
},
],
tags={
"Name": "pulumi-public-route-table-c",
},
vpc_id=vpc.id)
private_route_table_a = aws.ec2.RouteTable(
"pulumi-private-route-table-a",
routes=[
{
"cidr_block": "0.0.0.0/0",
"nat_gateway_id": ngw_a.id,
},
],
tags={
"Name": "pulumi-private-route-table-a",
},
vpc_id=vpc.id)
private_route_table_c = aws.ec2.RouteTable(
"pulumi-private-route-table-c",
routes=[
{
"cidr_block": "0.0.0.0/0",
"nat_gateway_id": ngw_c.id,
},
],
tags={
"Name": "pulumi-private-route-table-c",
},
vpc_id=vpc.id)
#Creating a RouteTableAssociation
route_table_association_public_a = aws.ec2.RouteTableAssociation(
"pulumi-route-table-association-public-a",
subnet_id=public_subnet_a.id,
route_table_id=public_route_table_a.id)
route_table_association_public_c = aws.ec2.RouteTableAssociation(
"pulumi-route-table-association-public-c",
subnet_id=public_subnet_c.id,
route_table_id=public_route_table_c.id)
route_table_association_private_a = aws.ec2.RouteTableAssociation(
"pulumi-route-table-association-private-a",
subnet_id=private_subnet_a.id,
route_table_id=private_route_table_a.id)
route_table_association_private_c = aws.ec2.RouteTableAssociation(
"pulumi-route-table-association-private-c",
subnet_id=private_subnet_c.id,
route_table_id=private_route_table_c.id)
#Creating a Security Group
alb_sg = aws.ec2.SecurityGroup(
"pulumi-alb-sg",
ingress=[
{
"from_port": 80,
"protocol": "TCP",
"to_port": 80,
"cidr_blocks": ["0.0.0.0/0"]
},
],
egress=[
{
"from_port": 0,
"protocol": "TCP",
"to_port": 65535,
"cidr_blocks": ["0.0.0.0/0"]
},
],
tags={
"Name": "pulumi-alb-sg",
},
vpc_id=vpc.id)
ec2_sg = aws.ec2.SecurityGroup(
"pulumi-ec2-sg",
ingress=[
{
"from_port": 80,
"protocol": "TCP",
"to_port": 80,
"security_groups": [alb_sg.id]
},
],
egress=[
{
"from_port": 0,
"protocol": "TCP",
"to_port": 65535,
"cidr_blocks": ["0.0.0.0/0"]
},
],
tags={
"Name": "pulumi-ec2-sg",
},
vpc_id=vpc.id)
rds_sg = aws.ec2.SecurityGroup(
"pulumi-rds-sg",
ingress=[
{
"from_port": 3306,
"protocol": "TCP",
"to_port": 3306,
"security_groups": [ec2_sg.id]
},
],
egress=[
{
"from_port": 0,
"protocol": "TCP",
"to_port": 65535,
"cidr_blocks": ["0.0.0.0/0"]
},
],
tags={
"Name": "pulumi-rds-sg",
},
vpc_id=vpc.id)
#Creating a Key Pair
key_pair = aws.ec2.KeyPair(
"pulumi-keypair",
public_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 [email protected]",
tags={
"Name": "pulumi-keypair",
})
#Creating a TargetGroup
target_group = aws.alb.TargetGroup(
"pulumi-target-group",
health_check={
"healthyThreshold": 5,
"interval": 30,
"matcher": "200,302",
"path": "/",
"protocol": "HTTP",
"timeout": 5,
"unhealthyThreshold": 2
},
name="pulumi-target-group",
port=80,
protocol="HTTP",
tags={
"Name": "pulumi-target-group",
},
target_type="instance",
vpc_id=vpc.id)
#Reading user data
file = open("./user-data")
user_data = file.read()
#Creating a Launch Configuration
launch_conf = aws.ec2.LaunchConfiguration(
"pulumi-launch-conf",
image_id="ami-0ee1410f0644c1cac",
instance_type="t2.micro",
associate_public_ip_address=True,
key_name=key_pair.key_name,
security_groups=[ec2_sg.id],
user_data=user_data)
file.close()
#Creating an Auto Scaling Group
autoscaling_group = aws.autoscaling.Group(
"pulumi-autoscaling-group",
availability_zones=["ap-northeast-1a", "ap-northeast-1c"],
health_check_type="ELB",
desired_capacity=1,
launch_configuration=launch_conf.name,
max_size=1,
min_size=1,
target_group_arns=[target_group.arn],
vpc_zone_identifiers=[
private_subnet_a.id,
private_subnet_c.id
])
#Creating a Load Balancer
alb = aws.alb.LoadBalancer(
"pulumi-alb",
load_balancer_type="application",
name="pulumi-alb",
security_groups=[alb_sg.id],
subnets=[
public_subnet_a.id,
public_subnet_c.id
],
tags={
"Name": "pulumi-alb",
})
#Creating a Listener
alb_listener = aws.alb.Listener(
"pulumi-alb-listener",
default_actions=[{
"target_group_arn": target_group.arn,
"type": "forward",
}],
load_balancer_arn=alb.arn,
port="80",
protocol="HTTP")
#Creating an RDS Subnet Group
rds_subnet = aws.rds.SubnetGroup(
"pulumi-rds-subnet",
subnet_ids=[
private_subnet_a.id,
private_subnet_c.id,
],
tags={
"Name": "pulumi-rds-subnet",
})
#Create an RDS instance
rds = aws.rds.Instance(
"pulumi-rds",
allocated_storage=20,
db_subnet_group_name=rds_subnet.name,
engine="mysql",
engine_version="5.7",
identifier="pulumi-rds",
instance_class="db.t2.micro",
name="pulumi",
parameter_group_name="default.mysql5.7",
password="password",
skip_final_snapshot=True,
storage_type="gp2",
tags={
"Name": "pulumi-rds",
},
username="admin",
vpc_security_group_ids=[rds_sg.id])
user-data
#!/bin/bash
yum install docker -y
service docker start
docker pull wordpress
docker run -p 80:80 -d wordpress
This time, launch EC2, which hosts the application, with a private subnet. Created NAT Gateway and Route Table for it so that EC2 can get out to the Internet
#Creating an EIP to be linked to NAT Gateway
ngw_eip_a = aws.ec2.Eip("pulumi-ngw-eip-a")
ngw_eip_c = aws.ec2.Eip("pulumi-ngw-eip-c")
#Creating Nat Gateway
ngw_a = aws.ec2.NatGateway(
"pulumi-ngw-a",
allocation_id=ngw_eip_a.id,
subnet_id=public_subnet_a.id)
#Creating Nat Gateway
ngw_c = aws.ec2.NatGateway(
"pulumi-ngw-c",
allocation_id=ngw_eip_c.id,
subnet_id=public_subnet_c.id)
#Creating a RouteTable for a private subnet
#Adding a route for NAT Gateway
private_route_table_a = aws.ec2.RouteTable(
"pulumi-private-route-table-a",
routes=[
{
"cidr_block": "0.0.0.0/0",
"nat_gateway_id": ngw_a.id,
},
],
tags={
"Name": "pulumi-private-route-table-a",
},
vpc_id=vpc.id)
private_route_table_c = aws.ec2.RouteTable(
"pulumi-private-route-table-c",
routes=[
{
"cidr_block": "0.0.0.0/0",
"nat_gateway_id": ngw_c.id,
},
],
tags={
"Name": "pulumi-private-route-table-c",
},
vpc_id=vpc.id)
#Linking RouteTable and subnet
route_table_association_private_a = aws.ec2.RouteTableAssociation(
"pulumi-route-table-association-private-a",
subnet_id=private_subnet_a.id,
route_table_id=private_route_table_a.id)
route_table_association_private_c = aws.ec2.RouteTableAssociation(
"pulumi-route-table-association-private-c",
subnet_id=private_subnet_c.id,
route_table_id=private_route_table_c.id)
LaunchConfiguration、AutoScalingGroup、TargetGroup Create Launch Configuration and Auto Scaling Group Also, create a TargetGroup to link ALB and AutoScalingGroup.
#Creating a TargetGroup
target_group = aws.alb.TargetGroup(
"pulumi-target-group",
health_check={
"healthyThreshold": 5,
"interval": 30,
"matcher": "200,302",
"path": "/",
"protocol": "HTTP",
"timeout": 5,
"unhealthyThreshold": 2
},
name="pulumi-target-group",
port=80,
protocol="HTTP",
tags={
"Name": "pulumi-target-group",
},
target_type="instance",
vpc_id=vpc.id)
#Reading user data
file = open("./user-data")
user_data = file.read()
#Creating a Launch Configuration
launch_conf = aws.ec2.LaunchConfiguration(
"pulumi-launch-conf",
image_id="ami-0ee1410f0644c1cac",
instance_type="t2.micro",
associate_public_ip_address=True,
key_name=key_pair.key_name,
security_groups=[ec2_sg.id],
user_data=user_data)
file.close()
#Creating an Auto Scaling Group
autoscaling_group = aws.autoscaling.Group(
"pulumi-autoscaling-group",
availability_zones=["ap-northeast-1a", "ap-northeast-1c"],
health_check_type="ELB",
desired_capacity=1,
launch_configuration=launch_conf.name,
max_size=1,
min_size=1,
target_group_arns=[target_group.arn],
vpc_zone_identifiers=[
private_subnet_a.id,
private_subnet_c.id
])
About the setting of health_check
of TargetGroup
Since it is redirected when accessing /
of WordPress, the status code (302) of redirect is also added to the setting value of matcher
.
About user_data of LaunchConfiguration, it is read from another file The contents of user_data will be described later.
ALB Create ALB and Listener.
#Creating a Load Balancer
alb = aws.alb.LoadBalancer(
"pulumi-alb",
load_balancer_type="application",
name="pulumi-alb",
security_groups=[alb_sg.id],
subnets=[
public_subnet_a.id,
public_subnet_c.id
],
tags={
"Name": "pulumi-alb",
})
#Create Listener (HTTP)
alb_listener = aws.alb.Listener(
"pulumi-alb-listener",
default_actions=[{
"target_group_arn": target_group.arn,
"type": "forward",
}],
load_balancer_arn=alb.arn,
port="80",
protocol="HTTP")
This time, I created a Listener with HTTP, but when creating an HTTPS Listener, it is also necessary to set the certificate etc. as follows.
#Create Listener (HTTPS)
alb_listener = aws.alb.Listener(
"pulumi-alb-listener",
certificate_arn="arn:aws:iam::187416307283:server-certificate/test_cert_rab3wuqwgja25ct3n4jdj2tzu4",
default_actions=[{
"target_group_arn": target_group.arn,
"type": "forward",
}],
load_balancer_arn=alb.arn,
port="443",
protocol="HTTPS",
ssl_policy="ELBSecurityPolicy-2016-08")
This time, start the WordPress image registered in Docker hub Install and start docker and start WordPress container with user data
user-data
#!/bin/bash
#install docker
yum install docker -y
#Start docker daemon
service docker start
#Pull WordPress image
docker pull wordpress
#Launch a WordPress container
docker run -p 80:80 -d wordpress
This time, I created a typical AWS configuration for running a dynamic website with pulumi and started the WordPress docker container.
The AWS resources created in the previous article are not explained in detail this time, so please refer to Previous article if you like.
Actually access
Language setting
Database information settings Here, enter the RDS settings you created earlier.
User information settings
Screen after WordPress login
Recommended Posts