• 如何使用 Terraform 來完成WordPress Spot instance 的滾動更新

    使用AWS Spot instance 的朋友都知道,他很便宜,有些機型可以便宜90%。

    他有兩種運行模式,一種是One time 一種是Persist,在AWS 容量充足的情況下,使用Persist 方式可以在很長時間內維持一個低價位的運行水平,但,問題是,AWS 的容量是動態調整的,比如您使用c5.large 的persist spot instance ,當有人啟用了更多的c5.large On-demand 容量,您使用的Spot instance 就會被強制釋放掉,而這段不可用的時間可能持續數分鐘到數小時,完全無法預估。這時候只能手動製作一個AMI,然後從AMI 啟動一個新的不同的instance type ,通常可用。

    那麼,如何做到無需人工干預,讓Spot instance 在不同的instance type 之間自動續命不停歇呢?

    當有人啟用了更多的On-demand 容量時,他總不可能把所有的instance type 都用盡吧,根據這個思路,我們可以使用Spot Fleet Request,在這個fleet 中設置幾個不同的機型。

    那麼選用那種類型的instance 呢?您一定想當然的認為 t3/t4 會比較便宜,然而在Spot instance ,並不是這樣,是使用的人越少,他越便宜,下面以Osaka region 的部分ARM64 機型為例,使用aws cli query:

    aws ec2 describe-spot-price-history \
      --instance-types t4g.medium c6g.medium c6gd.medium c7g.medium c7gd.medium c8g.medium m6g.medium m6gd.medium m7g.medium m8g.medium r6g.medium r7g.medium r8g.medium \
      --product-descriptions "Linux/UNIX" \
      --start-time $(date -u +"%Y-%m-%dT%H:%M:%SZ") \
      --end-time $(date -u +"%Y-%m-%dT%H:%M:%SZ") \
      --query "sort_by(SpotPriceHistory[?AvailabilityZone=='ap-northeast-3a' || AvailabilityZone=='ap-northeast-3c'], &SpotPrice)[*].[InstanceType,SpotPrice,AvailabilityZone]" \
      --output table
    
    ------------------------------------------------
    |           DescribeSpotPriceHistory           |
    +-------------+------------+-------------------+
    |  c8g.medium |  0.012400  |  ap-northeast-3c  |
    |  c8g.medium |  0.012500  |  ap-northeast-3a  |
    |  m6g.medium |  0.012600  |  ap-northeast-3c  |
    |  c7g.medium |  0.013600  |  ap-northeast-3a  |
    |  m6g.medium |  0.014200  |  ap-northeast-3a  |
    |  c7gd.medium|  0.014200  |  ap-northeast-3a  |
    |  m8g.medium |  0.014500  |  ap-northeast-3c  |
    |  m8g.medium |  0.014500  |  ap-northeast-3a  |
    |  m6gd.medium|  0.014600  |  ap-northeast-3a  |
    |  m6gd.medium|  0.014800  |  ap-northeast-3c  |
    |  m7g.medium |  0.014800  |  ap-northeast-3c  |
    |  m7g.medium |  0.015000  |  ap-northeast-3a  |
    |  r6g.medium |  0.015200  |  ap-northeast-3c  |
    |  r6g.medium |  0.015300  |  ap-northeast-3a  |
    |  r7g.medium |  0.016300  |  ap-northeast-3a  |
    |  c6gd.medium|  0.017400  |  ap-northeast-3c  |
    |  c6g.medium |  0.017700  |  ap-northeast-3c  |
    |  c6g.medium |  0.017700  |  ap-northeast-3a  |
    |  r7g.medium |  0.018200  |  ap-northeast-3c  |
    |  r8g.medium |  0.018200  |  ap-northeast-3a  |
    |  c7g.medium |  0.018200  |  ap-northeast-3c  |
    |  r8g.medium |  0.018400  |  ap-northeast-3c  |
    |  c6gd.medium|  0.018700  |  ap-northeast-3a  |
    |  t4g.medium |  0.019800  |  ap-northeast-3c  |
    |  t4g.medium |  0.020100  |  ap-northeast-3a  |
    +-------------+------------+-------------------+

    t4g.small On-Demand 的價格是 每小時 $0.0218,上面的價格比t4g.small 還要低,能不用他嗎?

    對於CPU 持續運算型的workload 可以選用C/M 系列,對於有多線程優化的workload 可以選用t4g.medium,對於Memory 優先的workload 則可以選用R/M 系列。

    但是,請注意,因為m8g/c8g 使用了更新一代的Graviton 4 chip,所以,即使只有1顆vCPU,因為他的處理速度更快,他的實際表現仍然可能會超過擁有兩顆Graviton 2 vCPU 的t4g,何況他還更便宜。

    各大雲平臺的ARM64 機器都是玄學,具體的性能表現沒有一個官方的評測,我估計是因為在不同的workload 上表現可能差異很大,因為傳統研發還是更注重於x86_64 。

    首先創建一個launch template ,裡面包含現在的EC2 製作的AMI,記錄一下 launch template id ,接下來會用到他。

    然後,從 Spot Requests 點擊 Create Spot Fleet request,首先當然是選擇使用launch template。

    對於 Target capacity 可以根據實際需要,比如我這個blog ,可以只選擇1 就好。

    對於 Network , 如果在launch template 中有設置這裡就不需要了,但不要多處設置以免衝突。

    好了,接下來是最重要的 Instance type requirements , 請選擇 Manually select instance types,然後 Add instance types ,將需要的instance types 加入進去。

    對於 Allocation strategy 就選擇預設的最低價。

    請不要點擊創建,可以看到在launch 旁邊有一個JSON config,點擊他將config download 到本機,保存為/Downloads/fleet.json。

    使用下面的aws cli 命令 直接創建 spot fleet –

    aws ec2 request-spot-fleet --spot-fleet-request-config file://Downloads/fleet.json
    
    
    
    {
        "IamFleetRole": "arn:aws:iam::123454567890:role/aws-ec2-spot-fleet-tagging-role",
        "AllocationStrategy": "priceCapacityOptimized",
        "TargetCapacity": 1,
        "ValidFrom": "2026-01-06T08:19:06.000Z",
        "ValidUntil": "2027-01-06T08:19:06.000Z",
        "TerminateInstancesWithExpiration": true,
        "Type": "maintain",
        "OnDemandAllocationStrategy": "lowestPrice",
        "LaunchSpecifications": [],
        "LaunchTemplateConfigs": [
            {
                "LaunchTemplateSpecification": {
                    "LaunchTemplateId": "lt-0716c882cb57a921d",
                    "Version": "$Latest"
                },
                "Overrides": [
                    {
                        "InstanceType": "m6g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0d2535d7e7cacf658",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "m6g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0c255e6c5c642da2a",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "m6g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-06ee85eed40f5261b",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "m7g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0d2535d7e7cacf658",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "m7g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0c255e6c5c642da2a",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "m7g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-06ee85eed40f5261b",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "m8g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0d2535d7e7cacf658",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "m8g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0c255e6c5c642da2a",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "m8g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-06ee85eed40f5261b",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "r6g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0d2535d7e7cacf658",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "r6g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0c255e6c5c642da2a",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "r6g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-06ee85eed40f5261b",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "r7g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0d2535d7e7cacf658",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "r7g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0c255e6c5c642da2a",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "r7g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-06ee85eed40f5261b",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "r8g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0d2535d7e7cacf658",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "r8g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0c255e6c5c642da2a",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "r8g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-06ee85eed40f5261b",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "t4g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0d2535d7e7cacf658",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "t4g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-0c255e6c5c642da2a",
                        "SpotPrice": "0.017"
                    },
                    {
                        "InstanceType": "t4g.medium",
                        "WeightedCapacity": 1,
                        "SubnetId": "subnet-06ee85eed40f5261b",
                        "SpotPrice": "0.017"
                    }
                ]
            }
        ]
    }

    大功告成!

    記錄一下 Request ID sfr-c7ccc145-d71d-4268-8b67-089161e02af6 ,接下來會用到他。

    這樣,當有人啟用了更多的 On-demand 容量而迫使您當前使用的Spot Instance 被終止後,Spot Fleet 將會從這些機型中啟動新的Spot Instance ,不可能所有機型的Spot 容量都被用盡,這是絕對不可能的!

    那麼,我們要如何更新呢?比如説,Security Patch,升級nginx ,php ,wordpress 版本?

    對於Wordpress 而言,他的更新很頻繁,我不希望剛post 一個新的blog 然後instance 就被terminate 了,所以,這裡我們要使用EFS 來放置所有的Wordpress 文件。

    那麼nginx , php 是不行的呀,如何用terraform 來自動化這些更新的動作?

    根據這個思路,我們先梳理一下具體要做哪些步驟:

    首先需要 Create AMI after nginx/php/OS change with current instance ID and give a name to this AMI

    aws ec2 create-image \
        --instance-id i-0716c882cb57a921d \
        --name "web2026" \
        --no-reboot \
        --tag-specifications 'ResourceType=image,Tags=[{Key=auto-delete,Value=no}]' \
        --region ap-northeast-3

    然後需要 Update launch template to use this AMI and set default version

    Create new version with updated AMI
    aws ec2 create-launch-template-version \
        --launch-template-id lt-0716c882cb57a921d \
        --source-version '$Latest' \
        --launch-template-data '{"ImageId":"ami-"}' \
        --region ap-northeast-3
    
    Set the new version as default
    aws ec2 modify-launch-template \
        --launch-template-id lt-0716c882cb57a921d \
        --default-version '$Latest' \
        --region ap-northeast-3
    
    Get AMI id from last step and check AMI progress
    aws ec2 describe-images \
        --image-ids ami-xxxxxxxx \
        --region ap-northeast-3 \
        --query 'Images[0].State'

    如果AMI 製作成功,那就 Terminate old instance ,此時Spot Fleet將會使用launch tempate 中的新的AMI 啟動新的Spot Instance。

    按照上述的流程,

    接下來安裝 terraform –

    terraform -v
    Terraform v1.5.7 on darwin_arm64

    創建一個工作目錄 mkdir ami-update-workflow

    創建main.tf 配置文件,需要修改的地方有 – 正確的Region,前面配置的Launch Template ID,以及啟動的Spot Fleet Request ID:

    terraform {
      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = "~> 5.0"
        }
      }
    }
    
    provider "aws" {
      region = "ap-northeast-3"
    }
    
    # Get instance ID from spot fleet using external data source
    data "external" "spot_instance" {
      program = ["bash", "-c", <<-EOT
        INSTANCE_ID=$(aws ec2 describe-spot-fleet-instances \
          --spot-fleet-request-id sfr-c7ccc145-d71d-4268-8b67-089161e02af6 \
          --region ap-northeast-3 \
          --query 'ActiveInstances[0].InstanceId' --output text)
        echo "{\"instance_id\":\"$INSTANCE_ID\"}"
      EOT
      ]
    }
    
    # Create AMI with correct EBS settings using AWS CLI
    resource "null_resource" "create_ami_with_ebs" {
      provisioner "local-exec" {
        command = <<-EOT
          AMI_ID=$(aws ec2 create-image \
            --instance-id ${data.external.spot_instance.result.instance_id} \
            --name "web-${formatdate("YYYYMMDD-hhmm", timestamp())}" \
            --no-reboot \
            --block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{"DeleteOnTermination":true,"VolumeSize":10,"VolumeType":"gp3"}}]' \
            --tag-specifications 'ResourceType=image,Tags=[{Key=auto-delete,Value=no}]' \
            --region ap-northeast-3 \
            --query 'ImageId' --output text)
          echo "{\"ami_id\":\"$AMI_ID\"}" > ami_output.json
        EOT
      }
    }
    
    # Get the AMI ID from the output file
    data "local_file" "ami_output" {
      depends_on = [null_resource.create_ami_with_ebs]
      filename   = "ami_output.json"
    }
    
    locals {
      ami_data = jsondecode(data.local_file.ami_output.content)
      ami_id   = local.ami_data.ami_id
    }
    
    # Update launch template and terminate instance
    resource "null_resource" "update_launch_template" {
      depends_on = [data.local_file.ami_output]
    
      provisioner "local-exec" {
        command = <<-EOT
      # Wait for AMI to be available
          while [ "$(aws ec2 describe-images --image-ids ${local.ami_id} --query 'Images[0].State' --output text --region ap-northeast-3)" != "available" ]; do
            echo "Waiting for AMI to be available..."
            sleep 30
          done
    
          # Create new version
          aws ec2 create-launch-template-version \
            --launch-template-id lt-0716c882cb57a921d \
            --source-version '$Latest' \
            --launch-template-data '{"ImageId":"${local.ami_id}"}' \
            --region ap-northeast-3
    
          # Set as default
          aws ec2 modify-launch-template \
            --launch-template-id lt-0716c882cb57a921d \
            --default-version '$Latest' \
            --region ap-northeast-3
    
          # Terminate the old instance
          aws ec2 terminate-instances \
            --instance-ids ${data.external.spot_instance.result.instance_id} \
            --region ap-northeast-3
        EOT
      }
    }
    
    output "ami_id" {
      value = local.ami_id
    }
    
    output "instance_id" {
      value = data.external.spot_instance.result.instance_id
    }

    在目錄中創建一個run.sh 內容物如下:

    rm terraform.tfstate*
    rm -rf .terraform/
    terraform init

    來跑一下:

    ./run.sh 
    
    Initializing the backend...
    ......
    Terraform has been successfully initialized!
    
    You may now begin working with Terraform. Try running "terraform plan" to see
    any changes that are required for your infrastructure. All Terraform commands
    should now work.
    
    If you ever set or change modules or backend configuration for Terraform,
    rerun this command to reinitialize your working directory. If you forget, other
    commands will detect it and remind you to do so if necessary.

    Run “terraform plan”

    ......
    
    Plan: 2 to add, 0 to change, 0 to destroy.
    
    Changes to Outputs:
      + ami_id      = (known after apply)
      + instance_id = "i-0ef93b2b937468a98"
    
    ───────────────────────────────────────────────────────────────────────────────
    
    Note: You didn't use the -out option to save this plan, so Terraform can't
    guarantee to take exactly these actions if you run "terraform apply" now.

    Run “terraform apply”,也可以直接跑到這裡不用plan 。

    ......
    null_resource.update_launch_template: Creation complete after 3m19s [id=3702937929507644703]
    
    Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
    
    Outputs:
    
    ami_id = "ami-0dd89a88bf12cb2bd"
    instance_id = "i-0ef93b2b937468a98"

    執行完成後,spot instance 就被製作成新的AMI 並被設置為launch template 的default AMI,而且最後會terminate 當前的spot instance 喔。

    目前運行穩定,沒發現有什麼問題,似乎使用ASG 也可以達成這個目的,讓我們下次再議。

    CIA 最近一段時間動作頻頻,發佈了多條針對中國招募線人的廣告Videos,很多人認為是在中國的諜報人員都被處決,我並不認同,我認為這是為了掩護某些重要情報來源而故意放的煙霧彈,當你看身邊所有人都像五十萬的時候,真正的五十萬就隱藏起來了。
  • 如何升級EC2 上的MacOS? How to upgrade MacOS on AWS EC2

    參考官方文件就可以了 – https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/mac-instance-updates.html

    過於陳舊的MacOS 需要升級ENA driver,但通常不會有這種情況,因為使用MacOS 主要是用於iOS 開發和迅速迭代,沒有人會用五年前的Mac 來寫code,因為你要支持最新的iPhone 就必須要用最新的MacOS。而且,不是所有的版本都支持升級,支持的版本請參考該頁面說明。

    使用SSH 連結到 EC2 並為ec2-user 設置一個密碼:

    sudo /usr/bin/dscl . -passwd /Users/ec2-user

    為了Enable the secure token for the ec2-user user,必須修改一次密碼,修改的動作並不是為了修改密碼,而是為了Enable the secure token。

    vi old_password.txt
    
    vi new_password.txt
    
    sysadminctl -oldPassword `cat old_password.txt` -newPassword `cat new_password.txt`
    
    2026-01-21 06:53:17.708 sysadminctl[705:6829] Attempting to change password for ec2-user…
    2026-01-21 06:53:19.287 sysadminctl[705:6829] SecKeychainCopyLogin returned -25294
    2026-01-21 06:53:19.287 sysadminctl[705:6829] Failed to update keychain password (-25294)
    2026-01-21 06:53:19.288 sysadminctl[705:6829] - Done

    確認一下真的啟用了:

    sysadminctl -secureTokenStatus ec2-user
    
    2026-01-21 06:58:35.755 sysadminctl[806:8689] Secure token is ENABLED for user ec2-user

    創建一個json 文件用於Delegate ownership of the Amazon EBS root volume to the EBS root volume administrative user,這是因為在 Apple Silicon Mac (Mac2, Mac2-m2, Mac-m4 等)上,系統更新需要特定的管理權限,當你要進行 macOS 系統更新時,需要先將 EBS根磁碟區的所有權從內部磁碟管理員(aws-managed-user)委派給 EBS 根磁碟區管理使用者(通常是 ec2-user)。

    vi mac-credentials.json
    
    {
      "internalDiskPassword":"",
      "rootVolumeUsername":"ec2-user",
      "rootVolumepassword":"newPasswordHere"
    }
    
    aws ec2 create-delegate-mac-volume-ownership-task \
    --instance-id i-079180f283a7b0baf \
    --mac-credentials file://mac-credentials.json
    
    {
        "MacModificationTask": {
            "InstanceId": "i-079180f283a7b0baf",
            "MacModificationTaskId": "macmodification-05b40255b8b15176c",
            "MacSystemIntegrityProtectionConfig": {},
            "StartTime": "2026-01-21T08:09:43.417000+00:00",
            "TaskState": "pending",
            "TaskType": "volume-ownership-delegation"
        }
    }
    
    aws ec2 describe-mac-modification-tasks \
    --mac-modification-task-id macmodification-05b40255b8b15176c
    
    {
        "MacModificationTasks": [
            {
                "InstanceId": "i-079180f283a7b0baf",
                "MacModificationTaskId": "macmodification-05b40255b8b15176c",
                "MacSystemIntegrityProtectionConfig": {},
                "StartTime": "2026-01-21T08:09:43.417000+00:00",
                "Tags": [],
                "TaskState": "in-progress",
                "TaskType": "volume-ownership-delegation"
            }
        ]
    }

    上面一般需要30~90 分鐘,我是用了四十幾分鐘,

    login after rebooted:
    
        ┌───┬──┐   __|  __|_  )
        │ ╷╭╯╷ │   _|  (     /
        │  └╮  │  ___|\___|___|
        │ ╰─┼╯ │  Amazon EC2
        └───┴──┘  macOS Sequoia 15.7.3
    
    
    softwareupdate --list
    Software Update Tool
    
    Finding available software
    Software Update found the following new or updated software:
    * Label: macOS Tahoe 26.2-25C56
        Title: macOS Tahoe 26.2, Version: 26.2, Size: 8111826KiB, Recommended: YES, Action: restart, 
    
    sudo softwareupdate --install --all --restart
    Software Update Tool
    
    Finding available software
    Downloading macOS Tahoe 26.2
    Password: 
    Downloading: 62.47%
    Downloading: 93.73%
    Downloading: 100.00%
    Downloaded: macOS Tahoe 26.2
    Restarting...
    
    
        ┌───┬──┐   __|  __|_  )
        │ ╷╭╯╷ │   _|  (     /
        │  └╮  │  ___|\___|___|
        │ ╰─┼╯ │  Amazon EC2
        └───┴──┘  macOS Tahoe 26.2
  • 作為一個身處自由世界的人,我這種講法是過於自私了

    我原本以為昨天晚上半夜被搖醒準備爬起來是幻覺,早上忽然看到,哎,有地震過。

    那看來不是幻覺。

    被社會主義奴役二十五年的委內瑞拉人民有沒有獲得自由還有待觀察,但以馬杜羅為首的軍方使用裝甲車衝撞輾壓抗議人群,早已失去其執政的合法性。

    至於他往美國境內走私毒品和軍火,並不是像墨西哥一樣從中國進口 fentanyl 原材料二次加工,而是哥倫比亞邊境過來的 cocaine ,日益先進的電動潛水艇技術讓美國廣袤的海岸線確實無法防範,就算是Coast Guard也會疲於奔命,關於這一點,Youtube 上有很多影片說明。

    中國支持馬杜羅的大量先進武器當然是為了石油而不是為了要和美國對抗,中共從來沒有什麼路線,底線,原則之類的,只有利益之爭。

    我至今還記得查韋斯女兒被一堆美鈔包圍的照片,這些所謂的社會主義革命者,其虛偽無恥無法用適當的文字來形容,查韋斯得癌症死去,算是為他留下一點顏面,如果長命百歲,他的名聲恐怕會更加惡臭。

    馬杜羅被美軍抓走後,網路上很多中國民族主義者想要共軍抓捕賴清德。

    對於民主國家而言,總統被抓了副總統可以上,副總統被抓了行政院長可以上,行政院長被抓了還有立法院院長,立法院副院長。

    而獨裁國家,總統被抓了,大家都不會往前衝的,你看委內瑞拉就知道。

    2026年觀看的第一部電影是關於二二八出品于1989年的《悲情城市》,這部電影對於二二八的描述並不直接。

    但是,想想今天的《大濛》都還遮遮掩掩,當年的《悲情城市》已經非常了不起,如果要放在一起比較,《大濛》就是0分。

    這部電影以1945至1949年為背景,透過基隆九份林家四兄弟的命運,呈現二二八事件與白色恐怖下臺灣社會的動盪與壓抑。四兄弟在政權更替、黑幫勾結與政治迫害中相繼遭遇不幸,象徵臺灣人民在歷史洪流中的掙扎,沉默與創傷。電影使用多種語言(台語、日語、粵語、國語、英語)呈現,以日常生活折射政治壓迫,並沒有什麼驚心動魄的場景。

    2023年出了4K 修復版,但是沒有上streaming ,大概是知道一上就會被盜版。

    今日的台灣社會對於二二八的反思是嚴重不足的,因為當時的那些上海黑幫和抓捕學生的兵,官,將並沒有得到任何清算。

    畢竟蔣公的日記已經把責任推給陳誠了。

    新的一年,願所有的獨裁者都長命百歲,這樣我們才能看到和民主國家不一樣的千百萬種可能性。