如何在GCP以及AWS設定 remote backend 管理 terraform 狀態檔

閱讀時間約 30 分鐘


raw-image

👨‍💻簡介

terraform在每次執行terraform planterraform apply時,是如何知道應該要管理哪些資源?

其實就是透過在每次執行terraform時,將建立或要變更的資源都記錄在terraform.state這份狀態檔,預設檔案使用JSON格式。

假設建立一個google cloud storage的resource,tf設定檔如下:

resource "google_storage_bucket" "bucket" {
name = "terraform-alan-test-bucket"
location = "ASIA-EAST1"
storage_class = "STANDARD"
public_access_prevention = "enforced"
force_destroy = true
uniform_bucket_level_access = true
}

建立後的terraform.tfstate的一小部分如下:

{
"version": 4,
"terraform_version": "1.5.7",
"serial": 3,
"lineage": "abda0fda-b807-b8b3-0a36-8b0c2f92e3f5",
"outputs": {},
"resources": [
{
"module": "module.base-bucket",
"mode": "managed",
"type": "google_storage_bucket",
"name": "bucket",
"provider": "module.base-bucket.provider[\"registry.terraform.io/hashicorp/google\"]",
"instances": [
{
"schema_version": 1,
"attributes": {
"autoclass": [],
"cors": [],
"custom_placement_config": [],
"default_event_based_hold": false,
"effective_labels": {},
"encryption": [],
"force_destroy": true,
"id": "terraform-alan-test-bucket",
"labels": null,
"lifecycle_rule": [],
"location": "ASIA-EAST1",
"logging": [],
"name": "terraform-alan-test-bucket",
}
}
]
}
]
}

可以看到id的屬性,當每次執行plan或是apply時,terraform就是拿這個屬性從本地terraform設定檔與雲上資源做比對。

如果你的terraform用在個人專案,則將狀態檔存在本機即可;不過如果是一個團隊要使用terraform,則可能會遇到幾個問題:

  • 狀態檔需要共用:需要確保團隊成員都能正常存取相同的terraform狀態檔。
  • 鎖定狀態檔:需要確保團隊成員使用terraform進行操作時,只有一人能對狀態檔做修改,否則可能會因為多個terraform進程對狀態檔做併發更新,導致資料丟失或是狀態檔損壞。

要解決上述問題,常見的做法是將狀態檔進行版本控制(git),但因為某些原因,將狀態檔進行版控並不是一個好想法。有底下幾個原因:

  • 手動操作錯誤:有時候可能在操作terraform時,忘記拉取最新狀態檔,或是在執行完terraform後,忘記將狀態檔更新到版控。可能團隊成員使用到舊的狀態檔導致資源回滾。
  • 鎖定問題:多數的版本控制系統沒提供任何形式的鎖定,防止兩個團隊成員同時對同一份狀態檔執行操作。
  • 加密:terraform狀態檔的資料預設都是以明文形式儲存。但某些資源需要儲存敏感資料,像是資料庫創建時需要建立初始化使用者以及密碼,這些資料不應該以明文的形式儲存在版本控制。

因為以上原因,terraform官方推出 remote backend的支援,可以將狀態檔儲存在所使用的雲平台,而不是使用版本控制,而remote backend解決了剛才列出的三個問題:

  • 手動操作錯誤:terraform每次運行時會自動從 remote backend 載入狀態檔,並且每次運行後都會自動將狀態檔儲存在 remote backend,解決了手動操作錯誤。
  • 鎖定問題:大多數 remote backend 都支援鎖定。運行terraform時會自動將檔案進行上鎖,確保只會有一人進行操作。
  • 加密:大多數 remote backend 都支援狀態檔的傳輸中加密和靜態加密。

使用gcp平台推薦使用 google cloud storage,整理的原因如下:

  • 這是託管服務,不需部署和管理額外基礎設施即可使用。
  • gcs旨在實現99.99%的持久性和年度耐用性。

数据可用性和耐用性 | Cloud Storage | Google Cloud

  • gcs支援加密,預設使用server side encrypt,另外也可使用ckms服務

数据加密选项 | Cloud Storage | Google Cloud

  • 支援版本控制

使用对象版本控制 | Cloud Storage | Google Cloud

  • 費用便宜,使用免費額度即可滿足需求。

价格 | Cloud Storage | Google Cloud

GCP GCS作為terraform remote backend

要使用 Google cloud stroage作為 terraform remote backend,首先是先建立 gcs bucket。 在新資料夾中建立一個provider.tf檔案

terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">=4.0"
}
}
}

provider "google" {
region ="asia-east1"
}

接著再建立一個名為bucket.tf檔案,使用 google_storage_bucket resource 建立 gcs bucket。

resource "google_storage_bucket" "bucket" {
name = "terraform-alan-test-bucket"
location = "ASIA-EAST1"
storage_class = "STANDARD"
public_access_prevention = "enforced"
force_destroy = false
uniform_bucket_level_access = true
}

參數說明如下:

  • name:定義 gcs bucket 名稱
  • location:指定 bucket 儲存位置
  • storage_class:指定 bucket 儲存類型
  • public_access_prevention:設定公開存取防止策略,enforce表示不允許公開訪問
  • force_destroy:設定是否可強制刪除
  • uniform_bucket_level_access:設定是否啟用統一訪問控制

當執行完terraform init以及 terraform apply部署完後,就會看到gcs已經建立完成。但目前狀態檔還是儲存在本地。要將狀態檔儲存到 gcs bucket,需要再額外設定 remote backend,語法如下:

terraform {
backend "<BACKEND_NAME>" {
[CONFIG...]
}
}

其中 BACKEND_NAME是要使用的資源,CONFIG是對這個後端的參數設定。以下是 gcs bucket的後端設定:

terraform {
backend "gcs" {
bucket = "terraform-alan-test-bucket"
prefix = "bucket-state"
}
}

參數說明如下:

  • bucket:要使用的bucket name,這邊填入剛剛建立的 bucket
  • prefix:定義狀態檔的路徑和名稱,以上述為例,狀態檔會被存放在 bucket-state資料夾

要將狀態檔儲存到 gcs ,只需要重新執行 terraform init 指令。該指令不僅可以下載 provider code,還可以設定 terraform backend。此外,init的指令是冪等的,多次執行可以確保每次都是預期的行為。

> terraform init
Initializing the backend...
Do you want to copy existing state to the new backend?
Pre-existing state was found while migrating the previous "local" backend to the
newly configured "gcs" backend. No existing state was found in the newly
configured "gcs" backend. Do you want to copy this state to the new "gcs"
backend? Enter "yes" to copy and "no" to start with an empty state.
Enter a value:

執行後terraform會自動檢查本地已有的狀態檔,並跳出提示說要將狀態檔複製到 gcs backend。如果輸入 yes,則會看到以下內容:

Successfully configured the backend "gcs"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing modules...
Initializing provider plugins...
- Reusing previous version of hashicorp/google from the dependency lock file
- Using previously-installed hashicorp/google v5.3.0
Terraform has been successfully initialized!

執行完畢後可以到 gcs查看狀態檔是否已經儲存上去。

raw-image

如果之後有資源使用一樣的backend,terraform執行時就會自動從這個 gcs拉取最新的狀態,並且執行後會自動將最新狀態推送到這個 gcs。

當有兩人同時執行時,則第二個人會出現以下訊息:

> terraform plan
Acquiring state lock. This may take a few moments...

│ Error: Error acquiring the state lock

│ Error message: writing
"gs://terraform-alan-test-bucket/bucket-state/default.tflock" failed:
│ googleapi: Error 412: At least one of the pre-conditions you specified did not
│ hold., conditionNotMet
│ Lock Info:
ID: 1698225515771180
│ Path: gs://terraform-alan-test-bucket/bucket-state/default.tflock
│ Operation: OperationTypeApply
│ Who: alan_wang
│ Version: 1.5.7
│ Created: 2023-10-25 09:18:35.490893 +0000 UTC
│ Info:


│ Terraform acquires a state lock to protect the state from being written
│ by multiple users at the same time. Please resolve the issue above and try
│ again. For most commands, you can disable locking with the "-lock=false"
│ flag, but this is not recommended.

這也確保了執行只會有一人,其他人要操作都會被擋下來。

AWS S3作為terraform remote backend

依照慣例先來個 provider.tf起手式

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.22.0"
}
}
}

provider "aws" {
alias = "ap-east-1"
region = "ap-east-1"
}

接著建立一個名為bucket.tf檔案

resource "aws_s3_bucket" "terraform_state" {
bucket = "terraform-alan-test-bucket"
provider = aws.ap-east-1
force_destroy = false
# Prevent accidental deletion of this S3 bucket
lifecycle {
prevent_destroy = true
}
}

