Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ec2/asg): CloudFormation-init support #8788

Closed
wants to merge 53 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
42f2b68
feat(ec2/asg): CloudFormation-Init support
rix0rrr Jun 29, 2020
bda2e34
Starting to lay down parts of the API
rix0rrr Jun 30, 2020
9028fe8
Some more spitballin'
rix0rrr Jun 30, 2020
cd906a4
InitCommand v0.1
njlynch Jun 30, 2020
0a8d20e
End-of-day check-in. Slightly more structure; users, groups, and sources
njlynch Jun 30, 2020
bc1b710
Merge remote-tracking branch 'origin/master' into huijbers/cfn-init
rix0rrr Jul 1, 2020
61ef425
I changed things!
rix0rrr Jul 1, 2020
bed1c4d
Packages implemented and some cleanup
njlynch Jul 1, 2020
dc129d7
Add consumption of CfnInit object
rix0rrr Jul 1, 2020
6f6486e
InitFile v0.1 done
njlynch Jul 1, 2020
e8e8aaf
Services v0.1 implementation and making eslint happy
njlynch Jul 2, 2020
9ac3037
Refactor signal/update handling in AutoScalingGroup and add Cfn-Init
rix0rrr Jul 2, 2020
e6c643f
Merge branch 'huijbers/cfn-init' of github.com:awslabs/aws-cdk into h…
rix0rrr Jul 2, 2020
0feefb9
Update ASG README, add fingerprinting
rix0rrr Jul 2, 2020
1f4f1cf
Lots of tests, some minor fixes/updates
njlynch Jul 2, 2020
c9a8b3f
Make everything build
rix0rrr Jul 2, 2020
73cb600
Merge branch 'huijbers/cfn-init' of github.com:awslabs/aws-cdk into h…
rix0rrr Jul 2, 2020
2615fad
Remove accidental changes
rix0rrr Jul 2, 2020
b41c2ba
Add tests on ASG changes
rix0rrr Jul 2, 2020
09f5020
More tests
njlynch Jul 2, 2020
5a57332
Add restart handles
rix0rrr Jul 3, 2020
0bdc67c
Make it possible for commands to register themselves into more than 1…
rix0rrr Jul 3, 2020
44c919d
Add integral test on restart handles
rix0rrr Jul 3, 2020
d3e1d53
Add cfn-init test to Instance
rix0rrr Jul 3, 2020
6f7a2f3
Add integ test
rix0rrr Jul 3, 2020
33843f4
Add log printing and forced instance replacement
rix0rrr Jul 3, 2020
80d0caf
Add 'ignoreFailures' option
rix0rrr Jul 3, 2020
1d5ccc6
Init assets implementation and more linter fixes. Still some FIXMEs/T…
njlynch Jul 3, 2020
e4059bd
Add README, rename to 'serviceRestartHandle' everywhere
rix0rrr Jul 6, 2020
a739a38
Tmp commit. Almost there??
njlynch Jul 6, 2020
5689799
Important bug fix
njlynch Jul 6, 2020
5c30482
Combined render() and bind() into one call to satisfy auth requirements
njlynch Jul 6, 2020
95fa96f
Minor build fixes
njlynch Jul 6, 2020
84a48cd
Tweaks
rix0rrr Jul 7, 2020
13bc709
Merge branch 'huijbers/cfn-init' of github.com:awslabs/aws-cdk into h…
rix0rrr Jul 7, 2020
c217f3d
Also perform bucket.grantRead for fromS3Object()
rix0rrr Jul 7, 2020
c53f435
Simplify element implementations w.r.t. bind(),
rix0rrr Jul 7, 2020
eeaafc3
Initial list of tests to write
rix0rrr Jul 7, 2020
c913976
Two new proposed tests
rix0rrr Jul 7, 2020
d0c0b57
Add common test setup
rix0rrr Jul 7, 2020
78ce0bd
Moar tests
rix0rrr Jul 7, 2020
a8ee450
Add a bunch of tests
rix0rrr Jul 7, 2020
0b89be7
Windows-specific bug fixes
njlynch Jul 7, 2020
f512f80
Update ASG test
rix0rrr Jul 7, 2020
5178411
Merge branch 'huijbers/cfn-init' of github.com:awslabs/aws-cdk into h…
rix0rrr Jul 7, 2020
2680f7d
Fix linter errors
rix0rrr Jul 7, 2020
eba62d0
Merge remote-tracking branch 'origin/master' into huijbers/cfn-init
rix0rrr Jul 7, 2020
c151796
Windows test
rix0rrr Jul 7, 2020
efa358f
Rewrite nodeunit -> jest test
rix0rrr Jul 7, 2020
1edda87
Minor clean-up
njlynch Jul 7, 2020
110798c
Merge remote-tracking branch 'origin/master' into huijbers/cfn-init
rix0rrr Jul 10, 2020
3bb9ba4
Expected integ test update after merge
njlynch Jul 10, 2020
4966d40
Merge remote-tracking branch 'origin/master' into cfn-init
njlynch Jul 14, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions packages/@aws-cdk/aws-ec2/adr/ec2-001-cfn-init-object-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
EC2-001: cfn-init object model
==============================

