diff options
author | clarkzjw <[email protected]> | 2023-01-01 21:08:22 -0800 |
---|---|---|
committer | clarkzjw <[email protected]> | 2023-01-01 21:08:22 -0800 |
commit | e13d4b448efd7174b1b4c8723cbc8be845470c60 (patch) | |
tree | c797ae22f1b2261b40c084e22c1e52dab39a6f2e | |
parent | e330106e9e6524fc76c407aa608a60ccef83bbe4 (diff) | |
download | jinwei.me-photo.jinwei.me.tar.gz |
stashphoto.jinwei.me
23 files changed, 479 insertions, 59 deletions
diff --git a/photo.jinwei.me/config/ansible.cfg b/photo.jinwei.me/config/ansible.cfg new file mode 100644 index 0000000..9345045 --- /dev/null +++ b/photo.jinwei.me/config/ansible.cfg | |||
@@ -0,0 +1,14 @@ | |||
1 | [defaults] | ||
2 | host_key_checking = False | ||
3 | transport = ssh | ||
4 | remote_user = admin | ||
5 | roles_path = roles | ||
6 | inventory = inventory | ||
7 | force_color = True | ||
8 | interpreter_python = auto_silent | ||
9 | |||
10 | [connection] | ||
11 | pipelining = True | ||
12 | |||
13 | [privilege_escalation] | ||
14 | become = True | ||
diff --git a/photo.jinwei.me/config/inventory/aws_ec2.yaml b/photo.jinwei.me/config/inventory/aws_ec2.yaml new file mode 100644 index 0000000..c35e172 --- /dev/null +++ b/photo.jinwei.me/config/inventory/aws_ec2.yaml | |||
@@ -0,0 +1,7 @@ | |||
1 | plugin: aws_ec2 | ||
2 | regions: | ||
3 | - eu-central-1 | ||
4 | hostnames: | ||
5 | - tag:Name | ||
6 | compose: | ||
7 | ansible_host: public_ip_address | ||
diff --git a/photo.jinwei.me/config/requirements.yaml b/photo.jinwei.me/config/requirements.yaml new file mode 100644 index 0000000..5229cc7 --- /dev/null +++ b/photo.jinwei.me/config/requirements.yaml | |||
@@ -0,0 +1,10 @@ | |||
1 | --- | ||
2 | collections: | ||
3 | - name: amazon.aws | ||
4 | version: 3.2.0 | ||
5 | - name: community.general | ||
6 | version: 4.7.0 | ||
7 | - name: ansible.posix | ||
8 | version: 1.3.0 | ||
9 | - name: community.docker | ||
10 | version: 3.2.1 | ||
diff --git a/photo.jinwei.me/config/role.yaml b/photo.jinwei.me/config/role.yaml new file mode 100644 index 0000000..ab3fca5 --- /dev/null +++ b/photo.jinwei.me/config/role.yaml | |||
@@ -0,0 +1,3 @@ | |||
1 | - hosts: "{{ target }}" | ||
2 | roles: | ||
3 | - role: "{{ role }}" | ||
diff --git a/photo.jinwei.me/config/roles/debian_init/defaults/main.yaml b/photo.jinwei.me/config/roles/debian_init/defaults/main.yaml new file mode 100644 index 0000000..685f0b6 --- /dev/null +++ b/photo.jinwei.me/config/roles/debian_init/defaults/main.yaml | |||
@@ -0,0 +1 @@ | |||
user_home: /home/clarkzjw | |||
diff --git a/photo.jinwei.me/config/roles/debian_init/tasks/main.yaml b/photo.jinwei.me/config/roles/debian_init/tasks/main.yaml new file mode 100644 index 0000000..19b0ed8 --- /dev/null +++ b/photo.jinwei.me/config/roles/debian_init/tasks/main.yaml | |||
@@ -0,0 +1,72 @@ | |||
1 | - name: Disable unattended-upgrades | ||
2 | ansible.builtin.systemd: | ||
3 | name: unattended-upgrades | ||
4 | state: stopped | ||
5 | enabled: false | ||
6 | |||
7 | - name: install packages | ||
8 | apt: | ||
9 | update_cache: true | ||
10 | name: | ||
11 | - apt-transport-https | ||
12 | - build-essential | ||
13 | - ca-certificates | ||
14 | - mariadb-client | ||
15 | - lsb-release | ||
16 | - python3 | ||
17 | - python3-dev | ||
18 | - python3-pip | ||
19 | - unzip | ||
20 | - gnupg | ||
21 | - htop | ||
22 | - curl | ||
23 | - tree | ||
24 | - zip | ||
25 | - vim | ||
26 | - zsh | ||
27 | - git | ||
28 | |||
29 | - name: add user | ||
30 | user: | ||
31 | name: clarkzjw | ||
32 | shell: /usr/bin/zsh | ||
33 | home: "{{ user_home }}" | ||
34 | system: true | ||
35 | |||
36 | - name: Add Docker GPG apt Key | ||
37 | apt_key: | ||
38 | url: https://download.docker.com/linux/debian/gpg | ||
39 | keyring: /etc/apt/trusted.gpg.d/docker.gpg | ||
40 | state: present | ||
41 | |||
42 | - name: Add Docker Repository | ||
43 | apt_repository: | ||
44 | repo: deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/docker.gpg] https://download.docker.com/linux/debian {{ ansible_distribution_release | lower }} stable | ||
45 | state: present | ||
46 | |||
47 | - name: Update apt and install docker-ce | ||
48 | apt: | ||
49 | name: | ||
50 | - docker-ce | ||
51 | - docker-ce-cli | ||
52 | - containerd.io | ||
53 | - docker-compose-plugin | ||
54 | state: latest | ||
55 | update_cache: true | ||
56 | |||
57 | - name: Install Docker Module for Python | ||
58 | pip: | ||
59 | name: | ||
60 | - docker | ||
61 | - docker-compose | ||
62 | |||
63 | - name: enable docker service | ||
64 | systemd: | ||
65 | name: docker | ||
66 | enabled: true | ||
67 | daemon_reload: true | ||
68 | |||
69 | - name: Clean unneeded packages | ||
70 | ansible.builtin.apt: | ||
71 | autoremove: true | ||
72 | purge: true | ||
diff --git a/photo.jinwei.me/config/roles/wordpress/Dockerfile b/photo.jinwei.me/config/roles/wordpress/Dockerfile new file mode 100644 index 0000000..34704c0 --- /dev/null +++ b/photo.jinwei.me/config/roles/wordpress/Dockerfile | |||
@@ -0,0 +1,5 @@ | |||
1 | FROM wordpress:apache | ||
2 | |||
3 | RUN apt-get update -y && apt-get install -y libgmp-dev && docker-php-ext-install gmp | ||
4 | |||
5 | ADD uploads.ini /usr/local/etc/php/conf.d/uploads.ini | ||
diff --git a/photo.jinwei.me/config/roles/wordpress/build.sh b/photo.jinwei.me/config/roles/wordpress/build.sh new file mode 100755 index 0000000..55d7c0e --- /dev/null +++ b/photo.jinwei.me/config/roles/wordpress/build.sh | |||
@@ -0,0 +1,5 @@ | |||
1 | docker_repo=docker.io/clarkzjw | ||
2 | docker_image=wordpress | ||
3 | docker_image_tag=$(date -u +%Y%m%d) | ||
4 | sudo docker build -t $docker_repo/$docker_image:"$docker_image_tag" . | ||
5 | sudo docker push $docker_repo/$docker_image:"$docker_image_tag" | ||
diff --git a/photo.jinwei.me/config/roles/wordpress/defaults/main.yaml b/photo.jinwei.me/config/roles/wordpress/defaults/main.yaml new file mode 100644 index 0000000..250e0a5 --- /dev/null +++ b/photo.jinwei.me/config/roles/wordpress/defaults/main.yaml | |||
@@ -0,0 +1,4 @@ | |||
1 | wordpress_image: clarkzjw/wordpress | ||
2 | wordpress_image_tag: 20221211 | ||
3 | wordpress_port: 30080 | ||
4 | wordpress_home: /opt/wordpress | ||
diff --git a/photo.jinwei.me/config/roles/wordpress/tasks/main.yaml b/photo.jinwei.me/config/roles/wordpress/tasks/main.yaml new file mode 100644 index 0000000..3835145 --- /dev/null +++ b/photo.jinwei.me/config/roles/wordpress/tasks/main.yaml | |||
@@ -0,0 +1,16 @@ | |||
1 | - name: Pull wordpress Docker image | ||
2 | community.docker.docker_image: | ||
3 | name: "{{ wordpress_image }}:{{ wordpress_image_tag }}" | ||
4 | source: pull | ||
5 | |||
6 | - name: render config file | ||
7 | template: | ||
8 | src: docker-compose.yaml.j2 | ||
9 | dest: "{{ wordpress_home }}/docker-compose.yaml" | ||
10 | mode: 0644 | ||
11 | |||
12 | - name: Start wordpress container using docker-compose | ||
13 | community.docker.docker_compose: | ||
14 | project_name: wordpress | ||
15 | project_src: "{{ wordpress_home }}" | ||
16 | register: output | ||
diff --git a/photo.jinwei.me/config/roles/wordpress/templates/docker-compose.yaml.j2 b/photo.jinwei.me/config/roles/wordpress/templates/docker-compose.yaml.j2 new file mode 100644 index 0000000..447b80b --- /dev/null +++ b/photo.jinwei.me/config/roles/wordpress/templates/docker-compose.yaml.j2 | |||
@@ -0,0 +1,22 @@ | |||
1 | version: '3' | ||
2 | services: | ||
3 | cloudflared: | ||
4 | image: cloudflare/cloudflared | ||
5 | container_name: cloudflare-tunnel | ||
6 | network_mode: host | ||
7 | restart: always | ||
8 | command: tunnel run | ||
9 | environment: | ||
10 | - TUNNEL_TOKEN={{ lookup('aws_ssm', '/jinwei-me/cloudflare/tunnel_token') }} | ||
11 | wordpress: | ||
12 | image: "{{ wordpress_image }}:{{ wordpress_image_tag }}" | ||
13 | volumes: | ||
14 | - "{{ wordpress_home }}/wp-content:/var/www/html/wp-content" | ||
15 | restart: always | ||
16 | ports: | ||
17 | - 30081:80 | ||
18 | environment: | ||
19 | - WORDPRESS_DB_HOST={{ lookup('aws_ssm', '/jinwei-me/mysql/host') }}:{{ lookup('aws_ssm', '/jinwei-me/mysql/port') }} | ||
20 | - WORDPRESS_DB_USER={{ lookup('aws_ssm', '/jinwei-me/mysql/username') }} | ||
21 | - WORDPRESS_DB_PASSWORD={{ lookup('aws_ssm', '/jinwei-me/mysql/password') }} | ||
22 | - WORDPRESS_DB_NAME={{ lookup('aws_ssm', '/jinwei-me/mysql/name') }} | ||
diff --git a/photo.jinwei.me/config/roles/wordpress/uploads.ini b/photo.jinwei.me/config/roles/wordpress/uploads.ini new file mode 100644 index 0000000..cd6e86c --- /dev/null +++ b/photo.jinwei.me/config/roles/wordpress/uploads.ini | |||
@@ -0,0 +1,5 @@ | |||
1 | file_uploads = On | ||
2 | post_max_size = 100M | ||
3 | upload_max_filesize = 100M | ||
4 | memory_limit = 512M | ||
5 | max_execution_time = 600 | ||
diff --git a/photo.jinwei.me/config/site.yaml b/photo.jinwei.me/config/site.yaml new file mode 100644 index 0000000..3dbcc71 --- /dev/null +++ b/photo.jinwei.me/config/site.yaml | |||
@@ -0,0 +1,3 @@ | |||
1 | - hosts: jinwei-me | ||
2 | roles: | ||
3 | - role: debian_init | ||
diff --git a/photo.jinwei.me/infra/.terraform.lock.hcl b/photo.jinwei.me/infra/.terraform.lock.hcl index 6007472..26d65b6 100644 --- a/photo.jinwei.me/infra/.terraform.lock.hcl +++ b/photo.jinwei.me/infra/.terraform.lock.hcl | |||
@@ -1,24 +1,66 @@ | |||
1 | # This file is maintained automatically by "terraform init". | 1 | # This file is maintained automatically by "terraform init". |
2 | # Manual edits may be lost in future updates. | 2 | # Manual edits may be lost in future updates. |
3 | 3 | ||
4 | provider "registry.terraform.io/hetznercloud/hcloud" { | 4 | provider "registry.terraform.io/cloudflare/cloudflare" { |
5 | version = "1.36.1" | 5 | version = "3.29.0" |
6 | constraints = "1.36.1" | 6 | constraints = "~> 3.29" |
7 | hashes = [ | 7 | hashes = [ |
8 | "h1:xZSvxx6aUo0oZp2uqNxi/+wqnCNEBBuu8y7GeXIO9qA=", | 8 | "h1:iGDvVJ6kdlopyhR3ONeoh8gZWZg8+M/seP7VM7gOp1I=", |
9 | "zh:16558b25c7f92f187278e94e951b0ab687882b06acff5b1387f3293f27939f8c", | 9 | "zh:0947f7f9e0234aaeb6b5f344de4148a6379d05370937e1c255872697803c17cc", |
10 | "zh:28fc79ac2189ff0f5e6c9535ada8f57552b6e21c978b59dc78e086c27b9e4b23", | 10 | "zh:17abb230abd852e0e4ed9921cd9aaf03336ad4a13a25b1040ed86cdbddf05123", |
11 | "zh:373907f9f7f2cefa94e2d5638bf5bef3d3b17e7655dc84dd6089346c6f4f9096", | 11 | "zh:2ddf550dbdf5c58bbb8d14de6b2dc76627bb92787b99328300fb312c51e12d1f", |
12 | "zh:394716cd877de682a0772d660f1bdb3838c5d751eca2211105d5ede248c48c39", | 12 | "zh:4645758bdefe52c1aa260368522aff6fcb4e508c918e9b2c263c9debd7d71684", |
13 | "zh:3c438c6590fcc8ac65a10039b2f5ba9ee379a734cb93a59c6cf74f385d891e87", | 13 | "zh:6047320a05d07045f7fb4b24c2540600473a94fc15a24ef99339a6690ab47dfe", |
14 | "zh:3f777a460a62fd23b283c269f1533b3887bf0c5564581e1e96cf294e077f5a8a", | 14 | "zh:6db2d4e4bc3ab8b6107aec80a8041388c2a7722472c5efa6caf8435a453b1f33", |
15 | "zh:4f62967553d7ce81ec14db7685306b625970ba6640b5764dc0137675ab97af0b", | 15 | "zh:8b6b75a75567ae44a788128aebcbb59cebd9a9dbc4ddc1b05f4455734363d55a", |
16 | "zh:56da08f8d75f596d6f9da4f0fd16bd60d1733cabcc260e885e1d7a711d6d3d8b", | 16 | "zh:90c51deb4e96690ed73d8b8498d5ab2d7bb78597861bbef23fab18764371deb0", |
17 | "zh:62776c885bfa8e715dba6662f1744b5251f4cdd523dd4d1e4ccb2e25489593e9", | 17 | "zh:9b0f89952afb5d00e31fb745f1ebb4ef677591ca62c002c744d23bcaa0d51e9a", |
18 | "zh:64cbb68139aa65f95ab3e654d872f9d34ef991fbf667fc30e0f29b96b5e8b4ed", | 18 | "zh:9cfe38d8ef5515d164f59b5f4ddc14bb8817051ea4efed54cb7834c66492dd79", |
19 | "zh:75a4b7a73ff0a537214d12d820438b7ae7a33d660e5d793f4ae0ebe3152bff00", | 19 | "zh:acf89e44b8643d52186ef5155c8889845681471abb60a933017cda9bc38d86ef", |
20 | "zh:7b59d72538772ada7d51eaa50c905285200b1889ab29948b533412ccdf4d18de", | 20 | "zh:c09205c6f1e39994c2f707cce0758a2cd16949b33566a724644593d2a616ea41", |
21 | "zh:b84eeaa82bf765c6dd945ae83f1a9271fa5fad53b861b18b09cb8deda67dae13", | 21 | "zh:c5412f2868592db091b91361b7a85fa3a1a97282e9e6e1c5883dd5f6b5f2e86c", |
22 | "zh:e81c3ea971e32a6ca3fdb0cd9e644614308ab2cf2a19482dd8a109d67fe3fb6f", | 22 | "zh:ff93702ca9a99863914718ae4214acffa1a72d481c8e1d3254ccf5930a2d7e10", |
23 | ] | ||
24 | } | ||
25 | |||
26 | provider "registry.terraform.io/hashicorp/aws" { | ||
27 | version = "4.46.0" | ||
28 | constraints = ">= 3.73.0, ~> 4.46" | ||
29 | hashes = [ | ||
30 | "h1:EZB4OgvytV38JpWyye9zoMQ0bfT9yB9xSXM5NY3Lrws=", | ||
31 | "zh:1678e6a4bdb3d81a6713adc62ca0fdb8250c584e10c10d1daca72316e9db8df2", | ||
32 | "zh:329903acf86ef6072502736dff4c43c2b50f762a958f76aa924e2d74c7fca1e3", | ||
33 | "zh:33db8131fe0ec7e1d9f30bc9f65c2440e9c1f708d681b6062757a351f1df7ce6", | ||
34 | "zh:3a3b010bc393784c16f4b6cdce7f76db93d5efa323fce4920bfea9e9ba6abe44", | ||
35 | "zh:979e2713a5759a7483a065e149e3cb69db9225326fc0457fa3fc3a48aed0c63f", | ||
36 | "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", | ||
37 | "zh:9efcf0067e16ad53da7504178a05eb2118770b4ae00c193c10ecad4cbfce308e", | ||
38 | "zh:a10655bf1b6376ab7f3e55efadf54dc70f7bd07ca11369557c312095076f9d62", | ||
39 | "zh:b0394dd42cbd2a718a7dd7ae0283f04769aaf8b3d52664e141da59c0171a11ab", | ||
40 | "zh:b958e614c2cf6d9c05a6ad5e94dc5c04b97ebfb84415da068be5a081b5ebbe24", | ||
41 | "zh:ba5069e624210c63ad9e633a8eb0108b21f2322bc4967ba2b82d09168c466888", | ||
42 | "zh:d7dfa597a17186e7f4d741dd7111849f1c0dd6f7ebc983043d8262d2fb37b408", | ||
43 | "zh:e8a641ca2c99f96d64fa2725875e797273984981d3e54772a2823541c44e3cd3", | ||
44 | "zh:f89898b7067c4246293a8007f59f5cfcac7b8dd251d39886c7a53ba596251466", | ||
45 | "zh:fb1e1df1d5cc208e08a850f8e84423bce080f01f5e901791c79df369d3ed52f2", | ||
46 | ] | ||
47 | } | ||
48 | |||
49 | provider "registry.terraform.io/hashicorp/random" { | ||
50 | version = "3.4.3" | ||
51 | hashes = [ | ||
52 | "h1:xZGZf18JjMS06pFa4NErzANI98qi59SEcBsOcS2P2yQ=", | ||
53 | "zh:41c53ba47085d8261590990f8633c8906696fa0a3c4b384ff6a7ecbf84339752", | ||
54 | "zh:59d98081c4475f2ad77d881c4412c5129c56214892f490adf11c7e7a5a47de9b", | ||
55 | "zh:686ad1ee40b812b9e016317e7f34c0d63ef837e084dea4a1f578f64a6314ad53", | ||
56 | "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", | ||
57 | "zh:84103eae7251384c0d995f5a257c72b0096605048f757b749b7b62107a5dccb3", | ||
58 | "zh:8ee974b110adb78c7cd18aae82b2729e5124d8f115d484215fd5199451053de5", | ||
59 | "zh:9dd4561e3c847e45de603f17fa0c01ae14cae8c4b7b4e6423c9ef3904b308dda", | ||
60 | "zh:bb07bb3c2c0296beba0beec629ebc6474c70732387477a65966483b5efabdbc6", | ||
61 | "zh:e891339e96c9e5a888727b45b2e1bb3fcbdfe0fd7c5b4396e4695459b38c8cb1", | ||
62 | "zh:ea4739860c24dfeaac6c100b2a2e357106a89d18751f7693f3c31ecf6a996f8d", | ||
63 | "zh:f0c76ac303fd0ab59146c39bc121c5d7d86f878e9a69294e29444d4c653786f8", | ||
64 | "zh:f143a9a5af42b38fed328a161279906759ff39ac428ebcfe55606e05e1518b93", | ||
23 | ] | 65 | ] |
24 | } | 66 | } |
diff --git a/photo.jinwei.me/infra/data.tf b/photo.jinwei.me/infra/data.tf new file mode 100644 index 0000000..2102273 --- /dev/null +++ b/photo.jinwei.me/infra/data.tf | |||
@@ -0,0 +1,11 @@ | |||
1 | data "aws_ami" "debian" { | ||
2 | most_recent = true | ||
3 | owners = ["136693071363"] | ||
4 | |||
5 | filter { | ||
6 | name = "name" | ||
7 | values = ["debian-11-amd64-*"] | ||
8 | } | ||
9 | } | ||
10 | |||
11 | data "aws_availability_zones" "available" {} | ||
diff --git a/photo.jinwei.me/infra/keypair.tf b/photo.jinwei.me/infra/keypair.tf new file mode 100644 index 0000000..a73a0af --- /dev/null +++ b/photo.jinwei.me/infra/keypair.tf | |||
@@ -0,0 +1,4 @@ | |||
1 | resource "aws_key_pair" "framework" { | ||
2 | key_name = "framework" | ||
3 | public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILS2i5/x9r+cv2j2/SUZ2x2fgQeGnJP1I7PUHC0UdWN6 framework" | ||
4 | } | ||
diff --git a/photo.jinwei.me/infra/main.tf b/photo.jinwei.me/infra/main.tf index aabde19..5d3a001 100644 --- a/photo.jinwei.me/infra/main.tf +++ b/photo.jinwei.me/infra/main.tf | |||
@@ -1,54 +1,46 @@ | |||
1 | terraform { | 1 | locals { |
2 | required_providers { | 2 | name = var.name |
3 | hcloud = { | ||
4 | source = "hetznercloud/hcloud" | ||
5 | version = "1.36.1" | ||
6 | } | ||
7 | } | ||
8 | } | ||
9 | |||
10 | variable "hcloud_token" { | ||
11 | sensitive = true | ||
12 | } | 3 | } |
13 | 4 | ||
14 | variable "ip_range" { | 5 | data "aws_subnet" "ec2" { |
15 | default = "10.0.1.0/24" | 6 | filter { |
7 | name = "availability-zone" | ||
8 | values = [aws_db_instance.jinwei-me.availability_zone] | ||
9 | } | ||
10 | filter { | ||
11 | name = "subnet-id" | ||
12 | values = module.vpc.public_subnets | ||
13 | } | ||
16 | } | 14 | } |
17 | 15 | ||
18 | resource "hcloud_ssh_key" "framework" { | 16 | resource "aws_instance" "jinwei_me" { |
19 | name = "framework" | 17 | ami = data.aws_ami.debian.id |
20 | public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILS2i5/x9r+cv2j2/SUZ2x2fgQeGnJP1I7PUHC0UdWN6 framework" | 18 | instance_type = var.ec2_instance_type |
21 | } | ||
22 | 19 | ||
23 | data "hcloud_image" "debian" { | 20 | subnet_id = data.aws_subnet.ec2.id |
24 | name = "debian-11" | 21 | key_name = "framework" |
25 | } | ||
26 | 22 | ||
27 | resource "hcloud_server" "default" { | 23 | vpc_security_group_ids = [aws_security_group.backend.id] |
28 | name = "photo" | ||
29 | image = data.hcloud_image.debian.name | ||
30 | server_type = "cpx11" | ||
31 | location = "fsn1" | ||
32 | ssh_keys = [hcloud_ssh_key.framework.id] | ||
33 | 24 | ||
34 | public_net { | 25 | root_block_device { |
35 | ipv4_enabled = true | 26 | volume_type = "gp3" |
36 | ipv4 = hcloud_primary_ip.primary_ip_1.id | 27 | // how to resize partition and file system after resizing ebs volume |
28 | // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html | ||
29 | volume_size = "30" | ||
30 | tags = { | ||
31 | Name = "${local.name}-root" | ||
32 | } | ||
37 | } | 33 | } |
38 | delete_protection = false | ||
39 | rebuild_protection = false | ||
40 | 34 | ||
41 | firewall_ids = [hcloud_firewall.default.id] | 35 | tags = { |
42 | } | 36 | Name = local.name |
37 | } | ||
43 | 38 | ||
44 | resource "hcloud_primary_ip" "primary_ip_1" { | 39 | lifecycle { |
45 | name = "primary_ip_test" | 40 | ignore_changes = [ami] |
46 | datacenter = "fsn1-dc14" | 41 | } |
47 | type = "ipv4" | ||
48 | assignee_type = "server" | ||
49 | auto_delete = true | ||
50 | } | 42 | } |
51 | 43 | ||
52 | resource "hcloud_firewall" "default" { | 44 | resource "aws_eip" "jinwei-me" { |
53 | name = "default" | 45 | instance = aws_instance.jinwei_me.id |
54 | } | 46 | } |
diff --git a/photo.jinwei.me/infra/outputs.tf b/photo.jinwei.me/infra/outputs.tf new file mode 100644 index 0000000..d24426f --- /dev/null +++ b/photo.jinwei.me/infra/outputs.tf | |||
@@ -0,0 +1,29 @@ | |||
1 | output "rds_hostname" { | ||
2 | description = "RDS instance hostname" | ||
3 | value = aws_db_instance.jinwei-me.address | ||
4 | } | ||
5 | |||
6 | output "rds_port" { | ||
7 | description = "RDS instance port" | ||
8 | value = aws_db_instance.jinwei-me.port | ||
9 | } | ||
10 | |||
11 | output "rds_username" { | ||
12 | description = "RDS instance username" | ||
13 | value = aws_db_instance.jinwei-me.username | ||
14 | } | ||
15 | |||
16 | output "rds_password" { | ||
17 | description = "RDS instance password" | ||
18 | value = random_password.rds_password.result | ||
19 | sensitive = true | ||
20 | } | ||
21 | |||
22 | output "instance" { | ||
23 | description = "The main EC2 instance." | ||
24 | value = { | ||
25 | arn = aws_instance.jinwei_me.arn | ||
26 | public_ip = aws_eip.jinwei-me.public_ip | ||
27 | private_ip = aws_instance.jinwei_me.private_ip | ||
28 | } | ||
29 | } | ||
diff --git a/photo.jinwei.me/infra/rds.tf b/photo.jinwei.me/infra/rds.tf new file mode 100644 index 0000000..f596107 --- /dev/null +++ b/photo.jinwei.me/infra/rds.tf | |||
@@ -0,0 +1,49 @@ | |||
1 | resource "aws_db_parameter_group" "jinwei-me" { | ||
2 | name = var.name | ||
3 | family = var.rds_parameter_group | ||
4 | } | ||
5 | |||
6 | resource "aws_db_instance" "jinwei-me" { | ||
7 | identifier = var.name | ||
8 | instance_class = var.rds_instance_class | ||
9 | allocated_storage = var.rds_storage | ||
10 | engine = var.rds_engine | ||
11 | engine_version = var.rds_engine_version | ||
12 | username = var.rds_username | ||
13 | password = random_password.rds_password.result | ||
14 | port = var.rds_port | ||
15 | db_subnet_group_name = aws_db_subnet_group.jinwei-me.name | ||
16 | vpc_security_group_ids = [aws_security_group.rds.id] | ||
17 | parameter_group_name = aws_db_parameter_group.jinwei-me.name | ||
18 | publicly_accessible = true | ||
19 | skip_final_snapshot = true | ||
20 | } | ||
21 | |||
22 | resource "random_password" "rds_password" { | ||
23 | length = 16 | ||
24 | special = false | ||
25 | } | ||
26 | |||
27 | resource "aws_ssm_parameter" "rds_host" { | ||
28 | name = "/${var.name}/mysql/host" | ||
29 | type = "String" | ||
30 | value = aws_db_instance.jinwei-me.address | ||
31 | } | ||
32 | |||
33 | resource "aws_ssm_parameter" "rds_port" { | ||
34 | name = "/${var.name}/mysql/port" | ||
35 | type = "String" | ||
36 | value = aws_db_instance.jinwei-me.port | ||
37 | } | ||
38 | |||
39 | resource "aws_ssm_parameter" "rds_user" { | ||
40 | name = "/${local.name}/mysql/username" | ||
41 | type = "String" | ||
42 | value = aws_db_instance.jinwei-me.username | ||
43 | } | ||
44 | |||
45 | resource "aws_ssm_parameter" "rds_password" { | ||
46 | name = "/${local.name}/mysql/password" | ||
47 | type = "SecureString" | ||
48 | value = random_password.rds_password.result | ||
49 | } | ||
diff --git a/photo.jinwei.me/infra/sg.tf b/photo.jinwei.me/infra/sg.tf new file mode 100644 index 0000000..4d5ecaa --- /dev/null +++ b/photo.jinwei.me/infra/sg.tf | |||
@@ -0,0 +1,38 @@ | |||
1 | # EC 2 | ||
2 | resource "aws_security_group" "backend" { | ||
3 | name = local.name | ||
4 | vpc_id = module.vpc.vpc_id | ||
5 | } | ||
6 | |||
7 | resource "aws_security_group_rule" "backend_ingress_ssh" { | ||
8 | security_group_id = aws_security_group.backend.id | ||
9 | type = "ingress" | ||
10 | protocol = "tcp" | ||
11 | from_port = 22 | ||
12 | to_port = 22 | ||
13 | cidr_blocks = ["0.0.0.0/0"] | ||
14 | } | ||
15 | |||
16 | resource "aws_security_group_rule" "backend_egress_all" { | ||
17 | security_group_id = aws_security_group.backend.id | ||
18 | type = "egress" | ||
19 | protocol = "all" | ||
20 | from_port = 0 | ||
21 | to_port = 0 | ||
22 | cidr_blocks = ["0.0.0.0/0"] | ||
23 | } | ||
24 | |||
25 | # RDS | ||
26 | resource "aws_security_group" "rds" { | ||
27 | name = "${local.name}-db" | ||
28 | vpc_id = module.vpc.vpc_id | ||
29 | } | ||
30 | |||
31 | resource "aws_security_group_rule" "db_ingress_backend" { | ||
32 | security_group_id = aws_security_group.rds.id | ||
33 | type = "ingress" | ||
34 | protocol = "tcp" | ||
35 | from_port = var.rds_port | ||
36 | to_port = var.rds_port | ||
37 | source_security_group_id = aws_security_group.backend.id | ||
38 | } | ||
diff --git a/photo.jinwei.me/infra/variables.tf b/photo.jinwei.me/infra/variables.tf new file mode 100644 index 0000000..7a62b4d --- /dev/null +++ b/photo.jinwei.me/infra/variables.tf | |||
@@ -0,0 +1,47 @@ | |||
1 | provider "aws" { | ||
2 | region = var.region | ||
3 | } | ||
4 | |||
5 | variable "name" { | ||
6 | description = "Name of the service. It will be used to name EC2, and RDS instances." | ||
7 | default = "jinwei-me" | ||
8 | } | ||
9 | |||
10 | variable "region" { | ||
11 | default = "eu-central-1" | ||
12 | description = "AWS region" | ||
13 | } | ||
14 | |||
15 | # RDS | ||
16 | variable "rds_instance_class" { | ||
17 | default = "db.t3.micro" | ||
18 | } | ||
19 | |||
20 | variable "rds_storage" { | ||
21 | default = 5 | ||
22 | } | ||
23 | |||
24 | variable "rds_username" { | ||
25 | default = "jinweime" | ||
26 | } | ||
27 | |||
28 | variable "rds_engine" { | ||
29 | default = "mariadb" | ||
30 | } | ||
31 | |||
32 | variable "rds_engine_version" { | ||
33 | default = "10.6" | ||
34 | } | ||
35 | |||
36 | variable "rds_parameter_group" { | ||
37 | default = "mariadb10.6" | ||
38 | } | ||
39 | |||
40 | variable "rds_port" { | ||
41 | default = 33060 | ||
42 | } | ||
43 | |||
44 | # EC 2 | ||
45 | variable "ec2_instance_type" { | ||
46 | default = "t3.micro" | ||
47 | } | ||
diff --git a/photo.jinwei.me/infra/versions.tf b/photo.jinwei.me/infra/versions.tf new file mode 100644 index 0000000..844ac4b --- /dev/null +++ b/photo.jinwei.me/infra/versions.tf | |||
@@ -0,0 +1,12 @@ | |||
1 | terraform { | ||
2 | required_providers { | ||
3 | aws = { | ||
4 | source = "hashicorp/aws" | ||
5 | version = "~> 4.46" | ||
6 | } | ||
7 | cloudflare = { | ||
8 | source = "cloudflare/cloudflare" | ||
9 | version = "~> 3.29" | ||
10 | } | ||
11 | } | ||
12 | } | ||
diff --git a/photo.jinwei.me/infra/vpc.tf b/photo.jinwei.me/infra/vpc.tf new file mode 100644 index 0000000..0776178 --- /dev/null +++ b/photo.jinwei.me/infra/vpc.tf | |||
@@ -0,0 +1,29 @@ | |||
1 | locals { | ||
2 | cidr_block = "10.31.0.0/16" | ||
3 | subnets = cidrsubnets(local.cidr_block, 4, 4, 4, 4, 4, 4) | ||
4 | subnet_groups = chunklist(local.subnets, 3) | ||
5 | } | ||
6 | |||
7 | module "vpc" { | ||
8 | source = "terraform-aws-modules/vpc/aws" | ||
9 | version = "3.18.1" | ||
10 | |||
11 | name = local.name | ||
12 | cidr = local.cidr_block | ||
13 | azs = data.aws_availability_zones.available.names | ||
14 | private_subnets = local.subnet_groups[0] | ||
15 | public_subnets = local.subnet_groups[1] | ||
16 | enable_dns_hostnames = true | ||
17 | enable_dns_support = true | ||
18 | enable_nat_gateway = false | ||
19 | single_nat_gateway = true | ||
20 | } | ||
21 | |||
22 | resource "aws_db_subnet_group" "jinwei-me" { | ||
23 | name = var.name | ||
24 | subnet_ids = module.vpc.public_subnets | ||
25 | |||
26 | tags = { | ||
27 | Name = var.name | ||
28 | } | ||
29 | } | ||