參數說明如下:

  • bucket:定義 s3 bucket 名稱
  • provider:指定 bucket 儲存位置
  • force_destroy:設定是否可強制刪除
  • prevent_destroy:任何嘗試刪除該資源的操作都將導致terraform退出並顯示錯誤。

接下來要替s3增加一些額外的保護

首先新增版本控制,使用aws_s3_bucket_versioning resource開啟版本控制,確保每次更新都會創建新版。當出現問題時也能恢復成舊版:

resource "aws_s3_bucket_versioning" "enabled" {
bucket = aws_s3_bucket.terraform_state.id
versioning_configuration {
status = "Enabled"
}
}

參數說明如下:

  • bucket:要啟用版本控制的 S3 bucket 的 ID
  • versioning_configuration
  • status:可用選項為EnabledDisabledSuspended,設為 “Enabled” 表示啟用版本控制

接著開啟加密設定,使用 aws_s3_bucket_server_side_encryption_configuration,開啟後寫入到這個 S3 的所有資料都會啟用 server 端的加密。確保狀態檔以及任何存在 S3 的敏感資料都在硬碟上加密:

resource "aws_s3_bucket_server_side_encryption_configuration" "server_side_encryption" {
bucket = aws_s3_bucket.terraform_state.id

rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}

參數說明如下:

  • bucket:要啟用版本控制的 S3 bucket 的 ID
  • apply_server_side_encryption_by_default:指定預設的 server 端加密設定。
  • sse_algorithm:設定 server 端加密算法,這裡使用的是 “AES256”。

補充一下其他可用選項

  1. AES256 (SSE-S3):
  • 描述:使用 Amazon S3 托管的密鑰(SSE-S3)進行加密。
  • 算法:AES-256。
  • 密鑰管理:由 Amazon S3 自動處理。

2. aws:kms (SSE-KMS):

  • 描述:使用 AWS Key Management Service (KMS) 托管的 CMK(客戶主密鑰)進行加密。
  • 算法:通常是 AES-256,但具體取決於 KMS。
  • 密鑰管理:由 AWS KMS 處理,允許更細緻的控制和審計跟踪。

3. aws:kms:dsse (SSE-KMS with Double-Wrap):

  • 描述:這是一種特殊的 KMS 加密方法,其中數據首先使用一個隨機數據加密密鑰 (DEK) 進行加密,然後 DEK 本身使用 KMS CMK 進行加密,從而實現雙重加密。
  • 密鑰管理:由 AWS KMS 處理。

區別:

  • 密鑰管理AES256 由 S3 自動管理,aws:kms 和 aws:kms:dsse 允許更多的控制和稽核,由 AWS KMS 處理。
  • 加密強度aws:kms:dsse 提供雙重加密,可提供更高的安全性。

推薦:

  • 對於大多數使用者,AES256 是一個簡單且安全的選擇。
  • 如果需要更細緻的密鑰管理、審計或控制,則推薦使用 aws:kms
  • 如果需要更高的安全性和加密強度,則可以考慮使用 aws:kms:dsse,但請注意,這可能會增加一些複雜性和成本。

如果開啟 aws:kms 時,推薦也需要設定 bucket_key_enabled,可減少對 kms請求,降低成本。 當使用SSE-KMS進行 server 端加密時,每次S3對象操作都會導致KMS請求,這可能會增加成本。使用S3 Bucket Keys,可以減少這些請求,從而減少成本。

審計:系統性的檢查和評估過程,用於確定某些標準、政策、法規或其他準則是否被遵循。

第三個設定是存取權的控制,阻止對 S3 bucket 的所有公開存取。

resource "aws_s3_bucket_public_access_block" "public_access" {
bucket = aws_s3_bucket.bucket.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}

參數說明如下:

  • bucket:要設定公開存取阻止的 S3 bucket ID。
  • block_public_acls:設定為 true 阻止公開 ACL。
  • block_public_policy:設定為 true 阻止公開策略。
  • ignore_public_acls:設定為 true 忽略公開 ACL。
  • restrict_public_buckets:設定為 true 限制公開 bucket。

最後一個要設定的是用來當作鎖的 DynamoDB table,使用 aws_dynamodb_table 的強一制性讀取和條件寫入,達到分散式鎖系統。

resource "aws_dynamodb_table" "terraform_locks" {
name = var.dynamodb_table_name
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}

參數說明如下:

  • name:這是 DynamoDB 表的名稱。
  • billing_mode:這指定了計費模式,能使用的值有PROVISIONEDPAY_PER_REQUEST,這裡使用"PAY_PER_REQUEST",依照需請求計費。另一種則是確定有固定的讀寫,則可以設定讀寫量。