Status
------

Active

Context
-------

Config sections in [`AWS::CloudFormation::Init`
blocks](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html)
can be one of commands, files, groups, packages, services, sources and users.

Each one of specified as a map of `{ key: { ...details... } }`.

For some config types the **key** is significant (such as which file to
write), for others is it not and is merely used for ordering. Some config
types have a strong need for case classes, others are fine as a collection
of data and can be modeled by structs. Some should admit Assets
in an easy way which requires a `bind` pattern for (a) binding an `Asset` object
to the construct tree and (b) granting permissions.

We'd like to give users the option to leave out keys that are unnecessary,
and have the API be consistent between the different config types.

Let's look at the different config types, in order of complexity.

* **group** - key is semantic, mapping group name => group id.
* **user** - key is semantic, mapping user name => (uid, homedir, groups)
* **command** - key is not semantic (just id+list order). Has 2 variants, specify
command as shell string or as argv array. 5 additional customization
options.
* **source** - key is semantic, mapping directory name => url of ZIP. Should admit assets,
so needs a class.
* **package** - depends on type of package (and platform). Case classes make this nicer.
- rpm, msi: key is not semantic, argument is a location for the archive.
- yum, apt, rubygems, python: key is the package name, argument are optional version number(s)
* **service** - key is semantic. Select service to either disables, enables, and/or optionally restarts services depending
on other things cfn-init does (like touching files). Needs to encode dependencies on other configuration options.
Has 2 fields that seem like it makes no sense for them to have different boolean values.
* **file** - key is semantic, indicating the file to create. Allows many diferent use cases which are
best served by case classes, and assets need a class.
- create file from literal string
- create file from base64 encoded string
- create a symlink from a literal string
- create file from URL download
- create JSON file from object
- (cdk specific) read file from disk and make inline file from it, mirroring executable bit
- (cdk specific) read file from disk and make asset from it, mirroring executable bit
- (cdk specific) I guess read symlink from disk but this seems less valuable
- on all of these we can configure owner, group, mode, mustache template substitution

File sources from URLs also allow authentication, which is a good feature to support eventually.
Easiest to do if we have classes for them.

It seems that couple of configs definitely *require* classes, and it would be weird to mix
structs and classes for the different config types. That means we use classes for all of them.

It would also be weird to mix factory functions and `new` for instantiation. Since we definitely
need case classes, we will use factory functions for all of them.

Services need to be able to encode references to other config sections, so it's tempting to use
object references for that. However, generally doing so is annoying because it turns what was once
a self-contained declarative expression into one in which subexpressions have to be assigned to variables
so that they can be referenced in 2 places. Assuming that people are generally used to encoding these
dependencies by file name, directory name, package name and command key, we can just keep the string
references.

How do we makes it possible to define configs and configsets.

We can keep the namespacing nice and flat and reduce the repetition by taking a list of `InitElement`,
subclassed by all the various init config types, so that we don't have to:

```ts
files: [
InitFile.from(...),
],
packages: [
InitPackage.from(...),
],
```

Instead we can go:

```ts
elements: [
InitFile.from(...),
InitPackage.from(...),
],
```

For configsets, a single config is the common use case:

```ts
CloudFormationInit.simpleConfig([
InitFile.from(...),
InitPackage.from(...),
])
```

For more complex cases, we can do:

```ts
CloudFormationInit.withConfigSets({
configSets: {
'default': ['cs1', 'cs2'],
'reverse': ['cs2', 'cs1'],
},
configs: {
cs1: [ ... ],
cs2: [ ... ],
}
])
```
Loading