Storage (S3)

S3 buckets with full feature parity — versioning, encryption, lifecycle rules, CORS, event notifications, static website hosting, Object Lock, and more.

API Group: aws.konfig.io/v1alpha1

S3Bucket # ✅ Working

Creates and manages an S3 bucket with comprehensive configuration. All sub-configurations (versioning, encryption, lifecycle, CORS, notifications, website, Object Lock, logging) are applied idempotently on every reconcile.

Spec

FieldTypeRequiredDescription
bucketNamestringGlobally unique bucket name. Immutable after creation.
regionstringAWS region for the bucket. Required for non-us-east-1 regions. Immutable.
versioningboolEnable S3 versioning.
serverSideEncryption.sseAlgorithmstringAES256 or aws:kms.
serverSideEncryption.kmsKeyIdstringKMS key ID or ARN (for aws:kms algorithm).
blockPublicAccess.blockPublicAclsboolBlock public ACLs.
blockPublicAccess.blockPublicPolicyboolBlock public bucket policies.
blockPublicAccess.ignorePublicAclsboolIgnore public ACLs.
blockPublicAccess.restrictPublicBucketsboolRestrict public bucket access.
lifecycleRules[]LifecycleRuleObject lifecycle rules.
lifecycleRules[].idstringUnique rule ID.
lifecycleRules[].statusstringEnabled or Disabled.
lifecycleRules[].prefixstringObject key prefix filter.
lifecycleRules[].expirationDaysint32Days after object creation to expire.
lifecycleRules[].expirationDatestringSpecific date for expiration (RFC3339).
lifecycleRules[].noncurrentVersionExpirationDaysint32Days after a version becomes non-current to expire it.
lifecycleRules[].transitions[]TransitionStorage class transitions. Each: days or date, storageClass.
lifecycleRules[].noncurrentVersionTransitions[]NoncurrentTransitionNoncurrent version transitions. Each: noncurrentDays, storageClass.
lifecycleRules[].abortIncompleteMultipartUploadDaysint32Days after initiation to abort incomplete multipart uploads.
corsRules[]CORSRuleCORS configuration rules.
corsRules[].idstringOptional rule ID.
corsRules[].allowedHeaders[]stringAllowed request headers.
corsRules[].allowedMethods[]stringAllowed HTTP methods (GET, PUT, POST, DELETE, HEAD).
corsRules[].allowedOrigins[]stringAllowed origin domains.
corsRules[].exposeHeaders[]stringResponse headers to expose to browsers.
corsRules[].maxAgeSecondsint32Browser preflight cache duration in seconds.
notificationConfig.lambdaFunctionConfigurations[]LambdaNotificationLambda function event notifications. Each: id, lambdaFunctionARN, events ([]string), filterPrefix, filterSuffix.
notificationConfig.queueConfigurations[]QueueNotificationSQS queue event notifications. Same fields with queueArn.
notificationConfig.topicConfigurations[]TopicNotificationSNS topic event notifications. Same fields with topicArn.
notificationConfig.eventBridgeEnabledboolSend all events to EventBridge.
websiteConfig.indexDocumentstringIndex document filename (e.g. index.html).
websiteConfig.errorDocumentstringError document filename (e.g. error.html).
websiteConfig.redirectAllTo.hostNamestringRedirect all requests to this hostname.
websiteConfig.redirectAllTo.protocolstringProtocol for redirect: http or https.
websiteConfig.routingRulesstringJSON routing rules for conditional redirects.
accelerateStatusstringEnabled or Suspended. Transfer Acceleration.
objectLockConfig.objectLockEnabledstringEnabled. Immutable once set at bucket creation.
objectLockConfig.rule.defaultRetention.modestringGOVERNANCE or COMPLIANCE.
objectLockConfig.rule.defaultRetention.daysint32Retention period in days.
objectLockConfig.rule.defaultRetention.yearsint32Retention period in years (mutually exclusive with days).
loggingConfig.targetBucketstringDestination bucket name for server access logs.
loggingConfig.targetPrefixstringKey prefix for log objects.
tagsmap[string]stringAWS tags applied to the bucket.

Status

FieldDescription
arnThe ARN of the bucket (e.g. arn:aws:s3:::my-bucket).
domainNameThe bucket's regional domain name (e.g. my-bucket.s3.us-east-1.amazonaws.com).
websiteEndpointStatic website hosting endpoint (if websiteConfig is configured).
conditionsStandard Kubernetes conditions.
observedGenerationLast reconciled generation.
lastSyncTimeRFC3339 timestamp of last sync.

Example — Basic with Encryption

yaml
apiVersion: aws.konfig.io/v1alpha1
kind: S3Bucket
metadata:
  name: prod-app-data
  namespace: storage
spec:
  bucketName: my-company-prod-app-data
  region: us-east-1
  versioning: true
  serverSideEncryption:
    sseAlgorithm: aws:kms
    kmsKeyId: arn:aws:kms:us-east-1:123456789012:key/mrk-abc123
  blockPublicAccess:
    blockPublicAcls: true
    blockPublicPolicy: true
    ignorePublicAcls: true
    restrictPublicBuckets: true
  loggingConfig:
    targetBucket: my-company-access-logs
    targetPrefix: prod-app-data/
  tags:
    env: prod
    team: platform