BillingModeSummary — Amazon DynamoDB

  • hash_key:這是表的主鍵名稱。
  • attribute
  • name:這是屬性的名稱,這裡是 “LockID”
  • type:這是屬性的類型,可以用的類型有S(字串)、N(數字)、B(二進制)

依照上面的設定,即可完成s3以及dynamodb的建立,一樣下 terraform init terraform apply完成建置。接著來設定 remote backend

terraform {
backend "s3" {
bucket = "terraform-alan-test-bucket"
key = "bucket-state/terraform.tfstate"
region = "ap-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}

參數說明如下:

  • bucket:要使用的bucket name,這邊填入剛剛建立的 bucket
  • key:要建立在 s3 的路徑和名稱
  • region:指定 s3 的區域
  • dynamodb_table:用來儲存狀態檔的鎖定,防止多人同時使用 terraform 操作同一份檔案,可防止同時修改,避免數據不一致
  • encrypt:決定是否加密 terraform state 檔案,設定為 true 將使用 s3 的 sse 進行加密
  • prefix:定義狀態檔的路徑和名稱,以上述為例,狀態檔會被存放在 bucket-state資料夾

一樣重下 terraform init 重設 backend

> terraform init
Initializing the backend...
Do you want to copy existing state to the new backend?
Pre-existing state was found while migrating the previous "local" backend to the
newly configured "s3" backend. No existing state was found in the newly
configured "s3" backend. Do you want to copy this state to the new "s3"
backend? Enter "yes" to copy and "no" to start with an empty state.
Enter a value:

執行後terraform會自動檢查本地已有的狀態檔,並跳出提示說要將狀態檔複製到 gcs backend。如果輸入 yes,則會看到以下內容:

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing modules...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/aws v5.22.0
Terraform has been successfully initialized!

一樣執行完畢後上去 s3 看一下狀態檔是否已經儲存上去

raw-image

當有兩人同時執行時,則第二個人會出現以下訊息:

> terraform apply
Acquiring state lock. This may take a few moments...

│ Error: Error acquiring the state lock

│ Error message: ConditionalCheckFailedException: The conditional request failed
│ Lock Info:
ID: 46f562fd-ab59-a657-6984-5e164ec4bf
│ Path: terraform-alan-test-bucket/bucket-state/terraform.tfstate
│ Operation: OperationTypeApply
│ Who: alan_wang@Alan-wangdeMacBook-Pro.local
│ Version: 1.5.7
│ Created: 2023-10-26 09:33:34.15838 +0000 UTC
│ Info:


│ Terraform acquires a state lock to protect the state from being written
│ by multiple users at the same time. Please resolve the issue above and try
│ again. For most commands, you can disable locking with the "-lock=false"
│ flag, but this is not recommended.

📚Reference

17會員
81Content count
golang
留言0
查看全部
發表第一個留言支持創作者!
wang alan的沙龍 的其他內容
📔心得 最近,我在探索 Ansible 自動化工具的過程中,決定運用它來建立 ELK Stack,這是我之前使用 Docker 建立的經驗的延伸。在這個過程中,我想分享一下我的學習心得。
在 Kubernetes 裡,Secret 就像是一個保險箱,可以放你任何不想公開的東西。比如說密碼、API 金鑰、憑證等,這樣的資料可能會被放在 Pod 裡,但你可以用 Secret 來避免直接在應用程式的程式碼中暴露這些機密資料。
👨‍💻簡介 今天早上在下kubectl get pods時,突然跳出了以下錯誤 Unable to connect to the server: x509: certificate has expired or is not yet valid
👨‍💻簡介 因在wsl環境下使用websocket通訊協議,並在windows使用postman發生連線被拒 嘗試了localhost與127.0.0.1都無效,爬文後找到了一些解決辦法,這邊簡單紀錄一下
👨‍💻簡介 從來沒想過部署可以如此的方便快速,第一次接觸到Zeabur的時候覺得他跟一般的雲端服務商差不多,架設網站用個vm之類的,但仔細去摸索後才發現他是個想讓開發人員專注在寫扣這件事上,不需去管任何infra相關事項的一個服務,像是架設wordpress需要sql,就簡單的點兩下即可完
什麼是 Kubernetes Deployment? 一樣先來個官網解說 A Deployment provides declarative updates for Pods and ReplicaSets. You describe a desired state in a Deployment,
📔心得 最近,我在探索 Ansible 自動化工具的過程中,決定運用它來建立 ELK Stack,這是我之前使用 Docker 建立的經驗的延伸。在這個過程中,我想分享一下我的學習心得。
在 Kubernetes 裡,Secret 就像是一個保險箱,可以放你任何不想公開的東西。比如說密碼、API 金鑰、憑證等,這樣的資料可能會被放在 Pod 裡,但你可以用 Secret 來避免直接在應用程式的程式碼中暴露這些機密資料。
👨‍💻簡介 今天早上在下kubectl get pods時,突然跳出了以下錯誤 Unable to connect to the server: x509: certificate has expired or is not yet valid
👨‍💻簡介 因在wsl環境下使用websocket通訊協議,並在windows使用postman發生連線被拒 嘗試了localhost與127.0.0.1都無效,爬文後找到了一些解決辦法,這邊簡單紀錄一下
👨‍💻簡介 從來沒想過部署可以如此的方便快速,第一次接觸到Zeabur的時候覺得他跟一般的雲端服務商差不多,架設網站用個vm之類的,但仔細去摸索後才發現他是個想讓開發人員專注在寫扣這件事上,不需去管任何infra相關事項的一個服務,像是架設wordpress需要sql,就簡單的點兩下即可完
什麼是 Kubernetes Deployment? 一樣先來個官網解說 A Deployment provides declarative updates for Pods and ReplicaSets. You describe a desired state in a Deployment,
你可能也想看
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
應屆畢業生們,恭喜你們即將踏入職場!你是不是總是被問到一個看似簡單但卻很複雜的問題:你想做什麼?而對於那些還沒有確定自己價值觀和職業目標的人來說,這個問題更是讓人感到焦慮。但是,確定自己的價值觀和職業目標對於我們未來的職業發展非常重要。
Thumbnail
Windows電腦中,我們可以利用內建工具"工作排程器"去預設電腦重新啟動或登入時,自動執行重要程式,避免遺漏程式忘記,導致連動程式的系統不能使用。 以下是教學步驟: 步驟一: 開啟Windows電腦中內建工具"工作排程器" 步驟二: 將游標移至"工作排程器程式庫"按右鍵"建立工作" 步驟三:
Thumbnail
对于 Notion 这样的生产力工具而言,非常适合进行任务管理。比如,制定各种学习计划、工作计划、习惯追踪。你可以看到很多用户乐此不疲地建立各种模版,其中最重要的便是进行任务追踪。 那么,与传统的工具而言,Notion 类产品为什么适合进行任务追踪呢? 📷 Notion 类生产力工具的独特之处
Thumbnail
在上次的文章中,我们介绍了《如何高效使用番茄工作法》。今天围绕时间管理的主题,继续介绍另外一种重要时间管理方法。 注释:本文方法对于 FlowUs 、Notion 等笔记软件均通用。本文以 FlowUs 为例。 时间管理的首要主题:时间追踪——柳比歇夫时间管理法 时间追踪—柳比歇夫时间管理模版分享
Thumbnail
第四步 回到以往 當我們開始懂得拒絕和開始忍受這些不方便時,才會慢慢發現許多沉積已久繁瑣的問題一一的被解開來,換一個念頭將我們從泥淖般的生活中脫離,讓行為回到以往並讓精神超越過去,才能感受自然帶給我們的美好清爽的時刻。
Thumbnail
第三步 感受 太陽東升西落是不變的道理,但唯有我們將眼睛張開才能感受它的刺眼,出了家門才能感受它的溫熱。用自己的雙眼去認識事物之美,當下的每個瞬間都可能是美的一部分。 用自己的雙眼去認識事物之美,當下的每個瞬間都可能是美的一部分。
Thumbnail
第二步 知足 梭羅在《湖濱散記》中提及「他自己的生活越簡單,宇宙的規律也就顯得簡單,寂寞將不成其為寂寞,貧困將不成其為貧困,軟弱將不成其為軟弱。」 超級流浪漢亞歷山大:「只有當我們分享的時候,才會發現知足的快樂。」
Thumbnail
第一步 善良 美國哲學作家梭羅曾說:「我之愛野性,不下於我之愛善良。」或許取的與大自然平衡點的第一步,綻放心中的善良去掩蓋內心深處的自私。 亞馬遜創始人貝佐斯曾經說過:「聰明是一種天賦,而善良是一種選擇。」
Thumbnail
本篇將會記錄如何在GCP上建立的Ubuntu虛擬機,進行Wordpress的環境準備與網站安裝。 本篇將會以架式環境與安裝 WordPress 為主,虛擬機平台的註冊與架設將不會太過著重,未來若有機會再進行記錄。 首先需要準備的軟體有 有沒有比較好或是其他區別,在這邊不做討論。
Thumbnail
留白是網站設計中被廣泛應用的手法。我們常常認為安靜、空的、無色的東西是無聊的,卻鮮少人了解到正因為這些空白的存在,才會成為有聲、有物、有色的對比基礎。網站設計中,很多人認為任何留白都是浪費空間,應該要讓大家看到越多內容越好。但事實上,留白是非常強大的視覺設計技巧,適當的留白甚至與好的內容同等重要。
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
應屆畢業生們,恭喜你們即將踏入職場!你是不是總是被問到一個看似簡單但卻很複雜的問題:你想做什麼?而對於那些還沒有確定自己價值觀和職業目標的人來說,這個問題更是讓人感到焦慮。但是,確定自己的價值觀和職業目標對於我們未來的職業發展非常重要。
Thumbnail
Windows電腦中,我們可以利用內建工具"工作排程器"去預設電腦重新啟動或登入時,自動執行重要程式,避免遺漏程式忘記,導致連動程式的系統不能使用。 以下是教學步驟: 步驟一: 開啟Windows電腦中內建工具"工作排程器" 步驟二: 將游標移至"工作排程器程式庫"按右鍵"建立工作" 步驟三:
Thumbnail
对于 Notion 这样的生产力工具而言,非常适合进行任务管理。比如,制定各种学习计划、工作计划、习惯追踪。你可以看到很多用户乐此不疲地建立各种模版,其中最重要的便是进行任务追踪。 那么,与传统的工具而言,Notion 类产品为什么适合进行任务追踪呢? 📷 Notion 类生产力工具的独特之处
Thumbnail
在上次的文章中,我们介绍了《如何高效使用番茄工作法》。今天围绕时间管理的主题,继续介绍另外一种重要时间管理方法。 注释:本文方法对于 FlowUs 、Notion 等笔记软件均通用。本文以 FlowUs 为例。 时间管理的首要主题:时间追踪——柳比歇夫时间管理法 时间追踪—柳比歇夫时间管理模版分享
Thumbnail
第四步 回到以往 當我們開始懂得拒絕和開始忍受這些不方便時,才會慢慢發現許多沉積已久繁瑣的問題一一的被解開來,換一個念頭將我們從泥淖般的生活中脫離,讓行為回到以往並讓精神超越過去,才能感受自然帶給我們的美好清爽的時刻。
Thumbnail
第三步 感受 太陽東升西落是不變的道理,但唯有我們將眼睛張開才能感受它的刺眼,出了家門才能感受它的溫熱。用自己的雙眼去認識事物之美,當下的每個瞬間都可能是美的一部分。 用自己的雙眼去認識事物之美,當下的每個瞬間都可能是美的一部分。
Thumbnail
第二步 知足 梭羅在《湖濱散記》中提及「他自己的生活越簡單,宇宙的規律也就顯得簡單,寂寞將不成其為寂寞,貧困將不成其為貧困,軟弱將不成其為軟弱。」 超級流浪漢亞歷山大:「只有當我們分享的時候,才會發現知足的快樂。」
Thumbnail
第一步 善良 美國哲學作家梭羅曾說:「我之愛野性,不下於我之愛善良。」或許取的與大自然平衡點的第一步,綻放心中的善良去掩蓋內心深處的自私。 亞馬遜創始人貝佐斯曾經說過:「聰明是一種天賦,而善良是一種選擇。」
Thumbnail
本篇將會記錄如何在GCP上建立的Ubuntu虛擬機,進行Wordpress的環境準備與網站安裝。 本篇將會以架式環境與安裝 WordPress 為主,虛擬機平台的註冊與架設將不會太過著重,未來若有機會再進行記錄。 首先需要準備的軟體有 有沒有比較好或是其他區別,在這邊不做討論。
Thumbnail
留白是網站設計中被廣泛應用的手法。我們常常認為安靜、空的、無色的東西是無聊的,卻鮮少人了解到正因為這些空白的存在,才會成為有聲、有物、有色的對比基礎。網站設計中,很多人認為任何留白都是浪費空間,應該要讓大家看到越多內容越好。但事實上,留白是非常強大的視覺設計技巧,適當的留白甚至與好的內容同等重要。