Implementation of riichi mahjong related stuff (hand cost, shanten, agari end, etc.)
Bot for tenhou.net riichi mahjong server written in Python
Set up an AWS Application Load Balancer (ALB) and an Amazon S3 bucket for logging ALB activity. The S3 service can then be used for storing app content files.
Plan was applied successfully (on test env):
$ terraform plan
(command output below, it executed planning on TF cloud)
[#7] Setup ALB and S3 modules
[#5] Add AWS Cloudwatch module
[#5] Add AWS Cloudwatch module
Set up AWS ALB.
Accessing application logs is an important part of monitoring and troubleshooting the performance of a system. AWS CloudWatch Logs is a service that allows you to collect, monitor, and analyze log data from various sources in the AWS Cloud.
$ terraform plan
(command output below, it executed planning on TF cloud)
Terraform will perform the following actions:
# module.kms.aws_kms_key.log_key will be created
+ resource "aws_kms_key" "log_key" {
+ arn = (known after apply)
+ bypass_policy_lockout_safety_check = false
+ customer_master_key_spec = "SYMMETRIC_DEFAULT"
+ description = (known after apply)
+ enable_key_rotation = true
+ id = (known after apply)
+ is_enabled = true
+ key_id = (known after apply)
+ key_usage = "ENCRYPT_DECRYPT"
+ multi_region = (known after apply)
+ policy = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-kms-log-key"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-kms-log-key"
+ "Owner" = "alex-ic"
}
}
# module.log.aws_cloudwatch_log_group.main will be created
+ resource "aws_cloudwatch_log_group" "main" {
+ arn = (known after apply)
+ id = (known after apply)
+ kms_key_id = (known after apply)
+ name = "awslogs-alex-ic-staging-log-group"
+ name_prefix = (known after apply)
+ retention_in_days = 14
+ skip_destroy = false
+ tags_all = {
+ "Environment" = "staging"
+ "Owner" = "alex-ic"
}
}
Plan: 2 to add, 0 to change, 0 to destroy.
Configure the Key Management Service (KMS) to manage and store credentials, access keys, and other surreptitious information securely. AWS Secrets Manager provides reliable, robust secret storage and encryption to ensure secure management of our confidential data.
$ terraform plan
(command output below, it executed planning on TF cloud)
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.kms.aws_kms_key.service_key will be created
+ resource "aws_kms_key" "service_key" {
+ arn = (known after apply)
+ bypass_policy_lockout_safety_check = false
+ customer_master_key_spec = "SYMMETRIC_DEFAULT"
+ deletion_window_in_days = 7
+ description = "KMS key for alex-ic-staging-service"
+ enable_key_rotation = true
+ id = (known after apply)
+ is_enabled = true
+ key_id = (known after apply)
+ key_usage = "ENCRYPT_DECRYPT"
+ multi_region = (known after apply)
+ policy = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-kms-key"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-kms-key"
+ "Owner" = "alex-ic"
}
}
# module.kms.aws_secretsmanager_secret.service_secrets["secret_key_base"] will be created
+ resource "aws_secretsmanager_secret" "service_secrets" {
+ arn = (known after apply)
+ description = "Secret 'secret_secret_key_base' for alex-ic-staging"
+ force_overwrite_replica_secret = false
+ id = (known after apply)
+ kms_key_id = (known after apply)
+ name = (known after apply)
+ name_prefix = (known after apply)
+ policy = (known after apply)
+ recovery_window_in_days = 0
+ rotation_enabled = (known after apply)
+ rotation_lambda_arn = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-kms"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-kms"
+ "Owner" = "alex-ic"
}
+ replica {
+ kms_key_id = (known after apply)
+ last_accessed_date = (known after apply)
+ region = (known after apply)
+ status = (known after apply)
+ status_message = (known after apply)
}
+ rotation_rules {
+ automatically_after_days = (known after apply)
}
}
# module.kms.aws_secretsmanager_secret_version.service_secrets["secret_key_base"] will be created
+ resource "aws_secretsmanager_secret_version" "service_secrets" {
+ arn = (known after apply)
+ id = (known after apply)
+ secret_id = (known after apply)
+ secret_string = (sensitive value)
+ version_id = (known after apply)
+ version_stages = (known after apply)
}
# module.kms.random_string.service_secret_random_suffix will be created
+ resource "random_string" "service_secret_random_suffix" {
+ id = (known after apply)
+ length = 6
+ lower = true
+ min_lower = 0
+ min_numeric = 0
+ min_special = 0
+ min_upper = 0
+ number = true
+ numeric = true
+ result = (known after apply)
+ special = false
+ upper = true
}
Plan: 4 to add, 0 to change, 0 to destroy.
Set up a Virtual Private Cloud (VPC) to manage and secure inbound and outbound traffic to our services and to divide up our assets into logical segments for better security and organization.
$ terraform plan
(command output below, it executed planning on TF cloud)
Terraform v1.3.7
on linux_amd64
Initializing plugins and modules...
module.vpc.data.aws_availability_zones.available: Reading...
module.vpc.data.aws_availability_zones.available: Read complete after 1s [id=ap-southeast-1]
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.vpc.module.vpc.aws_eip.nat[0] will be created
+ resource "aws_eip" "nat" {
+ allocation_id = (known after apply)
+ association_id = (known after apply)
+ carrier_ip = (known after apply)
+ customer_owned_ip = (known after apply)
+ domain = (known after apply)
+ id = (known after apply)
+ instance = (known after apply)
+ network_border_group = (known after apply)
+ network_interface = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ public_ipv4_pool = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-vpc-ap-southeast-1a"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-vpc-ap-southeast-1a"
+ "Owner" = "alex-ic"
}
+ vpc = true
}
# module.vpc.module.vpc.aws_internet_gateway.this[0] will be created
+ resource "aws_internet_gateway" "this" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-vpc"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-vpc"
+ "Owner" = "alex-ic"
}
+ vpc_id = (known after apply)
}
# module.vpc.module.vpc.aws_nat_gateway.this[0] will be created
+ resource "aws_nat_gateway" "this" {
+ allocation_id = (known after apply)
+ connectivity_type = "public"
+ id = (known after apply)
+ network_interface_id = (known after apply)
+ private_ip = (known after apply)
+ public_ip = (known after apply)
+ subnet_id = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-vpc-ap-southeast-1a"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-vpc-ap-southeast-1a"
+ "Owner" = "alex-ic"
}
}
# module.vpc.module.vpc.aws_route.private_nat_gateway[0] will be created
+ resource "aws_route" "private_nat_gateway" {
+ destination_cidr_block = "0.0.0.0/0"
+ id = (known after apply)
+ instance_id = (known after apply)
+ instance_owner_id = (known after apply)
+ nat_gateway_id = (known after apply)
+ network_interface_id = (known after apply)
+ origin = (known after apply)
+ route_table_id = (known after apply)
+ state = (known after apply)
+ timeouts {
+ create = "5m"
}
}
# module.vpc.module.vpc.aws_route.public_internet_gateway[0] will be created
+ resource "aws_route" "public_internet_gateway" {
+ destination_cidr_block = "0.0.0.0/0"
+ gateway_id = (known after apply)
+ id = (known after apply)
+ instance_id = (known after apply)
+ instance_owner_id = (known after apply)
+ network_interface_id = (known after apply)
+ origin = (known after apply)
+ route_table_id = (known after apply)
+ state = (known after apply)
+ timeouts {
+ create = "5m"
}
}
# module.vpc.module.vpc.aws_route_table.private[0] will be created
+ resource "aws_route_table" "private" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ propagating_vgws = (known after apply)
+ route = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-vpc-private"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-vpc-private"
+ "Owner" = "alex-ic"
}
+ vpc_id = (known after apply)
}
# module.vpc.module.vpc.aws_route_table.public[0] will be created
+ resource "aws_route_table" "public" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ propagating_vgws = (known after apply)
+ route = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-vpc-public"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-vpc-public"
+ "Owner" = "alex-ic"
}
+ vpc_id = (known after apply)
}
# module.vpc.module.vpc.aws_route_table_association.private[0] will be created
+ resource "aws_route_table_association" "private" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.module.vpc.aws_route_table_association.private[1] will be created
+ resource "aws_route_table_association" "private" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.module.vpc.aws_route_table_association.private[2] will be created
+ resource "aws_route_table_association" "private" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.module.vpc.aws_route_table_association.public[0] will be created
+ resource "aws_route_table_association" "public" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.module.vpc.aws_route_table_association.public[1] will be created
+ resource "aws_route_table_association" "public" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.module.vpc.aws_route_table_association.public[2] will be created
+ resource "aws_route_table_association" "public" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.module.vpc.aws_subnet.private[0] will be created
+ resource "aws_subnet" "private" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-southeast-1a"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.1.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-vpc-private-ap-southeast-1a"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-vpc-private-ap-southeast-1a"
+ "Owner" = "alex-ic"
}
+ vpc_id = (known after apply)
}
# module.vpc.module.vpc.aws_subnet.private[1] will be created
+ resource "aws_subnet" "private" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-southeast-1b"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.2.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-vpc-private-ap-southeast-1b"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-vpc-private-ap-southeast-1b"
+ "Owner" = "alex-ic"
}
+ vpc_id = (known after apply)
}
# module.vpc.module.vpc.aws_subnet.private[2] will be created
+ resource "aws_subnet" "private" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-southeast-1c"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.3.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-vpc-private-ap-southeast-1c"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-vpc-private-ap-southeast-1c"
+ "Owner" = "alex-ic"
}
+ vpc_id = (known after apply)
}
# module.vpc.module.vpc.aws_subnet.public[0] will be created
+ resource "aws_subnet" "public" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-southeast-1a"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.4.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = true
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-vpc-public-ap-southeast-1a"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-vpc-public-ap-southeast-1a"
+ "Owner" = "alex-ic"
}
+ vpc_id = (known after apply)
}
# module.vpc.module.vpc.aws_subnet.public[1] will be created
+ resource "aws_subnet" "public" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-southeast-1b"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.5.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = true
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-vpc-public-ap-southeast-1b"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-vpc-public-ap-southeast-1b"
+ "Owner" = "alex-ic"
}
+ vpc_id = (known after apply)
}
# module.vpc.module.vpc.aws_subnet.public[2] will be created
+ resource "aws_subnet" "public" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-southeast-1c"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.6.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = true
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-vpc-public-ap-southeast-1c"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-vpc-public-ap-southeast-1c"
+ "Owner" = "alex-ic"
}
+ vpc_id = (known after apply)
}
# module.vpc.module.vpc.aws_vpc.this[0] will be created
+ resource "aws_vpc" "this" {
+ arn = (known after apply)
+ cidr_block = "10.0.0.0/16"
+ default_network_acl_id = (known after apply)
+ default_route_table_id = (known after apply)
+ default_security_group_id = (known after apply)
+ dhcp_options_id = (known after apply)
+ enable_classiclink = (known after apply)
+ enable_classiclink_dns_support = (known after apply)
+ enable_dns_hostnames = true
+ enable_dns_support = true
+ enable_network_address_usage_metrics = (known after apply)
+ id = (known after apply)
+ instance_tenancy = "default"
+ ipv6_association_id = (known after apply)
+ ipv6_cidr_block = (known after apply)
+ ipv6_cidr_block_network_border_group = (known after apply)
+ main_route_table_id = (known after apply)
+ owner_id = (known after apply)
+ tags = {
+ "Name" = "alex-ic-staging-vpc"
}
+ tags_all = {
+ "Environment" = "staging"
+ "Name" = "alex-ic-staging-vpc"
+ "Owner" = "alex-ic"
}
}
Plan: 20 to add, 0 to change, 0 to destroy.
Provide a description of the changes this pull request brings to the codebase. Additionally, when the pull request is still being worked on, a checklist of the planned changes is welcome to track progress.
Describe in detail why this solution is the most appropriate, which solution you tried but did not go with, and how to test the changes. References to relevant documentation are welcome as well.
Show us the implementation: screenshots, GIFs, etc.
Provide a description of the changes this pull request brings to the codebase. Additionally, when the pull request is still being worked on, a checklist of the planned changes is welcome to track progress.
Describe in detail why this solution is the most appropriate, which solution you tried but did not go with, and how to test the changes. References to relevant documentation are welcome as well.
Show us the implementation: screenshots, GIFs, etc.
To have consistent plan/apply we need to use same TF version for all developers and for TF Cloud.
[#28] Lock TF version (#29)
It is a good practice to lock software on specific version to avoid any surprises in the future.
If TF Cloud version doesn't match configuration version, there will be an error:
If correct version is set, the plan is running fine:
[#3] Set up CD with GitHub Actions (#12)
[#3] Add build and deploy script
[#3] Set env variables from variable and remove deprecated code
[#3] Remove debug step
[#3] Update project README
[#3] Rephrase step names
[#3] Update outdated action versions
[#3] Remove mask-aws-account-id option
[#3] Allow to deploy be run on any branch
[#3] Apply deployment only on develop and main branches
[#3] Improve job name
We need a way to build a project Docker image and put this image in the registry.
develop
branch staging version of container should be build and pushed to AWS ECRmain
branch production version of container should be build and pushed to AWS ECRClose #3
Add GH action workflow to build docker image and deploy application to AWS.
Same workflow supports staging deployment from develop
branch and production deployment from main
branch.
You can find test workflow run here, image was built and deployed: https://github.com/Nihisil/nimble-devops-ic-app/actions/runs/4051871868