Example — Full-Featured with Lifecycle and Notifications

yaml
apiVersion: aws.konfig.io/v1alpha1
kind: S3Bucket
metadata:
  name: prod-media-bucket
  namespace: storage
spec:
  bucketName: my-company-prod-media
  region: us-east-1
  versioning: true
  serverSideEncryption:
    sseAlgorithm: AES256
  blockPublicAccess:
    blockPublicAcls: true
    blockPublicPolicy: true
    ignorePublicAcls: true
    restrictPublicBuckets: true
  lifecycleRules:
    - id: transition-to-ia
      status: Enabled
      prefix: uploads/
      transitions:
        - days: 30
          storageClass: STANDARD_IA
        - days: 90
          storageClass: GLACIER
      noncurrentVersionTransitions:
        - noncurrentDays: 30
          storageClass: STANDARD_IA
      noncurrentVersionExpirationDays: 90
      abortIncompleteMultipartUploadDays: 7
  notificationConfig:
    queueConfigurations:
      - id: new-upload-notify
        queueArn: arn:aws:sqs:us-east-1:123456789012:media-processing-queue
        events:
          - s3:ObjectCreated:*
        filterPrefix: uploads/
    eventBridgeEnabled: true
  tags:
    env: prod
    team: media

Example — Static Website with CORS

yaml
apiVersion: aws.konfig.io/v1alpha1
kind: S3Bucket
metadata:
  name: prod-static-site
  namespace: storage
spec:
  bucketName: my-company-www
  region: us-east-1
  versioning: false
  serverSideEncryption:
    sseAlgorithm: AES256
  websiteConfig:
    indexDocument: index.html
    errorDocument: 404.html
  corsRules:
    - id: allow-cdn
      allowedMethods:
        - GET
        - HEAD
      allowedOrigins:
        - https://www.example.com
        - https://app.example.com
      allowedHeaders:
        - "*"
      exposeHeaders:
        - ETag
      maxAgeSeconds: 3600
  tags:
    env: prod
    purpose: static-website

Notes

  • Bucket names are globally unique across all AWS accounts and regions.
  • The region field is required for any region other than us-east-1. It is immutable after creation.
  • All sub-configurations (versioning, encryption, lifecycle, CORS, notifications, website, logging) are applied idempotently — each has its own AWS API call and is reconciled independently.
  • objectLockConfig.objectLockEnabled can only be set at bucket creation time and cannot be changed afterward.

Deletion

Blocked if bucket not empty. S3 does not allow deletion of non-empty buckets. Empty the bucket (delete all objects and versions) before deleting the CR. For versioned buckets, all versions and delete markers must be removed.

S3BucketPolicy # ✅ Working

Attaches a resource-based IAM policy to an S3 bucket. The controller waits for the referenced S3Bucket CR to be Ready before creating the policy.

Spec

FieldTypeRequiredDescription
bucketRef.namestringName of the S3Bucket CR in the same namespace.
bucketRef.bucketNamestringDirect bucket name (alternative to bucketRef.name).
policyDocumentstringJSON IAM policy document for the bucket resource policy.

Status

FieldDescription
conditionsStandard Kubernetes conditions.
observedGenerationLast reconciled generation.
lastSyncTimeRFC3339 timestamp of last sync.

Example — HTTPS-Only Policy

yaml
apiVersion: aws.konfig.io/v1alpha1
kind: S3BucketPolicy
metadata:
  name: prod-app-data-https-only
  namespace: storage
spec:
  bucketRef:
    name: prod-app-data
  policyDocument: |
    {
      "Version": "2012-10-17",
      "Statement": [{
        "Sid": "DenyHTTP",
        "Effect": "Deny",
        "Principal": "*",
        "Action": "s3:*",
        "Resource": [
          "arn:aws:s3:::my-company-prod-app-data",
          "arn:aws:s3:::my-company-prod-app-data/*"
        ],
        "Condition": {
          "Bool": { "aws:SecureTransport": "false" }
        }
      }]
    }

Example — Cross-Account Read Access

yaml
apiVersion: aws.konfig.io/v1alpha1
kind: S3BucketPolicy
metadata:
  name: prod-app-data-cross-account
  namespace: storage
spec:
  bucketRef:
    name: prod-app-data
  policyDocument: |
    {
      "Version": "2012-10-17",
      "Statement": [{
        "Sid": "AllowCrossAccountRead",
        "Effect": "Allow",
        "Principal": {
          "AWS": "arn:aws:iam::987654321012:role/analytics-role"
        },
        "Action": ["s3:GetObject", "s3:ListBucket"],
        "Resource": [
          "arn:aws:s3:::my-company-prod-app-data",
          "arn:aws:s3:::my-company-prod-app-data/*"
        ]
      }]
    }

Notes

  • The controller waits for the S3Bucket CR to be Ready before applying the policy.
  • ARNs in the policy document must be specified manually — the operator does not automatically resolve CR references within the JSON.
  • Policy changes replace the entire bucket policy (no delta merge).

Deletion

Immediate. The bucket policy is deleted. The bucket itself is not affected.