โ† Semua pembelajaran / Laravel Nol โ†’ Enterprise
Fase 9 ยท Deploy di AWS

Secrets Manager

Rahasia yang tersimpan di berkas .env di dalam image akan ikut ke mana pun image itu pergi. Secrets Manager memindahkannya ke tempat yang punya kontrol akses, jejak audit, dan rotasi.

Intisari

  • ECS menyuntikkan rahasia sebagai environment variable lewat secrets di task definition.
  • Kodemu tidak berubah sama sekali: config/ tetap membaca env().
  • Execution role yang butuh izin membacanya โ€” bukan task role.
  • Parameter Store lebih murah untuk konfigurasi biasa; Secrets Manager punya rotasi otomatis.
  • Rotasi tidak berpengaruh sampai task dijalankan ulang โ€” rahasia dibaca saat kontainer menyala.

Membuat rahasia

aws secretsmanager create-secret \
  --name portal/app \
  --secret-string '{"APP_KEY":"base64:xxxx"}'

aws secretsmanager create-secret \
  --name portal/db \
  --secret-string '{"username":"portal","password":"โ€ฆ","host":"portal.cluster-abcโ€ฆ"}'

Menyuntikkannya ke kontainer

"secrets": [
  { "name": "APP_KEY",
    "valueFrom": "arn:aws:secretsmanager:ap-southeast-1:123456789012:secret:portal/app:APP_KEY::" },
  { "name": "DB_PASSWORD",
    "valueFrom": "arn:aws:secretsmanager:ap-southeast-1:123456789012:secret:portal/db:password::" },
  { "name": "REDIS_PASSWORD",
    "valueFrom": "arn:aws:secretsmanager:ap-southeast-1:123456789012:secret:portal/redis:token::" }
]

Format ARN-nya adalah arn:โ€ฆ:secret:nama:kunci-json:tahap:versi. Dua titik dua di akhir berarti "pakai tahap dan versi terkini". Dengan menyebutkan kunci JSON, satu rahasia bisa memuat beberapa nilai yang disuntikkan sebagai variabel berbeda.

Kodemu tidak berubah sedikit pun. ECS menyuntikkan nilainya sebagai environment variable biasa, config/database.php tetap membacanya lewat env('DB_PASSWORD'), dan aplikasimu tetap memanggil config('database.โ€ฆ'). Inilah buah dari disiplin yang dibangun di Fase 0 โ€” rantai itu bekerja tanpa satu pun perubahan hanya kalau tidak ada env() yang berkeliaran di luar config/.

Izin โ€” di execution role, bukan task role

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["secretsmanager:GetSecretValue"],
      "Resource": [
        "arn:aws:secretsmanager:ap-southeast-1:123456789012:secret:portal/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": ["kms:Decrypt"],
      "Resource": "arn:aws:kms:ap-southeast-1:123456789012:key/abc-123",
      "Condition": {
        "StringEquals": { "kms:ViaService": "secretsmanager.ap-southeast-1.amazonaws.com" }
      }
    }
  ]
}

Rahasia dibaca sebelum kontainermu menyala, oleh agen ECS โ€” jadi izinnya ada di execution role. Kalau kamu memasangnya di task role, task akan gagal menyala dengan ResourceInitializationError, dan pesannya tidak langsung menunjuk ke role yang salah. Kalau rahasianya dienkripsi dengan KMS key milikmu sendiri, izin kms:Decrypt juga wajib ada.

Secrets Manager atau Parameter Store

Secrets ManagerSSM Parameter Store
BiayaPer rahasia per bulanStandard: gratis
Rotasi otomatisYaTidak
Terintegrasi dengan RDSYa โ€” rotasi password bawaanTidak
TerenkripsiSelaluDengan tipe SecureString
Didukung secrets ECSYaYa
Pakai untukPassword database, APP_KEY, tokenKonfigurasi yang tidak rahasia

Pola yang hemat sekaligus rapi: Parameter Store untuk nilai konfigurasi yang banyak jumlahnya tapi tidak rahasia, dan Secrets Manager khusus untuk yang memang rahasia dan layak dirotasi. Membayar biaya Secrets Manager untuk lima puluh nilai konfigurasi biasa adalah pemborosan tanpa manfaat keamanan tambahan.

Rotasi

aws secretsmanager rotate-secret \
  --secret-id portal/db \
  --rotation-lambda-arn arn:aws:lambda:โ€ฆ:SecretsManagerRDSMySQLRotation \
  --rotation-rules AutomaticallyAfterDays=30

Rotasi tidak berpengaruh sampai task dijalankan ulang. Rahasia dibaca sekali saat kontainer menyala; proses yang sedang berjalan tetap memakai nilai lama. Untuk rotasi password database, itu artinya kamu perlu strategi dua langkah โ€” rotasi model "dua pengguna" yang disediakan AWS membuat password lama tetap berlaku selama satu siklus, sehingga task lama tidak langsung putus. Tanpa itu, rotasi otomatis akan mematikan aplikasimu di tengah malam.

Yang tidak boleh terjadi

Anti-polaKenapa berbahaya
.env ikut di dalam imageSiapa pun yang bisa menarik image bisa membacanya
Rahasia di environment task definitionTerlihat di konsol, tersimpan di setiap revisi selamanya
Rahasia di variabel CIBisa tercetak di log build
Rahasia yang sama untuk staging dan produksiKebocoran di staging = kebocoran produksi
Access key jangka panjang untuk aplikasiTask role sudah memberi kredensial sementara secara otomatis

Latihan: pindahkan APP_KEY dan password database ke Secrets Manager, suntikkan lewat secrets, dan pastikan tidak ada satu pun berkas .env di dalam image. Verifikasi dengan docker run --rm --entrypoint sh image:tag -c "ls -la /app/.env" โ€” harusnya tidak ada.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.