Earlier quoted context omitted.
In the early days, people would write imperative scripts to provision infrastructure, but once it's out there you can't just delete resources that you no longer want by deleting the relevant blocks from your script and re-running it--you had to delete them manually or write a "migration script". This was untenable. Then some tools came out which let you use YAML or JSON to describe the desired state of the world, and…
> Eventually the industry caught on to the scam and demanded programming languages back, so we got CDKs which misunderstand the assignment in a different way. Rather than emitting YAML… You’re in for a shock when you realise all they do is emit YAML
Libaws: A simpler way to declare AWS infrastructure
91–93 of 93 posts
Re: Libaws: A simpler way to declare AWS infrastructure
#92Earlier quoted context omitted.
In the early days, people would write imperative scripts to provision infrastructure, but once it's out there you can't just delete resources that you no longer want by deleting the relevant blocks from your script and re-running it--you had to delete them manually or write a "migration script". This was untenable. Then some tools came out which let you use YAML or JSON to describe the desired state of the world, and…
Amazon's CDK emits YAML. Troposphere emits YAML. You can diff the outputs if you wish, or did I misunderstand your last paragraph.
These are two examples I found online. The first is more complicated but it doesn't do any JavaScript IPC, no inheritance, no mutation, etc. You write it just like you want to write YAML, and it straightforwardly emits YAML (rather than the CDK version which is more opaque/magical). I prefer this:
def main():
bucket_name_parameter = ParameterString(Description="The name of the bucket")
key_arn_parameter = ParameterString(
Description="The ARN of the KMS key used to encrypt the bucket",
)
bucket = Bucket(BucketName=bucket_name_parameter)
t = Template(
description="S3 Bucket Template",
parameters={
"BucketName": bucket_name_parameter,
"KMSKeyARN": key_arn_parameter,
},
resources={
"Bucket": bucket,
"BucketPolicy": ManagedPolicy(
PolicyDocument={
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowFullAccessToBucket",
"Action": "s3:*",
"Effect": "Allow",
"Resource": Sub(
f"${{BucketARN}}/*", BucketARN=bucket.GetArn()
),
},
{
"Sid": "AllowUseOfTheKey",
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey",
],
"Resource": key_arn_parameter,
},
{
"Sid": "AllowAttachmentOfPersistentResources",
"Effect": "Allow",
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant",
],
"Resource": key_arn_parameter,
"Condition": {"Bool": {"kms:GrantIsForAWSResource": True}},
},
],
},
),
},
)
print(json.dumps(t.template_to_cloudformation(), indent=4))
Rather than this: class S3Stack(Stack):
def __init__(self, app: App, id: str) -> None:
super().__init__(app, id)
self.access_point = f"arn:aws:s3:{Aws.REGION}:{Aws.ACCOUNT_ID}:accesspoint/" \
f"{S3_ACCESS_POINT_NAME}"
# Set up a bucket
bucket = s3.Bucket(
self,
"example-bucket",
access_control=s3.BucketAccessControl.BUCKET_OWNER_FULL_CONTROL,
encryption=s3.BucketEncryption.S3_MANAGED,
block_public_access=s3.BlockPublicAccess.BLOCK_ALL,
)
# Delegating access control to access points
# https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-points-policies.html
bucket.add_to_resource_policy(
iam.PolicyStatement(
actions=["*"],
principals=[iam.AnyPrincipal()],
resources=[
bucket.bucket_arn,
bucket.arn_for_objects('*')
],
conditions={
"StringEquals":
{
"s3:DataAccessPointAccount": f"{Aws.ACCOUNT_ID}"
}
}
),
)
Note: Compared to Troposphere, the bindings in the first example are completely generated from a spec published by AWS, so they never fall behind. They're also type-annotated so you can use those bindings with type safety. Sadly, the project has been abandoned because it's CloudFormation-specific and the world has moved away from CloudFormation.Re: Libaws: A simpler way to declare AWS infrastructure
#93Earlier quoted context omitted.
In the early days, people would write imperative scripts to provision infrastructure, but once it's out there you can't just delete resources that you no longer want by deleting the relevant blocks from your script and re-running it--you had to delete them manually or write a "migration script". This was untenable. Then some tools came out which let you use YAML or JSON to describe the desired state of the world, and…
CDK outputs CloudFormation templates that you can pass to any other tool if you wish. CDK is technically just a glorified shim over CFN (although 1000x better but you do get caught in the awkwardness that is CFN many times).