s3-bucket-generic.yaml
---

S3 Bucket CloudFormation Deployment

This CloudFormation template will deploy an S3 bucket with it's own IAM user and a role to go along with it.

  • An S3 bucket with encryption enabled
  • An IAM user with full access to that S3 bucket
  • An IAM Policy which allows access to that S3 bucket
AWSTemplateFormatVersion: '2010-09-09' Description: Generic S3 bucket

Parameters

These are the input parameters for this template. All of these parameters must be supplied for this template to be deployed.

Parameters:

The name of the bucket.

BucketName: Type: String Description: The name of the S3 Bucket. AllowedPattern: '(^((?![-])[a-z0-9-]{0,63}(?<![-]))$)' EnableVersioningParameter: Type: String Description: Enable S3 Bucket Versioning Default: "Yes" AllowedValues: ["Yes", "No"] ExpireOldVersions: Type: Number Description: If Versioning is enabled, expire old versions after this many days (20 - 720, default 360) MinValue: 20 MaxValue: 720 Default: 360 EnableIntelligentTieringParameter: Type: String Description: Enable S3 Bucket Intelligent Tiering for all objects (90 days to archive, 360 to deep archive) Default: "Yes" AllowedValues: ["Yes", "No"] EnableRemoteAccountParameter: Type: String Description: Enable S3 Bucket Remote Account Access Default: "No" AllowedValues: ["Yes", "No"] RemoteAccountsList: Type: CommaDelimitedList Description: Comma delimited list of full root account ARNs

Tags

The following tags are applied to all resources created by this template.

TagService: Description: Service name (from the service catalog) that is utilizing this resource Type: String TagEnvironment: Description: Type of environment that is using this resource, such as 'dev', 'tst', 'prd'. Type: String AllowedValues: [dev, tst, prd, trn, stg, cfg, sup, rpt] Default: dev TagContactNetId: Description: NetID of the person to contact for information about this resource Type: String TagAccountNumber: Description: Financial system account number for the service utilizing this resource Type: String TagTicketNumber: Description: Ticket number that this resource is for Type: String

Metadata

Metadata is mostly for organizing and presenting Parameters in a better way when using CloudFormation in the AWS Web UI.

Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: S3 Bucket Configuration Parameters: - BucketName - EnableVersioningParameter - ExpireOldVersions - EnableIntelligentTieringParameter - EnableRemoteAccountParameter - RemoteAccountsList - Label: default: Tagging and Cost Management Parameters: - TagService - TagEnvironment - TagContactNetId - TagAccountNumber - TagTicketNumber ParameterLabels: BucketName: default: 'Bucket Name:' TagService: default: "Service Name:" TagEnvironment: default: 'Environment Type:' TagContactNetId: default: 'Technical Contact NetID:' TagAccountNumber: default: 'Financial Account Number:' TagTicketNumber: default: 'Ticket Number:' EnableVersioningParameter: default: 'Enable Versioning:' EnableIntelligentTieringParameter: default: 'Enable Intelligent Tiering:' EnableRemoteAccountParameter: default: 'Enable Remote Accounts:'

Conditions

Conditions: EnableVersioning: !Equals [!Ref EnableVersioningParameter, "Yes"] EnableIntelligentTiering: !Equals [!Ref EnableIntelligentTieringParameter, "Yes"] EnableRemoteAccount: !Equals [!Ref EnableRemoteAccountParameter, "Yes"]

Resources

These are all of the resources deployed by this template.

Resources:

S3 Bucket

This deploys the S3 bucket with some tags.

S3Bucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName AccessControl: Private BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 VersioningConfiguration: Fn::If: - EnableVersioning - Status: Enabled - !Ref AWS::NoValue LifecycleConfiguration: Rules: - Id: !Join ["-",[!Ref BucketName,"Multipart-Rule"]] AbortIncompleteMultipartUpload: DaysAfterInitiation: 3 Status: Enabled - Id: !Join ["-",[!Ref BucketName,"Lifecycle-Rule"]] NoncurrentVersionExpirationInDays: !Ref ExpireOldVersions Status: !If [EnableVersioning, Enabled, Disabled] IntelligentTieringConfigurations: - Fn::If: - EnableIntelligentTiering - Id: AllS3Objects Status: Enabled Tierings: - AccessTier: ARCHIVE_ACCESS Days: 90 - AccessTier: DEEP_ARCHIVE_ACCESS Days: 360 - !Ref AWS::NoValue PublicAccessBlockConfiguration: BlockPublicAcls: True BlockPublicPolicy: True IgnorePublicAcls: True RestrictPublicBuckets: True Tags: - Key: Name Value: !Sub "${BucketName}-s3" - Key: service Value: !Ref TagService - Key: environment Value: !Ref TagEnvironment - Key: contactnetid Value: !Ref TagContactNetId - Key: accountnumber Value: !Ref TagAccountNumber - Key: ticketnumber Value: !Ref TagTicketNumber

S3 BucketPolicy

Permits remote access to bucket from indicated accounts

RemoteBucketPolicy: Type: AWS::S3::BucketPolicy Condition: EnableRemoteAccount Properties: Bucket: !Ref S3Bucket PolicyDocument: Statement: - Sid: AllowRemoteAccountAccess Action: - "s3:GetBucketLocation" - "s3:ListBucket" - "s3:PutObject" - "s3:DeleteObject" - "s3:ListBucketVersions" Effect: "Allow" Principal: AWS: !Ref RemoteAccountsList Resource: - !Sub "${S3Bucket.Arn}" - !Sub "${S3Bucket.Arn}/*" - Sid: RequireFullAccessPut Action: - "s3:PutObject" Effect: "Deny" Principal: AWS: !Ref RemoteAccountsList Resource: - !Sub "${S3Bucket.Arn}/*" Condition: StringNotEquals: s3:x-amz-acl: bucket-owner-full-control

S3 Bucket User

Creates an IAM user that can only connect to the S3 bucket specified.

S3BucketUser: Type: AWS::IAM::User Properties: Path: "/" Policies: - PolicyName: S3BucketAccess PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:List* Resource: - "*" - Effect: Allow Action: - s3:* Resource: !Sub "${S3Bucket.Arn}/*"

S3 Bucket Assignable Policy

Creates an IAM policy that can only connect to the S3 bucket specified.

S3BucketPolicy: Type: AWS::IAM::Policy Properties: PolicyName: !Sub "s3access-${BucketName}" Roles: - !Ref EnvInstanceRole PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:List* Resource: - "*" - Effect: Allow Action: - s3:* Resource: !Sub "${S3Bucket.Arn}/*"

Instance Assignable Role

This is an IAM role that can be applied to an EC2 Instance. Any AWS specific permissions that the node might need should be defined here.

EnvInstanceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole Path: "/"

Instance Assignable Profile

This is just a little construct to connect a role together into a profile. The profile can be referenced by an EC2 Instance.

EnvInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: "/" Roles: - !Ref EnvInstanceRole

Outputs

Output values that can be viewed from the AWS CloudFormation console.

Outputs: BucketName: Description: "Bucket Name" Value: !Ref S3Bucket Export: Name: !Sub "${AWS::StackName}-bucket-name" BucketRole: Description: "Instance Role" Value: !Ref EnvInstanceRole Export: Name: !Sub "${AWS::StackName}-instance-role" InstanceProfile: Description: "Instance Profile" Value: !Ref EnvInstanceProfile Export: Name: !Sub "${AWS::StackName}-instance-profile" IAMUser: Description: "IAM User" Value: !Ref S3BucketUser Export: Name: !Sub "${AWS::StackName}-iam-user"